home *** CD-ROM | disk | FTP | other *** search
- /******************************************************
- * INTUTIL.C *
- * Dieses File enthält Utility-Funktionen zum *
- * Erstellen eines neuen Interpreterbefehls oder *
- * dessen Ausführung. *
- * (c) 1991 Ralf Morgenstern & toolbox *
- * Dieses File beinhaltet NUR DIE ÄNDERUNGEN zur *
- * Grundversion von "INTUTIL.C". Wo es mit altem *
- * Sourcecode weitergeht, zeigt "..." an!!!!!!!! *
- ******************************************************/
- ...
-
- int CmpVar (void);
- int Compare (int Op);
- int ReadComp (int *Op);
-
- void ClearProg (void);
- /* die neuen Funktionen */
- void Expression (void);
- void Term (void);
- void Faktor (void);
- int TestFunc (int *func);
- void NewString (VARDEF *Var,size_t len);
- void MinMax (int Ops, int minmax);
- void Length (void);
- void Left (void);
- void Right (void);
- void Mid (void);
- void InStr(void);
-
- int TestComma (void);
- int GetStringVar (VAR **str);
- int GetLong (long *val);
- ...
-
- static int expOk;/* ist der ausgewertete Ausdruck korrekt */
-
- /* die Namen der Interpreterfunktionen */
- static char *ifuncs[] = { "sqr","sqrt","sin","cos","tan"
- ,"atan","ln","exp","min","max",
- "laenge", "links", "rechts"
- ,"mitte", "suche", NULL };
-
- /* und zugehörige Tokens zum Aufruf */
- #define NEGOP 'a'
- #define SQROP 'b'
- #define SQRTOP 'c'
- #define SINOP 'd'
- #define COSOP 'e'
- #define TANOP 'f'
- #define ATANOP 'g'
- #define LNOP 'h'
- #define EXPOP 'i'
-
- /* BEACHTE : einige der Funktionen werden direkt (also nicht
- über CalcResult aufgerufen), und brauchen daher
- kein Token. */
- ...
-
- if ( Steuer != EOLCHAR ){
- serror( "unerwartetes Zeilenende" ); return(ERROR);
- }
-
- ...
-
- /* NewString : neuen String bereitstellen oder
- den Speicher auf neue Grö₧e erweitern
- */
- void NewString ( Var,len )
- VARDEF *Var;
- size_t len;
- {
- len++; /* für '\0' Abschlu₧ */
- if ( Var->variable.text == NULL )
- Var->variable.text = calloc( len,sizeof(char));
- else
- Var->variable.text = realloc( Var->variable.text,len );
- }
- /* Einlesen eines Ausdrucks von der gerade aktuellen
- Eingabeposition ab.
- */
- void
- ReadValue (Wert)
- VAR *Wert;
- {
- Scan (); /* Nächster Ausdruck von Eingabezeile */
- switch (Steuer) {
- case ZIFFER:
- /*
- Wert->VarType = FIXNUM;
- Wert->VarWert.variable.integer = atoi (ScanBuffer);
- break;
- führt sonst zu Fehler, da CalcExpression nur FLONUM liefert
- */
- case FLONUM:
- Wert->VarType = FLONUM;
- Wert->VarWert.variable.Flotype = atof (ScanBuffer);
- break;
- case STRING:
- Wert->VarType = STRING;
- NewString ( &Wert->VarWert,strlen( ScanBuffer ));
- strcpy (Wert->VarWert.variable.text,ScanBuffer);
- break;
- case ALPHA:
- printf ("\nVariablenzuweisung noch nicht implementiert! ");
- break;
- case SONDER:
- if (*ScanBuffer == '(') {
- }
- else
- printf ("\nUngültiges Zeichen in Ausdruck gefunden! ");
- }
- }
- /*---- SetValue Setze den Wert der Variable ----------*/
- void
- SetValue (NewVar,Wert,Type)
- VARDEF *NewVar,*Wert;
- unsigned char Type;
- {
- switch (Type) {
- case FIXNUM:
- NewVar->variable.integer = Wert->variable.integer;
- break;
- case FLONUM:
- NewVar->variable.Flotype = Wert->variable.Flotype;
- break;
- case ALPHA: /* ist das so korrekt ? was mit Variablen ? */
- NewVar->variable.zeichen = Wert->variable.zeichen;
- break;
- case STRING:
- if ( NewVar->variable.text != NULL )
- free( NewVar->variable.text );
- NewVar->variable.text = Wert->variable.text;
- break;
- default:
- printf ("\nZuweisung für diesen Typ nicht definiert!\n");
- break;
- }
- }
- ...
-
- /* CmpVar vergleicht zwei Variablen auf
- Größer, Kleiner oder Gleich.
- */
- int CmpVar ()
- {
- int rel;
- int Op;
- BotStack = TopStack = malloc (EXPSTACK * sizeof(EXPDEF));
- Scan (); /* Erstes Argument lesen... */
- expOk = TRUE; Expression(); /* ... und auswerten */
- if ( !expOk ){
- serror ("Ungültiger 1. Ausdruck gefunden! ");
- return (FALSE); /* Bedingung fehlerhaft */
- }
- if ( ReadComp( &Op ) == FALSE ){
- serror ("Vergleichsoperator erwartet! ");
- return (FALSE); /* Bedingung fehlerhaft */
- }
- Scan(); /* Zweites Argument lesen... */
- expOk = TRUE; Expression(); /* ... und auswerten */
- if ( !expOk ){
- serror ("Ungültiger 2. Ausdruck gefunden! ");
- return (FALSE); /* Bedingung fehlerhaft */
- }
- rel = Compare( Op );
- free ( BotStack );
- /* Beachte : Stack wird im Fehlerfall nicht freigegeben */
- return (rel);
- }
-
- /* ReadComp: lies Vergleichsoperator ein
- */
- int
- ReadComp ( Op )
- int *Op;
- {
- int relop; /* korrekter Vergleichoperetor gefunden? */
- relop = TRUE; /* wir sind ja Optimisten */
- switch (*ScanBuffer) {
- case '/':
- Scan ();
- if (*ScanBuffer == '=')
- *Op = UNGL;
- else {
- SkipChar ();
- }
- break;
- case '>':
- Scan ();
- if (*ScanBuffer == '=')
- *Op = GRGL;
- else {
- SkipChar ();
- *Op = GR;
- }
- break;
- case '<':
- Scan ();
- if (*ScanBuffer == '=')
- *Op = KLGL;
- else {
- SkipChar ();
- *Op = KL;
- }
- break;
- case '=':
- *Op = GL;
- break;
- default:
- relop = FALSE;
- break;
- }
- return( relop );
- }
- /* Compare
- Vergleiche die Ausdrücke auf dem Stack.
- */
- int Compare ( Op )
- int Op;
- {
- EXPDEF *Var1,*Var2;
- int rel;
- if ((Var2 = PopExp()) == NULL) {
- return(FALSE);
- }
- if ((Var1 = PopExp()) == NULL) {
- return( Var2->val.wert != 0 );
- }
- if (Var1->type == Var2->type) {
- if ( Var1->type == ZAHL ){
- switch (Op) { /* hier wird endlich verglichen */
- case GL:
- return ((Var1->val.wert == Var2->val.wert) ?
- TRUE : FALSE);
- case GRGL:
- return ((Var1->val.wert >= Var2->val.wert) ?
- TRUE : FALSE);
- case GR:
- return ((Var1->val.wert > Var2->val.wert) ?
- TRUE : FALSE);
- case KLGL:
- return ((Var1->val.wert <= Var2->val.wert) ?
- TRUE : FALSE);
- case KL:
- return ((Var1->val.wert < Var2->val.wert) ?
- TRUE : FALSE);
- case UNGL:
- return ((Var1->val.wert != Var2->val.wert) ?
- TRUE : FALSE);
- }/*switch*/
- }/* ZAHL */
- else if ( Var1->type == TEXT ){
- rel = strcmp( Var1->val.text,Var2->val.text );
- switch ( Op ) {
- case GL : return (( rel == 0 ) ? TRUE : FALSE );
- case GRGL : return (( rel >= 0 ) ? TRUE : FALSE );
- case GR : return (( rel > 0 ) ? TRUE : FALSE );
- case KLGL : return (( rel <= 0 ) ? TRUE : FALSE );
- case KL : return (( rel < 0 ) ? TRUE : FALSE );
- case UNGL : return (( rel != 0 ) ? TRUE : FALSE );
- }
- } /* TEXT */
- } /* type equal */
- return(TRUE); /* nur für den Compiler */
- } /* Compare */
- /* druckt eine Variable aus */
- void
- PrintVar (Name)
- char *Name;
- {
- VAR *Variable;
-
- /* wenn es Variable mit dem gesuchten Namen gibt, merken! */
- if ((Variable = IsVariable (Name)) != NULL) {
- switch (Variable->VarType) {
- case FIXNUM:
- printf ("%d",Variable->VarWert.variable.integer);
- break;
- case FLONUM:
- printf ("%f",Variable->VarWert.variable.Flotype);
- break;
- case STRING:
- printf( "%s",Variable->VarWert.variable.text );
- break;
- default:
- printf ("\nVariablentyp kann nicht gedruckt werden!\n");
- break;
- }
- }
- else {
- char buffer[40];
- sprintf (buffer,"Variable <%s> unbekannt! ",Name);
- fatal_error (buffer);
- }
- }
-
- /* CalcExpression: berechnet das Ergebnis eines Ausdrucks
- */
- int CalcExpression (Result)
- VAR *Result;
- {
- /* VAR *Variable; */
- BotStack = TopStack = malloc (EXPSTACK * sizeof(EXPDEF));
- Scan (); /* den ersten Ausdruck einlesen */
- if (Steuer == EOLCHAR)
- return (ERROR);
- expOk = TRUE; Expression();
- SetResultValue( Result );
- free (BotStack); /* Speicher wieder freigeben */
- if ( expOk ) return (OK);
- else return (ERROR);
- }
-
- /* Expression, Term und Faktor werten einen Ausdruck aus */
- void Expression (void)
- {
- char addop;
- if (( Steuer == SONDER ) &&
- (( *ScanBuffer == '+' ) || ( *ScanBuffer == '-' )) &&
- expOk ){
- addop = *ScanBuffer;
- Scan(); Term();
- if ( addop == '-' ) CalcResult( NEGOP,1 );
- }
- else Term();
- while (( Steuer == SONDER ) &&
- (( *ScanBuffer == '+' ) || ( *ScanBuffer == '-' ))
- && expOk ){
- addop = *ScanBuffer;
- Scan(); Term();
- CalcResult( addop,2 );
- }
- }/* Expression */
- void Term (void )
- {
- char mulop;
- Faktor();
- while (( Steuer == SONDER ) &&
- (( *ScanBuffer == '*' ) || ( *ScanBuffer == '/' ))
- && expOk ){
- mulop = *ScanBuffer;
- Scan(); Faktor();
- CalcResult( mulop,2 );
- }
- }/* Term */
-
- ...
- int TestFunc ( func )
- int *func;
- {
- register int i,j;
- for ( i=0;
- ( ifuncs[ i ] != NULL ) &&
- ( j = strcmp( ifuncs[ i ],ScanBuffer ) != 0 );
- i++ );
- *func = i;
- return( j );
- }/* TestFunc */
-
- /* SetResultValue: wandelt das Berechnungsergebnis in die
- Variablenstruktur */
- void
- SetResultValue (Result)
- VAR *Result;
- {
- switch (BotStack->type) {
- case ZAHL: /* Zahlen in Fließkommadarstellung */
- Result->VarWert.variable.Flotype = BotStack->val.wert;
- Result->VarType = FLONUM;
- break;
- case TEXT:
- Result->VarWert.variable.text = BotStack->val.text;
- Result->VarType = STRING;
- break;
- case FELD:
- fatal_error ("Arrayzuweisung noch nicht implementiert!");
- break;
- default:
- fatal_error ("Unbekannter Zahlentyp gefunden! ");
- break;
- }
- }
- /* PushExp
- welche in ScanBuffer steht auf Stack ablegen.
- */
- void
- PushExp ()
- {
- VAR *Variable;
- switch (Steuer) {
- case ZIFFER:
- case FLONUM:
- TopStack->type = ZAHL;
- TopStack->val.wert = atof (ScanBuffer);
- break;
- case ALPHA:
- /* Wenn es die Variable gibt, Zeiger drauf und merken! */
- if ((Variable = IsVariable (ScanBuffer)) != NULL) {
- switch (Variable->VarType) {
- case ZIFFER:
- TopStack->type = ZAHL;
- TopStack->val.wert =
- Variable->VarWert.variable.integer;
- break;
- case FLONUM:
- TopStack->type = ZAHL;
- TopStack->val.wert = Variable->
- VarWert.variable.Flotype;
- break;
- case STRING :
- TopStack->type = TEXT;
- TopStack->val.text =
- malloc(strlen(Variable->VarWert.variable.text
- )+1);
- strcpy( TopStack->val.text,
- Variable->VarWert.variable.text );
- break;
- default :
- serror ("Typ für Operation nicht erlaubt! ");
- break;
- }
- }
- else
- serror ("Variable nicht definiert! ");
- break;
- case STRING:
- TopStack->type = TEXT;
- TopStack->val.text = malloc( strlen(ScanBuffer)+1);
- strcpy( TopStack->val.text,ScanBuffer );
- break;
- default:
- serror ("Keine Operation für diesen Typ vorhanden!");
- break;
- }
- TopStack++; /* Stackpointer an die nächste Position */
- }
-
- /* CalcResult: berechnet das Ergebnis eines Ausdrucks,
- der sich auf dem Stack befindet
- */
- void
- CalcResult ( Op,Ops )
- int Op,Ops;
- {
- EXPDEF *Var1,*Var2,Result;
- char *v1,*v2;
- size_t l1,l2;
- /* da die Anzahl der Parameter schon in <Faktor> überprüft
- wird, sparen wir uns hier weitere Kontrollen
- */
- Var1 = PopExp();
- if( Ops > 1 ) Var2 = PopExp();
- if (( Ops == 1 ) || ( Var1->type == Var2->type )) {
- if ( Var1->type == ZAHL ){
- switch (Op) {
- case '+':
- Result.val.wert = Var2->val.wert + Var1->val.wert;
- break;
- case '-':
- Result.val.wert = Var2->val.wert - Var1->val.wert;
- break;
- case '*':
- Result.val.wert = Var2->val.wert * Var1->val.wert;
- break;
- case '/':
- Result.val.wert = Var2->val.wert / Var1->val.wert;
- break;
- case NEGOP :
- Result.val.wert = -Var1->val.wert;
- break;
- case SQROP :
- Result.val.wert = Var1->val.wert * Var1->val.wert;
- break;
- case SQRTOP :
- Result.val.wert = sqrt ( Var1->val.wert );
- break;
- case SINOP :
- Result.val.wert = sin ( Var1->val.wert*M_PI/180 );
- break;
- case COSOP :
- Result.val.wert = cos ( Var1->val.wert*M_PI/180 );
- break;
- case TANOP :
- Result.val.wert = tan ( Var1->val.wert*M_PI/180 );
- break;
- case ATANOP :
- Result.val.wert = 180/M_PI*atan ( Var1->val.wert );
- break;
- case LNOP :
- Result.val.wert = log ( Var1->val.wert );
- break;
- case EXPOP :
- Result.val.wert = exp ( Var1->val.wert );
- break;
- }/* switch */
- TopStack->val.wert = Result.val.wert;
- }/* ZAHL */
- else if ( Var1->type == TEXT ){
- /* für / + * gemeinsame Anweisungen */
- l1 = strlen( Var1->val.text );
- l2 = strlen( Var2->val.text );
- v1 = Var1->val.text;
- switch ( Op ){
- case '+' :
- Var2->val.text = realloc( Var2->val.text,l1+l2+1);
- v2 = Var2->val.text;
- while ( *v2++ != '\0' ); v2--; /* ohne '\0' */
- v1 = Var1->val.text;
- while (( *v2++ = *v1++ ) != '\0' );
- break;
- case '*' :
- case '/' :
- if ( l1 > l2 ) l1 = l2;
- v2 = Var2->val.text;
- if ( Op == '/' ) v2 += ( l2 - l1 );
- /* bis auf diese Anweisung, sind die beiden gleich */
- while ( l1-- > 0 ) *v2++ = *v1++; /* ohne '\0' */
- break;
- }/* switch Op */
- free( Var1->val.text );
- TopStack->val.text = Var2->val.text;
- }/* TEXT */
- TopStack->type = Var1->type;
- TopStack++;
- }
- else
- serror("Operation für Variablentyp nicht implementiert!");
-
- }/* CalcResult */
-
- /* MinMax: Je nach Wert des Parameters minmax, Minimum oder
- Maximum der durch Ops bestimmten Anzahl Werte auf
- dem Stack,ermitteln eine Funktion für min und max.
- , weil beide bis auf den Vergleich identisch sind.
- */
- void MinMax ( Ops,minmax )
- int Ops,minmax;
- {
- EXPDEF Result,*Var;
- Var = PopExp();
- Result.val.wert = Var->val.wert;
- Result.type = Var->type;
-
- /* eigentlich müssen wir noch auf ZAHL testen */
- while ( --Ops > 0 ){
- Var = PopExp();
- if ( Var->type != Result.type ){
- serror( "nur gleiche Typen für <max> erlaubt" );
- break;
- }
- if ( minmax == 1 ){
- if ( Var->val.wert > Result.val.wert )
- Result.val.wert = Var->val.wert;
- }
- else{
- if ( Var->val.wert < Result.val.wert )
- Result.val.wert = Var->val.wert;
- }
- }
- TopStack->type = Result.type;
- TopStack->val.wert = Result.val.wert;
- TopStack++;
- }/* MinMax */
-
- /* Length : die Länge eines Strings */
- void Length( void )
- {
- EXPDEF *top;
- size_t len;
- top = PopExp();
- if ( top->type != TEXT ){
- fatal_error( "STRING erwartet in <laenge>" ); return;
- }
- len = strlen( top->val.text );
- free( top->val.text );
- TopStack->type = ZAHL;
- TopStack->val.wert = (float)len;
- TopStack++;
- }/* Length */
- /* Left : die durch anz bestimmte Anzahl Zeichen von links
- her aus einem String.
- Syntax : links "(" String "," Zahl ")"
- String und zahl können jeweils ein Ausdruck des
- entsprechenden Typs sein.
- Bsp. setze l=links(s+"...",x-2);
- */
- void Left( void )
- {
- EXPDEF *str,*anz;
- char *s;
- anz = PopExp();
- if ( anz->type != ZAHL ){
- fatal_error( "<links> erwartet ZAHL als 2. P." );
- return;
- }
- str = PopExp();
- if ( str->type != TEXT ){
- fatal_error( "<links> erwartet STRING als 1. P." );
- return;
- }
- s = str->val.text + (long)anz->val.wert;
- *s = '\0'; /* den Rest einfach abschneiden */
- TopStack->type = TEXT;
- TopStack->val.text = str->val.text;
- TopStack++;
- }/* Left */
- /* Right : wie Left, nur sind hier die Zeichen vom rechten
- Ende her gewünscht
- Syntax : rechts "(" String "," Zahl ")"
- */
- void Right( void )
- {
- EXPDEF *str,*anz;
- char *s,*d;
- size_t l;
- anz = PopExp();
- if ( anz->type != ZAHL ){
- fatal_error( "<rechts> erwartet ZAHL als 2. P." );
- return;
- }
- str = PopExp();
- if ( str->type != TEXT ){
- fatal_error( "<rechts> STRING als 1. P." ); return;
- }
- l = strlen( str->val.text );
- if ( (long)anz->val.wert > l ) anz->val.wert = l;
- s = str->val.text;
- d = s + ( l - (long)anz->val.wert );
- while ( (*s++ = *d++ ) != '\0' );
- /* den rechten Teil zum Stringanfang hinziehen */
- TopStack->type = TEXT;
- TopStack->val.text = str->val.text;
- TopStack++;
- }
- /* Right
- Mid : hier wird mitten hinein gegriffen
- Syntax mitte "(" String "," Zahl1 "," Zahl2 ")"
- "Zahl1" bestimmt, ab welcher Position "Zahl"
- "viel" Zeichen genommen werden.
- */
- void Mid ( void )
- {
- EXPDEF *str,*start,*anzahl;
- char *mid,*s,*d;
- int ab,anz,len;
- anzahl = PopExp();
- if ( anzahl->type != ZAHL ){
- fatal_error( "<mitte> erwartet ZAHL als 3.P." );
- return;
- }
- else anz = (int)anzahl->val.wert;
- start = PopExp();
- if ( start->type != ZAHL ){
- fatal_error( "<mitte> erwartet ZAHL als 2.P." );
- return;
- }
- else ab = (int)start->val.wert;
- str = PopExp();
- if ( str->type != TEXT ){
- fatal_error( "<mitte> erwartet STRING als 1.P." );
- return;
- }
- else len = (int)strlen( str->val.text );
- if ( ab > len ){ /* Anfangsposition hinter Stringende */
- *TopStack->val.text = '\0';
- }
- else {
- if ( anz > ( len - ab )) anz = len - ab;
- mid = calloc( anz,sizeof( char ));
- s = str->val.text + (long)ab;
- d = mid;
- while ( anz-- > 0 ) *d++ = *s++; *d = '\0';
- free( str->val.text );
- TopStack->val.text = mid;
- }
- TopStack->type = TEXT;
- TopStack++;
- /* Mid */
-
- /* Instr : suche pattern in String ab Position start
- Syntax : suche "(" String "," Stringvariable "," Zahl ")"
- Bsp. setze pos=suche("wie","na wie geht's",0);
- */
-
- void InStr( void )
- {
- EXPDEF *pattern,*str,*start;
- char *search,*find;
- size_t len;
- long ab,pos;
- start = PopExp();
- if ( start->type != ZAHL ){
- serror( "<suche> erwartet ZAHL als 2.P." ); return;
- }
- else ab = (long)start->val.wert;
- str = PopExp();
- if ( str->type != TEXT ){
- serror( "<suche> erwartet STRING als 2.P." ); return;
- }
- else len = strlen( str->val.text );
- pattern = PopExp();
- if ( pattern->type != TEXT ){
- serror( "<suche> erwartet STRING als 1.P." ); return;
- }
- if ( ab > len ){ /* Anfangsposition hinter Stringende */
- TopStack->val.wert = -1;
- }
- else {
- search = str->val.text + ab; /* ab hier ... */
- find = strstr( search,pattern->val.text ); /* .suchen */
- if ( find == NULL ) pos = -1; /* nicht gefunden */
- else pos = find - str->val.text; /* bei pos gefunden */
- free( str->val.text );
- free( pattern->val.text );
- TopStack->val.wert = (float)pos;
- }
- TopStack->type = ZAHL;
- TopStack++;
- }/* InStr */
-
- /* PopExp
- Holt einen Ausdruck vom Variablenstack
- */
-
- EXPDEF *
- PopExp ()
- {
- if (TopStack-- != BotStack)
- return (TopStack);
- else
- return (NULL);
- }
-
- /* ClearProg: den Speicherplatz, der durch das Programm
- belegt ist, freigeben
- */
-
- void
- ClearProg ()
- {
- PRGZEILE *Memory;
- ActLine = FirstLine; /* Zeiger auf erste Programmzeile */
- while (ActLine) {
- Memory = ActLine; /* wird gleich benötigt */
- ActLine = ActLine->NextZeile;
- /* das ist die nächste Zeile */
- free (Memory); /* Speicherplatz freigeben */
- }
- FirstLine = ActLine = NULL; /* Zeiger zurücksetzen */
- }
-
- /* TestComma : teste ob das zeichen im ScanBuffer
- ein "," ist
- */
-
- int TestComma()
- {
- if (( Steuer == SONDER ) && ( *ScanBuffer == ',' ))
- return ( TRUE );
- else{
- serror( ", erwartet" ); return ( FALSE );
- }
- }
-
- /* GetStringVar : lies den nächsten Bezeichner und liefere
- die zugehörige Variable
- */
-
- int GetStringVar ( str )
- VAR **str;
- {
- Scan();
- if( Steuer != ALPHA ){
- serror( "Bezeichner erwartet" );
- return( FALSE );
- }
- if (( *str = IsVariable( ScanBuffer )) == NULL ){
- fatal_error( "Variable existiert nicht" );
- return( FALSE );
- }
- return ( TRUE );
- }
-
- /* GetLong : lies und berechne den nächsten Ausdruck, und
- liefere seinen Wert als long-Grö₧e
- */
- int GetLong ( val )
- long *val;
- {
- VAR Var;
- CalcExpression( &Var );
- if ( Var.VarType == FLONUM ){
- *val = (long)Var.VarWert.variable.Flotype;
- return ( TRUE );
- }
- else if ( Var.VarType == FIXNUM ){
- *val = (long)Var.VarWert.variable.integer;
- return ( TRUE );
- }
- else{
- serror( "ZAHL erwartet" ); return( FALSE );
- }
- }
- /*--------------------------------------------------------*/
- /* Ende von INTUTIL.C */
-