summaryrefslogtreecommitdiff
path: root/support/spelchek/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'support/spelchek/parse.c')
-rw-r--r--support/spelchek/parse.c769
1 files changed, 769 insertions, 0 deletions
diff --git a/support/spelchek/parse.c b/support/spelchek/parse.c
new file mode 100644
index 0000000000..8c21edc94f
--- /dev/null
+++ b/support/spelchek/parse.c
@@ -0,0 +1,769 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"heap.h"
+#include"library.h"
+
+#define PARSERIMPLEMENTATION
+#include"parse.h"
+
+#define RINGSIZE 15
+#define MAXSTRING 256
+#define MAXWORT 1022
+#define MODESTACK 100
+#define MINDESTLAENGE 1
+
+#ifdef DEBUG
+#define storemode( mode ) { ringindex++; ringindex %= RINGSIZE; modering[ringindex] = mode; printf("%d ",modering[ringindex]);}
+#else
+#define storemode( mode ) { ringindex++; ringindex %= RINGSIZE; modering[ringindex] = mode;}
+#endif
+
+#define min(a,b) ((a)<(b) ? (a) : (b))
+#define is_a_letter(c) ((('A'<=(c))&&((c)<='Z'))||(('a'<=(c))&&((c)<='z')))
+#define islower( c ) ( ('a'<= ( c ))&&(( c ) <= 'z') )
+#define isdigit( c ) ( ('0'<= ( c ))&&(( c ) <= '9') )
+#define isupper( c ) ( ('A'<= ( c ))&&(( c ) <= 'Z') )
+#define preprevious_mode ( modering[ ringindex > 0 ? ringindex-1 : RINGSIZE-1 ] )
+#define previous_mode ( modering[ ringindex ] )
+#define old_mode( age ) ( modering[ ringindex - age => 0 ? ringindex-age : RINGSIZE + ringindex - age ] )
+
+enum catcode {
+ catcode_escape,
+ catcode_begingroup,
+ catcode_endgroup,
+ catcode_mathshift,
+ catcode_alignmenttab,
+ catcode_endofline,
+ catcode_space,
+ catcode_letter,
+ catcode_other,
+ catcode_active,
+ catcode_comment,
+ catcode_ignored,
+ catcode_eof
+};
+
+enum parsemode {
+ no_mode, /* kein mode im mode-ring */
+ common_mode, /* normale buchstaben */
+ escape_mode, /* befehle */
+ parameter_mode, /* untersuchung von environment-parametern */
+ space_mode, /* skippen von leerzeichen */
+ digit_mode, /* behandeln von zahlen (mit dezimalpunkt) */
+ other_mode, /* skippen von others ( z.b. '(' ) */
+ skip_mode, /* $$ werden geskipt und aehnliches */
+ comment_mode, /* behandeln von kommentaren */
+ active_mode, /* untersuchen von active-characters */
+ end_deletion_mode /* skippen der parameter von \end */
+};
+
+struct token {
+ enum catcode catcode;
+ unsigned char token;
+};
+
+
+struct active_expansion{
+ unsigned char of_what;
+ unsigned char *what;
+};
+
+
+struct active_definition{
+ struct active_definition *next;
+ unsigned char character;
+ int anzahl;
+ struct active_expansion expansion[1];
+};
+
+
+/* Modulglobale variablen */
+
+static enum parsemode modering[RINGSIZE];
+static int ringindex;
+static unsigned char punctuation_chars[50] = ".,:;!?"; /* characters, die hinter sich, aber nicht vor sich ein space wollen */
+static unsigned char textbegingroup_chars[20] = "("; /* characters, die vor sich, aber nicht hinter sich ein space wollen */
+static unsigned char textendgroup_chars[20] = ")"; /* characters, die vor sich, aber nicht hinter sich ein space wollen */
+static unsigned char sentenceend_chars[20]=".!?";
+static int zeilenoffset;
+static struct active_expansion default_expansion;
+static struct active_definition *active_defs;
+static struct active_definition *escape_def;
+static struct active_definition escape_default;
+static heap *active_heap;
+static enum parsemode mode_stack[MODESTACK];
+static enum parsemode *mode; /* pointer auf den mode_stack */
+static struct token actualtoken;
+static FILE *source;
+static FILE *outputfile;
+static const unsigned char *texname;
+static struct token catcodes[256];
+static library *skipped_env, *skipped_com, *delimiter_com;
+static library *weird_capital;
+
+/* prototypen */
+
+static struct token next_token(void);
+static void exit_parser( void );
+
+/* code */
+
+void init_parser(FILE *infofile, FILE *sourcefile, FILE *outfile, const unsigned char *sourcename )
+{
+
+ unsigned char zeile[MAXSTRING];
+ unsigned char keyword[MAXSTRING];
+ outputfile = outfile;
+ source = sourcefile;
+ texname = sourcename;
+ zeilennummer = 1;
+ zeilenoffset = 0;
+
+
+ /* initialisierung des mode-rings auf den jeweils die alten modes kommen */
+
+ for ( ringindex = 0; ringindex < RINGSIZE; ringindex++ )
+ modering[ringindex] = no_mode;
+ ringindex = 0;
+
+ escape_default.anzahl = 1;
+ escape_default.next = NULL;
+ default_expansion.of_what = '-';
+ default_expansion.what = "\\-@";
+ escape_default.expansion[0] = default_expansion;
+
+ skipped_env = library_create( 500 );
+ skipped_com = library_create( 500 );
+ delimiter_com = library_create( 500 );
+ weird_capital = library_create( 500 ); /* 1.11.91 */
+ active_heap = heap_create( 500 );
+ atexit( exit_parser );
+ escape_def = &escape_default;
+ active_defs = NULL;
+ { /* init catcodes */
+ unsigned char c;
+ for ( c = 255; c >= ' '; c-- )
+ {
+ catcodes[c].catcode = catcode_other;
+ catcodes[c].token = c;
+ }
+ for ( c = 1; c < ' '; c++ )
+ catcodes[c].catcode = catcode_ignored;
+
+ catcodes['\\'].catcode = catcode_escape;
+ catcodes['{'].catcode = catcode_begingroup;
+ catcodes['}'].catcode = catcode_endgroup;
+ catcodes['$'].catcode = catcode_mathshift;
+ catcodes['&'].catcode = catcode_alignmenttab;
+ catcodes['\n'].catcode = catcode_endofline;
+ catcodes['\n'].token = '\n';
+ catcodes[' '].catcode = catcode_space;
+ catcodes['\t'].catcode = catcode_space;
+ catcodes['%'].catcode = catcode_comment;
+ for ( c = 'A'; c <= 'Z'; c++ )
+ catcodes[c].catcode = catcode_letter;
+ for ( c = 'a'; c <= 'z'; c++ )
+ catcodes[c].catcode = catcode_letter;
+ catcodes[0].catcode = catcode_eof;
+ } /* init catcodes */
+
+ /* infofile-syntax
+ <keyword>=<string>
+ <keyword> = catcodes / skipped_environment / skipped_commands */
+
+ while( fscanf( infofile, "%s\t%s\n", keyword, zeile ))
+ {
+ unsigned char *zeilepointer;
+ zeilepointer = zeile;
+
+ if (!strcmp(keyword,"escape"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_escape;
+ else if (!strcmp(keyword,"begingroup"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_begingroup;
+ else if (!strcmp(keyword,"endgroup"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_endgroup;
+ else if (!strcmp(keyword,"mathshift"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_mathshift;
+ else if (!strcmp(keyword,"alignmenttab"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_alignmenttab;
+ else if (!strcmp(keyword,"endofline"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_endofline;
+ else if (!strcmp(keyword,"space"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_space;
+ else if (!strcmp(keyword,"letter"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_letter;
+ else if (!strcmp(keyword,"active"))
+ {
+ int i,anzahl;
+ struct active_definition *ad;
+ unsigned char expansion[80];
+ catcodes[*zeilepointer++].catcode = catcode_active;
+ anzahl = atoi( zeilepointer );
+ ad = heap_allocate( active_heap, sizeof( struct active_definition ) + sizeof( struct active_expansion ) * ( anzahl - 1 ));
+ ad->character = *zeile;
+ ad->anzahl = anzahl;
+ ad->next = active_defs;
+ active_defs = ad;
+
+ for ( i = 0; i < anzahl; i++ )
+ {
+ fscanf( infofile, "%c\t%s\n", &( ((ad->expansion)[i]).of_what), expansion );
+ ((ad->expansion)[i]).what = heap_allocate( active_heap, strlen( expansion ) + 1 );
+ strcpy( ((ad->expansion)[i]).what, expansion );
+ } /* for i < anzahl */
+ }
+ else if (!strcmp(keyword,"escape_def"))
+ {
+ int i,anzahl;
+ unsigned char expansion[80];
+ anzahl = atoi( zeilepointer );
+ escape_def = heap_allocate( active_heap, sizeof( struct active_definition ) + sizeof( struct active_expansion ) * ( anzahl - 1 ));
+ escape_def->character = *zeile;
+ escape_def->anzahl = anzahl;
+ escape_def->next = NULL;
+
+ for ( i = 0; i < anzahl; i++ )
+ {
+ fscanf( infofile, "%c\t%s\n", &( ((escape_def->expansion)[i]).of_what), expansion );
+ ((escape_def->expansion)[i]).what = heap_allocate( active_heap, strlen( expansion ) + 1 );
+ strcpy( ((escape_def->expansion)[i]).what, expansion );
+ } /* for i < anzahl */
+ }
+ else if (!strcmp(keyword,"other"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_other;
+ else if (!strcmp(keyword,"ignored"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_ignored;
+ else if (!strcmp(keyword,"comment"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_comment;
+ else if (!strcmp(keyword,"escape"))
+ while ( *zeilepointer ) catcodes[*zeilepointer++].catcode = catcode_escape;
+ else if (!strcmp(keyword,"skipped_command"))
+ library_enter_entry( skipped_com, &zeile[1], 1 );
+ else if (!strcmp(keyword,"punctuation"))
+ strcpy( punctuation_chars, zeile );
+ else if (!strcmp(keyword,"sentenceend"))
+ strcpy( sentenceend_chars, zeile );
+ else if (!strcmp(keyword,"text_begingroup"))
+ strcpy( textbegingroup_chars, zeile );
+ else if (!strcmp(keyword,"text_endgroup"))
+ strcpy( textendgroup_chars, zeile );
+ else if (!strcmp(keyword,"capital")) /* 1.11.91 */
+ library_enter_entry( weird_capital, zeile, 1 );
+ else if (!strcmp(keyword,"skipped_environment"))
+ library_enter_entry( skipped_env, zeile, 1 );
+ else if (!strcmp(keyword,"delimiter_command"))
+ library_enter_entry( delimiter_com, &zeile[1], 1 );
+ else if (!strcmp(keyword,"end_of_file"))break;
+ else
+ printf( "Invalid command %s ignored; check infofile\n\b", keyword);
+ } /* while fgets */
+ actualtoken = next_token();
+ mode = mode_stack+1;
+ *mode = common_mode;
+} /* init_parser */
+
+static struct token next_token(void)
+{
+ unsigned char zeichen;
+ for (;;)
+ {
+ zeichen = getc( source );
+ if (feof(source)) break;
+ if ( zeichen == '\n' ) zeilenoffset++;
+ if (catcodes[zeichen].catcode != catcode_ignored ) return ( catcodes[zeichen] );
+ } /* while zeichen != EOF */
+ return( catcodes[0] );
+} /* next_token */
+
+
+
+unsigned char *next_word( int *end_of_sentence )
+{
+ static unsigned char wortbuffer[MAXWORT + 2];
+ unsigned char *wort;
+ unsigned char *wortzeiger;
+ unsigned char escapebuffer[MAXSTRING];
+ unsigned char *escapezeiger;
+ unsigned char parameterbuffer[MAXSTRING];
+ unsigned char *parameterzeiger;
+ unsigned char endbuffer[MAXSTRING];
+ unsigned char *endzeiger;
+ int wortlaenge = 0;
+
+ escapezeiger = escapebuffer;
+ end_of_sentence = &new_sentence;
+ wort = &wortbuffer[2];
+ wortzeiger = wort;
+ wortlaenge = 0;
+ zeilennummer += zeilenoffset;
+ zeilenoffset = 0;
+
+ while( 1 )
+ {
+ if ( wortzeiger < wort)
+ {
+ wortzeiger = wort;
+ printf("%s:%d:wortunderflow\n",texname, zeilennummer );
+ }
+ if ( wortzeiger >= &wort[MAXWORT-1])
+ {
+ printf("%s:%d:wortoverflow\n",texname, zeilennummer );
+ return(wort);
+ }
+ if ( mode <= mode_stack ) /* stack underflow verhindern */
+ {
+ zeilennummer += zeilenoffset;
+ zeilenoffset = 0;
+ fprintf( outputfile, "%s:%d: stack underflow\n",
+ texname, zeilennummer );
+ mode = mode_stack + 1;
+ *mode = common_mode;
+ };
+ if ( mode >= &mode_stack[ MODESTACK - 1] ) /* stack overflow */
+ {
+ zeilennummer += zeilenoffset;
+ zeilenoffset = 0;
+ fprintf( outputfile, "%s:%d: stack overflow\n",
+ texname, zeilennummer );
+ mode = mode_stack + 1;
+ *mode = common_mode;
+ };
+
+
+ switch( *mode )
+ {
+ case common_mode: /* normale buchstaben */
+ while( actualtoken.catcode == catcode_letter )
+ {
+ if (wortzeiger - wort >= MAXWORT) return(wort);
+ *wortzeiger++ = actualtoken.token;
+ wortlaenge++;
+ actualtoken = next_token();
+ }
+ switch( actualtoken.catcode )
+ {
+ case catcode_escape:
+ storemode( *mode );
+ *++mode = escape_mode; /* mode auf den stack */
+ if (wortzeiger - wort >= MAXWORT) return(wort);
+ *wortzeiger++ = actualtoken.token;
+ actualtoken = next_token();
+ escapezeiger = escapebuffer; /* initialisierung des escapebuffers */
+ break;
+ case catcode_begingroup:
+ storemode( *mode );
+ *++mode = common_mode;
+ actualtoken = next_token();
+ break;
+ case catcode_endgroup:
+ storemode( *mode );
+ --mode;
+ actualtoken = next_token();
+ break;
+ case catcode_mathshift:
+ /* *wortzeiger++ = actualtoken.token; */ /* mshift nicht an wort dran */
+ actualtoken = next_token();
+ break;
+ case catcode_endofline:
+ case catcode_space:
+ storemode( *mode );
+ *++mode = space_mode;
+ *wortzeiger = 0;
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ if ( actualtoken.token == '\n' )
+ {
+ zeilennummer += zeilenoffset;
+ zeilenoffset = 0;
+ }
+ wortzeiger = wort; wortlaenge = 0;
+ break;
+ case catcode_alignmenttab:
+ case catcode_other:
+ storemode( *mode );
+ *++mode = other_mode;
+ *wortzeiger = 0;
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ wortzeiger = wort; wortlaenge = 0;
+ break;
+ case catcode_active:
+ storemode( *mode );
+ *++mode = active_mode;
+ break;
+ case catcode_comment:
+ storemode( *mode );
+ *++mode = comment_mode;
+ break;
+ case catcode_ignored:
+ ;
+ break;
+ case catcode_eof:
+ return( NULL );
+
+ } /* local switch */
+ break;
+
+
+ case escape_mode: /* befehle */
+ switch( actualtoken.catcode )
+ {
+ case catcode_space:
+ *--wortzeiger = 0; /* \\ = \n wortzeiger eins runter, um alten backslash zu tilgen */
+ storemode( *mode );
+ *mode = space_mode;
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ wortzeiger = wort; wortlaenge = 0; /* neues wort anfangen */
+ break;
+ case catcode_escape:
+ *--wortzeiger = 0; /* \\ = \n wortzeiger eins runter, um alten backslash zu tilgen */
+ actualtoken = next_token(); /* naechstes token holen */
+ storemode( *mode );
+ mode--; /* alten mode vom stack holen */
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ wortzeiger = wort; wortlaenge = 0; /* neues wort anfangen */
+ break;
+ case catcode_other:
+ {
+ int i = 0;
+ while ( (((escape_def->expansion)[i]).of_what != actualtoken.token ) && ( i < escape_def->anzahl )) i++;
+
+ /* jetzt haben wir die makroexpansion und schauen ob sie geskippt werden muss */
+
+ if ( i == escape_def->anzahl ) ;
+ else
+ {
+ unsigned char string[80];
+ storemode( *mode );
+ mode--;
+ actualtoken = next_token();
+ strcpy( string,&(((escape_def->expansion)[i]).what[1])); /* kopieren ohne backslash */
+ string[strlen( string )-1] = 0;
+ if( library_find_entry( delimiter_com, string ))
+ {
+ *--wortzeiger = 0; /* eingefuegt 14.11.91 */
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ wortzeiger = wort; wortlaenge = 0;
+ break;
+ }
+ if ( library_find_entry( skipped_com, string ))
+ {
+ *--wortzeiger = 0; /* backslash wegwerfen */
+ }
+ else
+ {
+ wortzeiger--;
+ strcpy (wortzeiger, (( escape_def->expansion)[i] ).what);
+ wortzeiger += strlen((( escape_def->expansion)[i] ).what);
+ wortlaenge++;
+ }
+
+ break;
+ }
+ }
+ case catcode_begingroup: /* zeichen fuer geschweifte klammer auf */
+ case catcode_endgroup: /* zeichen fuer geschweifte klammer zu */
+ case catcode_mathshift: /* dollarzeichen */
+ case catcode_alignmenttab: /* ampersand */
+ case catcode_active:
+ case catcode_comment:
+ *wortzeiger++ = actualtoken.token;
+ actualtoken = next_token();
+ storemode( *mode );
+ mode--;
+ break;
+ case catcode_endofline:
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ *wortzeiger = 0;
+ actualtoken = next_token();
+ break;
+ case catcode_letter:
+ escapezeiger = escapebuffer;
+ do{
+ *escapezeiger++ = actualtoken.token;
+ actualtoken = next_token();
+ }while( actualtoken.catcode == catcode_letter );
+ *escapezeiger = 0;
+ if(!strcmp(escapebuffer,"begin"))
+ {
+ storemode( *mode );
+ *mode = parameter_mode;
+ if( actualtoken.catcode == catcode_comment )
+ {
+ storemode(*mode);
+ *++mode = comment_mode;
+ }
+ break;
+ }
+ if(!strcmp(escapebuffer,"end"))
+ {
+ storemode( *mode );
+ *mode = end_deletion_mode;
+ if( actualtoken.catcode == catcode_comment )
+ {
+ storemode( *mode );
+ *++mode = comment_mode;
+ }
+ break;
+ }
+ if(library_find_entry( delimiter_com, escapebuffer )) /* escapesequenz wortdelimiter (wie \quad)*/
+ {
+ storemode( *mode );
+ mode--;
+ *--wortzeiger = 0;
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ wortzeiger = wort; wortlaenge = 0;
+ }
+ else if ( library_find_entry( skipped_com, escapebuffer ))
+ {
+ storemode( *mode );
+ *mode = space_mode; /* damit der delimiting space ueberlesen wird, eingeb. 20.11.91 */
+ *--wortzeiger = 0;
+ }
+ else
+ {
+ strcpy( wortzeiger,escapebuffer );
+ wortzeiger += ( escapezeiger - escapebuffer );
+ *wortzeiger++ = '@'; /* statt eines leerzeichens in der library fuer z.B. stra\ss e */
+ storemode( *mode );
+ mode--;
+ while ( actualtoken.catcode == catcode_space ) actualtoken = next_token();
+ }
+ break;
+
+ case catcode_ignored:
+ ;
+ break;
+ case catcode_eof:
+ return( NULL );
+
+ } /* local switch */
+
+ break;
+
+ case parameter_mode: /* untersuchung von environment-parametern */
+ parameterzeiger = parameterbuffer;
+ while ( actualtoken.token == '[' )
+ while ( actualtoken.token != ']' )
+ {
+ actualtoken = next_token();
+ if ( actualtoken.catcode == catcode_eof ) return( NULL );
+ }
+ while ( actualtoken.catcode == catcode_begingroup )
+ actualtoken = next_token();
+ while ( actualtoken.catcode == catcode_letter )
+ {
+ *parameterzeiger++ = actualtoken.token;
+ actualtoken = next_token();
+ }
+ *parameterzeiger = 0;
+ if( library_find_entry( skipped_env, parameterbuffer ))
+ {
+ storemode( *mode );
+ *mode = skip_mode;
+ break;
+ }
+ else if ( actualtoken.token == '*' ) actualtoken = next_token();
+ while ( actualtoken.catcode == catcode_endgroup ) actualtoken = next_token();
+ storemode( *mode );
+ mode--;
+ break;
+
+ case other_mode: /* behandlung von others, insbes. interpunktion */
+ if ( punctuation_check )
+ {
+ if ( strchr( punctuation_chars, actualtoken.token ))
+ {
+ unsigned char mishandled_token = actualtoken.token;
+ actualtoken = next_token();
+ if ( actualtoken.catcode == catcode_eof ) return( NULL );
+ if ( strchr(sentenceend_chars, mishandled_token) &&
+ !isdigit( actualtoken.token )) *end_of_sentence = 1;
+ if ( ( actualtoken.catcode != catcode_space )&&
+ ( actualtoken.catcode != catcode_endofline )&&
+ !isdigit( actualtoken.token )&&
+ ( actualtoken.catcode != catcode_alignmenttab)&&
+ ( actualtoken.catcode != catcode_endgroup ))
+ {
+ fprintf(outputfile , "%s:%d: missing space after %c\n",
+ texname, zeilennummer, mishandled_token );
+ }
+ }
+ else /* if actualtoken.token is punctuation_char */
+ {
+ actualtoken = next_token();
+ }
+ }
+ else actualtoken = next_token(); /* if punctuation_check */
+ storemode( *mode );
+ mode--;
+ break;
+
+ case space_mode: /* skippen von leerzeichen */
+ while (( actualtoken.catcode == catcode_space )||( actualtoken.catcode == catcode_endofline))
+ actualtoken = next_token();
+ if ( actualtoken.catcode == catcode_eof ) return( NULL );
+ if ( punctuation_check )
+ if ( strchr( punctuation_chars, actualtoken.token ))
+ fprintf( outputfile , "%s:%d: extra space before %c\n", texname, zeilennummer, actualtoken.token );
+ storemode( *mode );
+ mode--;
+ break;
+ case skip_mode: /* environments{parameterbuffer} werden geskipt */
+ do {
+ do {
+ do {
+ do {
+ do {
+ if( actualtoken.catcode == catcode_eof ) return( NULL );
+ while ( actualtoken.catcode != catcode_escape )actualtoken = next_token();
+ if( actualtoken.catcode == catcode_eof ) return( NULL );
+ actualtoken = next_token();
+ }while( actualtoken.token != 'e' );
+ actualtoken = next_token();
+ }while( actualtoken.token != 'n' );
+ actualtoken = next_token();
+ }while( actualtoken.token != 'd' );
+ actualtoken = next_token();
+ }while( actualtoken.catcode != catcode_begingroup );
+ actualtoken = next_token();
+ endzeiger = endbuffer;
+ while( actualtoken.catcode == catcode_letter )
+ {
+ *endzeiger++ = actualtoken.token;
+ actualtoken = next_token();
+ }
+ *endzeiger = 0;
+ }while( 0 != strcmp( endbuffer,parameterbuffer ));
+ actualtoken = next_token();
+ if( actualtoken.catcode == catcode_eof ) return( NULL );
+ storemode( *mode );
+ mode--;
+ break;
+ case comment_mode: /* behandeln von kommentaren */
+ while ( actualtoken.catcode != catcode_endofline )
+ {
+ actualtoken = next_token();
+ if ( actualtoken.catcode == catcode_eof ) return( NULL );
+ }
+ if ( actualtoken.token == '\n' )
+ {
+ zeilennummer += zeilenoffset;
+ zeilenoffset = 0;
+ }
+ storemode( *mode ); /* 1.11.91 */
+ mode--; /* 1.11.91 */
+ actualtoken = next_token();
+ break;
+
+
+ case active_mode: /* untersuchen von active-characters */
+ {
+ unsigned char wrong_token;
+ struct active_definition *def;
+ int i=0;
+
+ storemode( *mode );
+ mode--;
+ def = active_defs;
+ while ( def->character != actualtoken.token ) def = def->next;
+ actualtoken = next_token();
+ while ( (((def->expansion)[i]).of_what != actualtoken.token ) && ( i < def->anzahl )) i++;
+
+ /* jetzt haben wir die makroexpansion und schauen ob sie geskippt werden muss */
+
+ wrong_token = actualtoken.token;
+ actualtoken = next_token();
+ if ( i == def->anzahl )
+ {
+ fprintf( outputfile, "%s:%d: active %c with unknown parameter %c\n",
+ texname, zeilennummer, def->character,wrong_token );
+ }
+ else
+ {
+ unsigned char string[80];
+ strcpy( string,&(((def->expansion)[i]).what[1])); /* kopieren ohne backslash */
+ string[strlen( string )-1] = 0;
+ if( library_find_entry( delimiter_com, string ))
+ {
+ if ( wortlaenge > MINDESTLAENGE )
+ return( wort );
+ wortzeiger = wort; wortlaenge = 0;
+ }
+ if ( library_find_entry( skipped_com, string ))
+ {
+ ;
+ }
+ else
+ {
+ strcpy (wortzeiger, ((def->expansion)[i]).what);
+ wortzeiger += strlen(((def->expansion)[i]).what);
+ wortlaenge++;
+ }
+ }
+ }
+ break;
+
+
+ case end_deletion_mode:
+ storemode( *mode );
+ mode--;
+ if ( actualtoken.catcode == catcode_begingroup )
+ while ( actualtoken.catcode != catcode_endgroup )
+ {
+ actualtoken = next_token();
+ if ( actualtoken.catcode == catcode_eof ) return ( NULL );
+ }
+ actualtoken = next_token();
+ break;
+ default:
+ ;
+ break;
+ } /* switch */
+ } /* while 1 */
+} /* next_word */
+
+static void exit_parser( void ) /* wirft die nebemlibraries weg */
+{
+ library_delete( skipped_com );
+ library_delete( skipped_env );
+ library_delete( delimiter_com );
+ library_delete( weird_capital );
+ heap_delete( active_heap );
+}
+
+
+int check_first_char( unsigned char *word ) /* prueft den ersten buchstaben */
+{ /* 1 = gross, 0 = klein */
+ unsigned char *hilfspointer;
+ while(word)
+ {
+ unsigned char string[MAXSTRING];
+ while( !is_a_letter( *word ))
+ {
+ if( *word == '\\' )
+ break;
+ word++;
+ }
+ if ( islower( *word ) ) return( 0 );
+ if ( isupper( *word ) ) return( 1 );
+
+ /* wir brauchen noch weird_capital fuer \L@ \AE@ etc. */
+
+ hilfspointer = word;
+ while( ( word )&&( *word != '@' )) /* bis zum @ kopieren */
+ word++; /* von hilfspointer bis word */
+ /* ist der bereich als capital definiert? 1 : continue; */
+ word++; /* affenschwanz mitnehmen */
+ strncpy( string, hilfspointer, min(word - hilfspointer,MAXSTRING) );
+ string[ min(word-hilfspointer,MAXSTRING-1) ] = 0;
+ if ( library_find_entry( weird_capital, string )) return( 1 );
+ }
+ return(0);
+}