Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

toyparse.c

Go to the documentation of this file.
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                : tsm@accesscomm.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 "toyparse.h"
00020 #include "toyparse_internal.h"
00021 
00028 
00030 /*#define PRINT_COMMENTS*/
00031 
00041 int CheckLineSyntax(TokenType *tarray, ...)
00042 {
00043   long int type=-1,subtype=-1;
00044   int pos=0;
00045   int syntaxok=0;
00046   va_list a;
00047 
00048   if(tarray==NULL)  return(-1);
00049 
00050   /*  Start getting arguments from the variable-arg part  */
00051   va_start(a,tarray);
00052   {
00053     /*  Loop while we're not done       */
00054     while((syntaxok==0)&&((type!=TYPE_ENDOPEN)||(type!=TYPE_ENDCLOSE)))
00055     {
00056       type=va_arg(a,int);       /*      Get next argument       */
00057       if((type==TYPE_ENDOPEN)||(type==TYPE_ENDCLOSE))
00058       {
00059         /*  Last argument */
00060         break;
00061       }
00062 
00063       subtype=va_arg(a,int);  /*  Get next argument     */
00064       if((subtype==TYPE_ENDOPEN)||(subtype==TYPE_ENDCLOSE))
00065       {
00066         /*  Last argument in wrong place! */
00067         syntaxok=-1;
00068         break;
00069       }
00070 
00071       /*  Check if syntax matches */
00072       if((tarray[pos].token==NULL)||(tarray[pos].type!=type)||(tarray[pos].subtype==-1))
00073       {
00074         syntaxok=-1;
00075       }
00076       else if((subtype!=-1)&&(tarray[pos].subtype!=subtype))
00077       {
00078         syntaxok=-1;
00079       }
00080       /*  Increment position in array */
00081       pos++;
00082     }
00083   }
00084   va_end(a);
00085 
00086   if(syntaxok!=0)                   return(-1);
00087   else if(type==TYPE_ENDOPEN)       return( 0);
00088   else if(tarray[pos].token==NULL)  return( 0);
00089   else                              return(-1);
00090 }
00091 
00092 
00096 TokenType *LineToTypes(const char *str, const char **table[])
00097 {
00098   TokenType *tarray=NULL;
00099   /*  Create array of token-strings  */
00100   char **strList=NULL;
00101 
00102   if((str==NULL)||(table==NULL)) return(NULL);
00103   
00104   strList=Explode(str);
00105 
00106   if(strList==NULL)
00107   {
00108     return(NULL);
00109   }
00110 
00111   /*  Convert token strings to array of types */
00112   tarray=TokensToType((const char **)strList,table);
00113   /*  Note that this is **NOT**  FreeStrList().  We want
00114       to free the array containing the strings, but not the
00115       strings themselves - that way, the strings in tarray
00116       are still valid and freeable.                         */
00117   free(strList);
00118   /*  Return array of types */
00119   return(tarray);
00120 }
00121 
00125 void FreeType(TokenType *types)
00126 {
00127   int n;
00128   if(types==NULL) return;
00129 
00130   for(n=0; types[n].token!=NULL; n++)
00131   {
00132     free((void *)types[n].token);
00133   }
00134   free(types);
00135 }
00136 
00140 TokenType *TokensToType(const char **tokens, const char **table[])
00141 {
00142   int size=-1, n=-1;
00143   TokenType *tarray;
00144 
00145   if(tokens==NULL)
00146   {
00147     tarray=(TokenType *)malloc(sizeof(TokenType));
00148     tarray->type=-1;
00149     tarray->subtype=-1;
00150     tarray->token=NULL;
00151     return(tarray);
00152   }
00153 
00154   /*  Count # strings in token list */
00155   for(size=0; tokens[size]!=NULL; size++);
00156 
00157   /*  Allocate array of token descriptors */
00158   tarray=(TokenType *)malloc((size+1)*sizeof(TokenType));
00159 
00160   /*  Loop through token strings and array  */
00161   for(n=0; n<size; n++)
00162   {
00163     /*  Get the base type, if any */
00164     int type=DetermineType(tokens[n],table);
00165     /*  Set string in array to match  */
00166     tarray[n].token=(char *)tokens[n];
00167     tarray[n].type=type;
00168     if(type==-1)
00169     { /*  If type is unknown, subtype is too  */
00170       tarray[n].subtype=-1;
00171     }
00172     else
00173     {
00174       /*  Look up and set subtype */
00175       tarray[n].subtype=DetermineSubType(type,tokens[n],table);
00176     }
00177   }
00178 
00179   /*  Terminate it, to mark end */
00180   tarray[size].type=-1;
00181   tarray[size].subtype=-1;
00182   tarray[size].token=NULL;
00183 
00184   return(tarray);
00185 }
00186 
00190 int DetermineSubType(int type,const char *str, const char **args[])
00191 {
00192   int n=-1;
00193   if((args==NULL)||(type<0))  return(-1);
00194 
00195   /*  Ensure that 'type' is actually in the list  */
00196   for(n=0; (n<type)&&(args[n]!=NULL); n++);
00197 
00198   /*  Went past the end of the list */
00199   if(args[n]==NULL)  return(-1);
00200 
00201   return(FindInList(str,args[n]));
00202 }
00203 
00207 int FindInList(const char *str, const char *list[])
00208 {
00209   int n;
00210   for(n=0; list[n]!=NULL; n++)
00211     if(CompareType(str,list[n])>=0) return(n);
00212 
00213   return(-1);
00214 }
00215 
00219 int DetermineType(const char *str, const char **table[])
00220 {
00221   int i;
00222 
00223   for(i=0; table[i]!=NULL; i++)
00224   {
00225     if(table[i]!=NULL)
00226     if(FindInList(str,table[i])>=0)  return(i);
00227   }
00228   return(-1);
00229 }
00230 
00234 int CompareType(const char *str, const char *typestr)
00235 {
00236   int error=0,strpos=0,typepos=0;
00237   if((str==NULL)||(typestr==NULL))  return -1;
00238 
00239   /* Loop until entire string is parsed */
00240   while(!error&&(str[strpos]!='\0')&&(typestr[typepos]!='\0'))
00241   {
00242     /* Case sensitive string matching. */
00243     while(typestr[typepos]==str[strpos])
00244     {
00245       if((typestr[typepos]=='\0')||(str[strpos]=='\0')||(typestr[typepos]=='%'))
00246         break;
00247 
00248         typepos++;
00249         strpos++;
00250     }
00251 
00252     /* Three cases:   1) Both strings ended, which is OK.
00253                       2) One did, the other didn't.  Bad.
00254                       3) A variable argument was encountered in typestr.  */
00255 
00256     /* Strings match */
00257     if((typestr[typepos]=='\0')&&(str[strpos]=='\0'))
00258     {     return(0);    }
00259     else if((typestr[typepos]=='\0')||(str[strpos]=='\0'))
00260     {
00261       /* Strings didn't match. */
00262       return(-1);
00263     }
00264     else if(typestr[typepos]=='%')
00265       switch(toupper(typestr[typepos+1]))
00266       {
00267       case 'S':
00268         /* Anything goes, so just return true */
00269         return(0);
00270         break;
00271 
00272       case 'U':
00273         while(isdigit(str[strpos]))  strpos++;
00274         /* Advance past "%u" */
00275         typepos+=2;
00276         break;
00277 
00278       default:
00279         /* End of string or invalid type */
00280         return(-1);
00281       }
00282     else
00283     {
00284       return(-1);
00285     }
00286   }
00287 
00288   /* Type matches */
00289 
00290   if((str[strpos]=='\0')&&(typestr[typepos]=='\0'))
00291     return 0;
00292   else /* types don't match */
00293     return(-1);
00294 }
00295 
00296 
00297 void *AllocateArray(void *in, int size, int num);
00298 
00299 
00305 char **Explode(const char *strIn)
00306 {
00307   char **strList=NULL;
00308   int pos=0,numStr=0;
00309 
00310   /*  Ignore whitespace */
00311   while(isspace(strIn[pos]))    pos++;
00312 
00313   while(strIn[pos]!='\0')
00314   {
00315     /* Ignore whitespace */
00316     while(isspace(strIn[pos])) pos++;
00317 
00318     /* If we haven't reached the end of the string, must be another
00319        word.                                                          */
00320     if(strIn[pos]!='\0')
00321     {
00322       char buf[100];
00323       int bufPos=0;
00324 
00325       /* If we find a comment, stop parsing the line */
00326       if((strIn[pos]=='/')&&(strIn[pos+1]=='/'))
00327       {
00328         pos+=2;
00329 #ifdef PRINT_COMMENTS
00330         /*  Prints comments for debugging */
00331         printf("//");
00332         while((strIn[pos]!='\0')&&(strIn[pos]!='\n')&&(strIn[pos]!='\r'))
00333         {
00334           /* Print the string, except for CR/LF stuff at the end  */
00335           printf("%c",strIn[pos++]);
00336         }
00337         printf("\n"); /* Print one linefeed */
00338 #endif
00339         /* Fast-forward to end of string  */
00340         while(strIn[pos]!='\0') pos++;
00341 
00342         continue;
00343       }
00344       strList=(char **)AllocateArray(strList,sizeof(char *),numStr+1);
00345       numStr++;
00346       while(!isspace(strIn[pos])&&(strIn[pos]!='\0')&&(bufPos<(100-1)))
00347       {
00348         /* Add letters to the end of our string */
00349         buf[bufPos++]=strIn[pos++];
00350       }
00351 
00352       buf[bufPos++]='\0'; /* NULL terminator */
00353       /* Allocate memory for string */
00354       strList[numStr-1]=(char *)malloc(bufPos);
00355       /* Copy string into new memory */
00356       strcpy(strList[numStr-1],buf);
00357     }
00358   }
00359 
00360   if(strList==NULL)
00361   {
00362     /* Don't bother returning any mem if the list is empty */
00363     return(NULL);
00364   }
00365   else
00366   {
00367     /* Tack a NULL onto the end of the list so we can tell where it ends
00368        */
00369     strList=(char **)AllocateArray(strList,sizeof(char *),numStr+1);
00370     strList[numStr]=NULL;
00371     return(strList);
00372 
00373   }
00374 }
00375 
00380 void *AllocateArray(void *in, int size, int num)
00381 {
00382   if(in==NULL)  return(malloc(size*num));
00383   else          return(realloc(in,size*num));
00384 
00385 }
00386 
00391 void FreeStrList(char **strList)
00392 {
00393   int n;
00394   if(strList==NULL) return;
00395 
00396   for(n=0; strList[n]!=NULL; n++)
00397   {
00398     free(strList[n]);
00399   }
00400 
00401   free(strList);
00402 }
00403 
00404 

Generated on Sat Oct 11 13:19:26 2003 for Spritelib by doxygen 1.3.4