home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / emxtutor.zip / emxsrcd1.zip / emx / src / emxdoc / input.c < prev    next >
C/C++ Source or Header  |  1998-07-04  |  13KB  |  491 lines

  1. /* input.c -- Read and tokenize the input file
  2.    Copyright (c) 1993-1998 Eberhard Mattes
  3.  
  4. This file is part of emxdoc.
  5.  
  6. emxdoc is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. emxdoc is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with emxdoc; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include "emxdoc.h"
  27. #include "cond.h"
  28.  
  29. #define COND_STACK_SIZE         8
  30.  
  31. struct cond
  32. {
  33.   int start_line;
  34.   int true;
  35.   int else_seen;
  36. };
  37.  
  38. static struct cond cond_stack[COND_STACK_SIZE];
  39. static int cond_sp;
  40.  
  41.  
  42. #define ISARG(C) ((C) == '{' || (C) == '[')
  43. #define ISARGW(C) (isspace (C) || ISARG (C))
  44. #define ISENDW(C) (isspace (C) || (C) == 0)
  45.  
  46. #define SKIP1W(P,AT) do { (P) += (AT); if (isspace (*(P))) ++(P); } while (0)
  47. #define SKIPW(P,AT) do { (P) += (AT); while (isspace (*(P))) ++(P); } while (0)
  48.  
  49. void read_line (void)
  50. {
  51.   uchar *p;
  52.   int c1;
  53.  
  54. redo:
  55.   ++line_no;
  56.   if (fgets (input, sizeof (input), input_file) == NULL)
  57.     {
  58.       if (ferror (input_file))
  59.         {
  60.           perror (input_fname);
  61.           exit (1);
  62.         }
  63.       end_of_file = TRUE;
  64.       if (cond_sp >= 0)
  65.         fatal ("%s:%d: Unterminated %cif",
  66.                input_fname, cond_stack[cond_sp].start_line, escape);
  67.       return;
  68.     }
  69.   p = strchr (input, '\n');
  70.   if (p == NULL)
  71.     fatal ("%s:%d: Line too long", input_fname, line_no);
  72.   *p = 0;
  73.   if (input[0] == escape)
  74.     {
  75.       p = input + 1;
  76.       if (strncmp (p, "c", 1) == 0 && ISENDW (p[1]))
  77.         goto redo;
  78.       if (strncmp (p, "if", 2) == 0 && isspace (p[2]))
  79.         {
  80.           SKIPW (p, 2);
  81.           c1 = condition (p);
  82.           if (cond_sp + 1 >= COND_STACK_SIZE)
  83.             fatal ("%s:%d: Conditional stack overflow", input_fname, line_no);
  84.           ++cond_sp;
  85.           cond_stack[cond_sp].true = c1;
  86.           cond_stack[cond_sp].start_line = line_no;
  87.           cond_stack[cond_sp].else_seen = FALSE;
  88.           goto redo;
  89.         }
  90.       else if (strcmp (p, "else") == 0)
  91.         {
  92.           if (cond_sp < 0)
  93.             fatal ("%s:%d: %celse without %cif",
  94.                    input_fname, line_no, escape, escape);
  95.           if (cond_stack[cond_sp].else_seen)
  96.             fatal ("%s:%d: Multiple %celse for %cif in line %d",
  97.                    input_fname, line_no, escape, escape,
  98.                    cond_stack[cond_sp].start_line);
  99.           cond_stack[cond_sp].else_seen = TRUE;
  100.           cond_stack[cond_sp].true = !cond_stack[cond_sp].true;
  101.           goto redo;
  102.         }
  103.       else if (strcmp (p, "endif") == 0)
  104.         {
  105.           if (cond_sp < 0)
  106.             fatal ("%s:%d: %cendif without %cif",
  107.                    input_fname, line_no, escape, escape);
  108.           --cond_sp;
  109.           goto redo;
  110.         }
  111.     }
  112.  
  113.   if (cond_sp >= 0 && !cond_stack[cond_sp].true)
  114.     goto redo;
  115.  
  116.   p = input;
  117.   while (isspace (*p))
  118.     ++p;
  119.   if (*p == 0)
  120.     input[0] = 0;
  121. }
  122.  
  123.  
  124. void open_input (const char *name)
  125. {
  126.  
  127.   line_no = 0; end_of_file = FALSE; cond_sp = -1;
  128.   input_fname = name;
  129.   input_file = fopen (input_fname, "rt");
  130.   if (input_file == NULL)
  131.     {
  132.       perror (input_fname);
  133.       exit (1);
  134.     }
  135. }
  136.  
  137.  
  138. static void invalid_tag (void)
  139. {
  140.   fatal ("%s:%d: Invalid tag", input_fname, line_no);
  141. }
  142.  
  143.  
  144. int parse_tag (const uchar **ptr)
  145. {
  146.   const uchar *p;
  147.  
  148.   p = *ptr;
  149.   if (*p != escape)
  150.     return FALSE;
  151.   ++p;                          /* Skip escape character */
  152.   tg_flags = 0;
  153.   switch (*p)
  154.     {
  155.     case '.':
  156.       tg_tag = TAG_FULLSTOP;
  157.       ++p;
  158.       break;
  159.  
  160.     case 'b':
  161.       if (strncmp (p, "bf", 2) == 0 && ISARGW (p[2]))
  162.         {
  163.           tg_tag = TAG_STYLE;
  164.           tg_style = STYLE_BOLD;
  165.           p += 2;
  166.         }
  167.       else if (strncmp (p, "break", 5) == 0 && ISENDW (p[5]))
  168.         {
  169.           tg_tag = TAG_BREAK;
  170.           SKIP1W (p, 5);        /* Skip one space */
  171.         }
  172.       else if (strcmp (p, "bugs") == 0)
  173.         tg_tag = TAG_BUGS;
  174.       else
  175.         invalid_tag ();
  176.       break;
  177.  
  178.     case 'c':
  179.       if (strncmp (p, "compat", 6) == 0 && isspace (p[6]))
  180.         {
  181.           tg_tag = TAG_COMPAT;
  182.           p += 6;
  183.         }
  184.       else
  185.         invalid_tag ();
  186.       break;
  187.  
  188.     case 'd':
  189.       if (strcmp (p, "description") == 0)
  190.         tg_tag = TAG_DESCRIPTION;
  191.       else
  192.         invalid_tag ();
  193.       break;
  194.  
  195.     case 'e':
  196.       if (strncmp (p, "em", 2) == 0 && ISARGW (p[2]))
  197.         {
  198.           tg_tag = TAG_STYLE;
  199.           tg_style = STYLE_EMPHASIZE;
  200.           p += 2;
  201.         }
  202.       else if (strcmp (p, "enddescription") == 0)
  203.         tg_tag = TAG_ENDDESCRIPTION;
  204.       else if (strcmp (p, "endenumerate") == 0)
  205.         tg_tag = TAG_ENDENUMERATE;
  206.       else if (strcmp (p, "endexample") == 0)
  207.         tg_tag = TAG_ENDEXAMPLE;
  208.       else if (strcmp (p, "endheaders") == 0)
  209.         tg_tag = TAG_ENDHEADERS;
  210.       else if (strcmp (p, "endindent") == 0)
  211.         tg_tag = TAG_ENDINDENT;
  212.       else if (strcmp (p, "enditemize") == 0)
  213.         tg_tag = TAG_ENDITEMIZE;
  214.       else if (strcmp (p, "endlist") == 0)
  215.         tg_tag = TAG_ENDLIST;
  216.       else if (strcmp (p, "endprototype") == 0)
  217.         tg_tag = TAG_ENDPROTOTYPE;
  218.       else if (strcmp (p, "endsamplecode") == 0)
  219.         tg_tag = TAG_ENDSAMPLECODE;
  220.       else if (strcmp (p, "endverbatim") == 0)
  221.         tg_tag = TAG_ENDVERBATIM;
  222.       else if (strcmp (p, "endtypewriter") == 0)
  223.         tg_tag = TAG_ENDTYPEWRITER;
  224.       else if (strcmp (p, "endipf") == 0)
  225.         tg_tag = TAG_ENDIPF;
  226.       else if (strcmp (p, "endlatex") == 0)
  227.         tg_tag = TAG_ENDLATEX;
  228.       else if (strcmp (p, "endtext") == 0)
  229.         tg_tag = TAG_ENDTEXT;
  230.       else if (strcmp (p, "endtable") == 0)
  231.         tg_tag = TAG_ENDTABLE;
  232.       else if (strcmp (p, "enumerate") == 0)
  233.         tg_tag = TAG_ENUMERATE;
  234.       else if (strcmp (p, "errors") == 0)
  235.         tg_tag = TAG_ERRORS;
  236.       else if (strcmp (p, "example") == 0)
  237.         tg_tag = TAG_EXAMPLE;
  238.       else
  239.         invalid_tag ();
  240.       break;
  241.  
  242.     case 'f':
  243.       if (strncmp (p, "format", 6) == 0 && isspace (p[6]))
  244.         {
  245.           tg_tag = TAG_FORMAT;
  246.           SKIPW (p, 6);
  247.         }
  248.       else if (strncmp (p, "function", 8) == 0 && isspace (p[8]))
  249.         {
  250.           tg_tag = TAG_FUNCTION;
  251.           SKIPW (p, 8);
  252.         }
  253.       else
  254.         invalid_tag ();
  255.       break;
  256.  
  257.     case 'h':
  258.       if (p[1] >= '1' && p[1] <= '0' + SECTION_LEVELS)
  259.         {
  260.           tg_tag = TAG_HEADING;
  261.           tg_level = p[1] - '0';
  262.           tg_underline = (tg_level == 1 ? '=' : '-');
  263.           p += 2;
  264.           while (*p != 0 && !isspace (*p))
  265.             switch (*p++)
  266.               {
  267.               case 'h':
  268.                 tg_flags |= HF_HIDE;
  269.                 break;
  270.               case 'u':
  271.                 tg_flags |= HF_UNNUMBERED;
  272.                 break;
  273.               default:
  274.                 invalid_tag ();
  275.               }
  276.           SKIPW (p, 0);
  277.         }
  278.       else if (p[1] == '-' || p[1] == '=')
  279.         {
  280.           tg_tag = TAG_HEADING;
  281.           tg_level = 0;
  282.           tg_underline = p[1];
  283.           SKIPW (p, 2);
  284.         }
  285.       else if (strncmp (p, "hpt", 3) == 0 && ISARGW (p[3]))
  286.         {
  287.           tg_tag = TAG_HPT;
  288.           p += 3;
  289.         }
  290.       else if (strcmp (p, "headers") == 0)
  291.         tg_tag = TAG_HEADERS;
  292.       else if (strcmp (p, "hints") == 0)
  293.         tg_tag = TAG_HINTS;
  294.       else
  295.         invalid_tag ();
  296.       break;
  297.  
  298.     case 'i':
  299.       if (p[1] >= '1' && p[1] <= '2')
  300.         {
  301.           tg_tag = TAG_INDEX;
  302.           tg_level = p[1] - '0';
  303.           SKIPW (p, 2);
  304.         }
  305.       else if (strcmp (p, "implementation") == 0)
  306.         tg_tag = TAG_IMPLEMENTATION;
  307.       else if (strcmp (p, "ipf") == 0)
  308.         tg_tag = TAG_IPF;
  309.       else if (strcmp (p, "ipfminitoc") == 0)
  310.         tg_tag = TAG_IPFMINITOC;
  311.       else if (strncmp (p, "item", 4) == 0 && ISENDW (p[4]))
  312.         {
  313.           tg_tag = TAG_ITEM;
  314.           SKIPW (p, 4);
  315.         }
  316.       else if (strncmp (p, "index", 5) == 0 && isspace (p[5]))
  317.         {
  318.           tg_tag = TAG_INDEX;
  319.           tg_level = 0;
  320.           SKIPW (p, 5);
  321.         }
  322.       else if (strcmp (p, "indent") == 0)
  323.         tg_tag = TAG_INDENT;
  324.       else if (strcmp (p, "itemize") == 0)
  325.         tg_tag = TAG_ITEMIZE;
  326.       else
  327.         invalid_tag ();
  328.       break;
  329.  
  330.     case 'k':
  331.       if (strncmp (p, "keyword ", 8) == 0)
  332.         {
  333.           tg_tag = TAG_KEYWORD;
  334.           SKIPW (p, 8);
  335.         }
  336.       else
  337.         invalid_tag ();
  338.       break;
  339.  
  340.     case 'l':
  341.       if (strncmp (p, "label ", 6) == 0)
  342.         {
  343.           tg_tag = TAG_LABEL;
  344.           SKIPW (p, 6);
  345.         }
  346.       else if (strncmp (p, "language", 8) == 0 && isspace (p[8]))
  347.         {
  348.           tg_tag = TAG_LANGUAGE;
  349.           SKIPW (p, 8);
  350.         }
  351.       else if (strcmp (p, "latex") == 0)
  352.         tg_tag = TAG_LATEX;
  353.       else if (strcmp (p, "list") == 0)
  354.         tg_tag = TAG_LIST;
  355.       else
  356.         invalid_tag ();
  357.       break;
  358.  
  359.     case 'p':
  360.       if (strcmp (p, "prototype") == 0)
  361.         tg_tag = TAG_PROTOTYPE;
  362.       else if (strncmp (p, "param", 5) == 0 && isspace (p[5]))
  363.         {
  364.           tg_tag = TAG_PARAM;
  365.           SKIPW (p, 5);
  366.         }
  367.       else if (strncmp (p, "pa", 2) == 0 && ISARGW (p[2]))
  368.         {
  369.           tg_tag = TAG_STYLE;
  370.           tg_style = STYLE_PARAM;
  371.           p += 2;
  372.         }
  373.       else
  374.         invalid_tag ();
  375.       break;
  376.  
  377.     case 'r':
  378.       if (strncmp (p, "ref", 3) == 0 && ISARGW (p[3]))
  379.         {
  380.           tg_tag = TAG_REF;
  381.           p += 3;
  382.         }
  383.       else if (strncmp (p, "replace", 7) == 0 && isspace (p[7]))
  384.         {
  385.           tg_tag = TAG_REPLACE;
  386.           SKIPW (p, 7);
  387.         }
  388.       else if (strcmp (p, "restrictions") == 0)
  389.         tg_tag = TAG_RESTRICTIONS;
  390.       else if (strcmp (p, "returnvalue") == 0)
  391.         tg_tag = TAG_RETURNVALUE;
  392.       else
  393.         invalid_tag ();
  394.       break;
  395.  
  396.     case 's':
  397.       if (strncmp (p, "seealso", 7) == 0 && isspace (p[7]))
  398.         {
  399.           tg_tag = TAG_SEEALSO;
  400.           p += 7;
  401.         }
  402.       else if (strcmp (p, "samplecode") == 0)
  403.         tg_tag = TAG_SAMPLECODE;
  404.       else if (strncmp (p, "samplefile", 10) == 0 && isspace (p[10]))
  405.         {
  406.           tg_tag = TAG_SAMPLEFILE;
  407.           SKIPW (p, 10);
  408.         }
  409.       else if (strncmp (p, "set", 3) == 0 && isspace (p[3]))
  410.         {
  411.           tg_tag = TAG_SET;
  412.           SKIPW (p, 3);
  413.         }
  414.       else if (strncmp (p, "sl", 2) == 0 && ISARGW (p[2]))
  415.         {
  416.           tg_tag = TAG_STYLE;
  417.           tg_style = STYLE_SLANTED;
  418.           p += 2;
  419.         }
  420.       else if (strncmp (p, "special", 7) == 0 && isspace (p[7]))
  421.         {
  422.           tg_tag = TAG_SPECIAL;
  423.           SKIPW (p, 7);
  424.         }
  425.       else if (strncmp (p, "sy", 2) == 0 && ISARGW (p[2]))
  426.         {
  427.           tg_tag = TAG_STYLE;
  428.           tg_style = STYLE_SYNTAX;
  429.           p += 2;
  430.         }
  431.       else if (strncmp (p, "syntax", 6) == 0 && isspace (p[6]))
  432.         {
  433.           tg_tag = TAG_SYNTAX;
  434.           SKIPW (p, 6);
  435.         }
  436.       else
  437.         invalid_tag ();
  438.       break;
  439.  
  440.     case 't':
  441.       if (strncmp (p, "tt", 2) == 0 && ISARGW (p[2]))
  442.         {
  443.           tg_tag = TAG_STYLE;
  444.           tg_style = STYLE_TTY;
  445.           p += 2;
  446.         }
  447.       else if (strcmp (p, "toc") == 0)
  448.         tg_tag = TAG_TOC;
  449.       else if (strcmp (p, "text") == 0)
  450.         tg_tag = TAG_TEXT;
  451.       else if (strncmp (p, "table ", 6) == 0)
  452.         {
  453.           tg_tag = TAG_TABLE;
  454.           SKIPW (p, 6);
  455.         }
  456.       else if (strncmp (p, "title ", 6) == 0)
  457.         {
  458.           tg_tag = TAG_TITLE;
  459.           SKIPW (p, 6);
  460.         }
  461.       else if (strcmp (p, "typewriter") == 0)
  462.         tg_tag = TAG_TYPEWRITER;
  463.       else
  464.         invalid_tag ();
  465.       break;
  466.  
  467.     case 'u':
  468.       if (strncmp (p, "ul", 2) == 0 && ISARGW (p[2]))
  469.         {
  470.           tg_tag = TAG_STYLE;
  471.           tg_style = STYLE_UNDERLINE;
  472.           p += 2;
  473.         }
  474.       else
  475.         invalid_tag ();
  476.       break;
  477.  
  478.     case 'v':
  479.       if (strcmp (p, "verbatim") == 0)
  480.         tg_tag = TAG_VERBATIM;
  481.       else
  482.         invalid_tag ();
  483.       break;
  484.  
  485.     default:
  486.       invalid_tag ();
  487.     }
  488.   *ptr = p;
  489.   return TRUE;
  490. }
  491.