Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields  

toyparse.c

00001 /***************************************************************************
00002                           toyparse.c  -  Core code for the Toy Memory
00003     Manager's parsing engine.  Both ToyLoad.c and ToyParseCmd.c use it.
00004 
00005                              -------------------
00006     begin                : Sat Jan 25 2003
00007     copyright            : (C) 2003 by Tyler Montbriand
00008     student #            : 200200370
00009     class                : CS330
00010     email                : monttyle@heavyspace.ca
00011 ***************************************************************************/
00012 
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <ctype.h>
00017 #include <malloc.h>
00018 #include <stdarg.h>
00019 #include "ToyMem.h"
00020 #include "toyparse.h"
00021 #include "toyparse_internal.h"
00022 
00023 
00025 /*#define PRINT_COMMENTS*/
00026 
00036 int CheckLineSyntax(TokenType *tarray, ...)
00037 {
00038   long int type=-1,subtype=-1;
00039   int pos=0;
00040   int syntaxok=0;
00041   va_list a;
00042 
00043   if(tarray==NULL)  return(-1);
00044 
00045   /*  Start getting arguments from the variable-arg part  */
00046   va_start(a,tarray);
00047   {
00048     /*  Loop while we're not done       */
00049     while((syntaxok==0)&&((type!=TYPE_ENDOPEN)||(type!=TYPE_ENDCLOSE)))
00050     {
00051       type=va_arg(a,int);       /*      Get next argument       */
00052       if((type==TYPE_ENDOPEN)||(type==TYPE_ENDCLOSE))
00053       {
00054         /*  Last argument */
00055         break;
00056       }
00057 
00058       subtype=va_arg(a,int);  /*  Get next argument     */
00059       if((subtype==TYPE_ENDOPEN)||(subtype==TYPE_ENDCLOSE))
00060       {
00061         /*  Last argument in wrong place! */
00062         syntaxok=-1;
00063         break;
00064       }
00065 
00066       /*  Check if syntax matches */
00067       if((tarray[pos].token==NULL)||(tarray[pos].type!=type)||(tarray[pos].subtype==-1))
00068       {
00069         syntaxok=-1;
00070       }
00071       else if((subtype!=-1)&&(tarray[pos].subtype!=subtype))
00072       {
00073         syntaxok=-1;
00074       }
00075       /*  Increment position in array */
00076       pos++;
00077     }
00078   }
00079   va_end(a);
00080 
00081   if(syntaxok!=0)                   return(-1);
00082   else if(type==TYPE_ENDOPEN)       return( 0);
00083   else if(tarray[pos].token==NULL)  return( 0);
00084   else                              return(-1);
00085 }
00086 
00087 
00091 TokenType *LineToTypes(const char *str, const char **table[])
00092 {
00093   TokenType *tarray=NULL;
00094   /*  Create array of token-strings  */
00095   char **strList=Explode(str);
00096 
00097   /*  Convert token strings to array of types */
00098   tarray=TokensToType((const char **)strList,table);
00099   /*  Note that this is **NOT**  FreeStrList().  We want
00100       to free the array containing the strings, but not the
00101       strings themselves - that way, the strings in tarray
00102       are still valid and freeable.                         */
00103   free(strList);
00104   /*  Return array of types */
00105   return(tarray);
00106 }
00107 
00111 void FreeType(TokenType *types)
00112 {
00113   int n;
00114   if(types==NULL) return;
00115 
00116   for(n=0; types[n].token!=NULL; n++)
00117   {
00118     free((void *)types[n].token);
00119   }
00120   free(types);
00121 }
00122 
00126 TokenType *TokensToType(const char **tokens, const char **table[])
00127 {
00128   int size=-1, n=-1;
00129   TokenType *tarray;
00130 
00131   if(tokens==NULL)
00132   {
00133     tarray=(TokenType *)malloc(sizeof(TokenType));
00134     tarray->type=-1;
00135     tarray->subtype=-1;
00136     tarray->token=NULL;
00137     return(tarray);
00138   }
00139 
00140   /*  Count # strings in token list */
00141   for(size=0; tokens[size]!=NULL; size++);
00142 
00143   /*  Allocate array of token descriptors */
00144   tarray=(TokenType *)malloc((size+1)*sizeof(TokenType));
00145 
00146   /*  Loop through token strings and array  */
00147   for(n=0; n<size; n++)
00148   {
00149     /*  Get the base type, if any */
00150     int type=DetermineType(tokens[n],table);
00151     /*  Set string in array to match  */
00152     tarray[n].token=(char *)tokens[n];
00153     tarray[n].type=type;
00154     if(type==-1)
00155     { /*  If type is unknown, subtype is too  */
00156       tarray[n].subtype=-1;
00157     }
00158     else
00159     {
00160       /*  Look up and set subtype */
00161       tarray[n].subtype=DetermineSubType(type,tokens[n],table);
00162     }
00163   }
00164 
00165   /*  Terminate it, to mark end */
00166   tarray[size].type=-1;
00167   tarray[size].subtype=-1;
00168   tarray[size].token=NULL;
00169 
00170   return(tarray);
00171 }
00172 
00176 int DetermineSubType(int type,const char *str, const char **args[])
00177 {
00178   int n=-1;
00179   if((args==NULL)||(type<0))  return(-1);
00180 
00181   /*  Ensure that 'type' is actually in the list  */
00182   for(n=0; (n<type)&&(args[n]!=NULL); n++);
00183 
00184   /*  Went past the end of the list */
00185   if(args[n]==NULL)  return(-1);
00186 
00187   return(FindInList(str,args[n]));
00188 }
00189 
00193 int FindInList(const char *str, const char *list[])
00194 {
00195   int n;
00196   for(n=0; list[n]!=NULL; n++)
00197     if(CompareType(str,list[n])>=0) return(n);
00198 
00199   return(-1);
00200 }
00201 
00205 int DetermineType(const char *str, const char **table[])
00206 {
00207   int i;
00208 
00209   for(i=0; table[i]!=NULL; i++)
00210   {
00211     if(table[i]!=NULL)
00212     if(FindInList(str,table[i])>=0)  return(i);
00213   }
00214   return(-1);
00215 }
00216 
00220 int CompareType(const char *str, const char *typestr)
00221 {
00222   int error=0,strpos=0,typepos=0;
00223   if((str==NULL)||(typestr==NULL))  return -1;
00224 
00225   /* Loop until entire string is parsed */
00226   while(!error&&(str[strpos]!='\0')&&(typestr[typepos]!='\0'))
00227   {
00228     /* Case sensitive string matching. */
00229     while(typestr[typepos]==str[strpos])
00230     {
00231       if((typestr[typepos]=='\0')||(str[strpos]=='\0')||(typestr[typepos]=='%'))
00232         break;
00233 
00234         typepos++;
00235         strpos++;
00236     }
00237 
00238     /* Three cases:   1) Both strings ended, which is OK.
00239                       2) One did, the other didn't.  Bad.
00240                       3) A variable argument was encountered in typestr.  */
00241 
00242     /* Strings match */
00243     if((typestr[typepos]=='\0')&&(str[strpos]=='\0'))
00244     {     return(0);    }
00245     else if((typestr[typepos]=='\0')||(str[strpos]=='\0'))
00246     {
00247       /* Strings didn't match. */
00248       return(-1);
00249     }
00250     else if(typestr[typepos]=='%')
00251       switch(toupper(typestr[typepos+1]))
00252       {
00253       case 'S':
00254         /* Anything goes, so just return true */
00255         return(0);
00256         break;
00257 
00258       case 'U':
00259         while(isdigit(str[strpos]))  strpos++;
00260         /* Advance past "%u" */
00261         typepos+=2;
00262         break;
00263 
00264       default:
00265         /* End of string or invalid type */
00266         return(-1);
00267       }
00268     else
00269     {
00270       return(-1);
00271     }
00272   }
00273 
00274   /* Type matches */
00275 
00276   if((str[strpos]=='\0')&&(typestr[typepos]=='\0'))
00277     return 0;
00278   else /* types don't match */
00279     return(-1);
00280 }
00281 
00282 
00283 void *AllocateArray(void *in, int size, int num);
00284 
00285 
00291 char **Explode(const char *strIn)
00292 {
00293   char **strList=NULL;
00294   int pos=0,numStr=0;
00295 
00296   /*  Ignore whitespace */
00297   while(isspace(strIn[pos]))    pos++;
00298 
00299   while(strIn[pos]!='\0')
00300   {
00301     /* Ignore whitespace */
00302     while(isspace(strIn[pos])) pos++;
00303 
00304     /* If we haven't reached the end of the string, must be another
00305        word.                                                          */
00306     if(strIn[pos]!='\0')
00307     {
00308       char buf[100];
00309       int bufPos=0;
00310 
00311       /* If we find a comment, stop parsing the line */
00312       if((strIn[pos]=='/')&&(strIn[pos+1]=='/'))
00313       {
00314         pos+=2;
00315 #ifdef PRINT_COMMENTS
00316         /*  Prints comments for debugging */
00317         printf("//");
00318         while((strIn[pos]!='\0')&&(strIn[pos]!='\n')&&(strIn[pos]!='\r'))
00319         {
00320           /* Print the string, except for CR/LF stuff at the end  */
00321           printf("%c",strIn[pos++]);
00322         }
00323         printf("\n"); /* Print one linefeed */
00324 #endif
00325         /* Fast-forward to end of string  */
00326         while(strIn[pos]!='\0') pos++;
00327 
00328         continue;
00329       }
00330       strList=(char **)AllocateArray(strList,sizeof(char *),numStr+1);
00331       numStr++;
00332       while(!isspace(strIn[pos])&&(strIn[pos]!='\0')&&(bufPos<(100-1)))
00333       {
00334         /* Add letters to the end of our string */
00335         buf[bufPos++]=strIn[pos++];
00336       }
00337 
00338       buf[bufPos++]='\0'; /* NULL terminator */
00339       /* Allocate memory for string */
00340       strList[numStr-1]=(char *)malloc(bufPos);
00341       /* Copy string into new memory */
00342       strcpy(strList[numStr-1],buf);
00343     }
00344   }
00345 
00346   if(strList==NULL)
00347   {
00348     /* Don't bother returning any mem if the list is empty */
00349     return(NULL);
00350   }
00351   else
00352   {
00353     /* Tack a NULL onto the end of the list so we can tell where it ends
00354        */
00355     strList=(char **)AllocateArray(strList,sizeof(char *),numStr+1);
00356     strList[numStr]=NULL;
00357     return(strList);
00358 
00359   }
00360 }
00361 
00366 void *AllocateArray(void *in, int size, int num)
00367 {
00368   if(in==NULL)  return(malloc(size*num));
00369   else          return(realloc(in,size*num));
00370 
00371 }
00372 
00377 void FreeStrList(char **strList)
00378 {
00379   int n;
00380   if(strList==NULL) return;
00381 
00382   for(n=0; strList[n]!=NULL; n++)
00383   {
00384     free(strList[n]);
00385   }
00386 
00387   free(strList);
00388 }
00389 
00390 

Generated on Fri Apr 4 14:29:07 2003 for ToyMem by doxygen1.3-rc3