#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);
}