Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

l_struct.c File Reference

Go to the source code of this file.

Functions

fielddef_tFindField (fielddef_t *defs, char *name)
qboolean ReadChar (source_t *source, fielddef_t *fd, void *p)
qboolean ReadNumber (source_t *source, fielddef_t *fd, void *p)
int ReadString (source_t *source, fielddef_t *fd, void *p)
int ReadStructure (source_t *source, structdef_t *def, char *structure)
int WriteFloat (FILE *fp, float value)
int WriteIndent (FILE *fp, int indent)
int WriteStructure (FILE *fp, structdef_t *def, char *structure)
int WriteStructWithIndent (FILE *fp, structdef_t *def, char *structure, int indent)


Function Documentation

fielddef_t* FindField fielddef_t defs,
char *  name
 

Definition at line 60 of file l_struct.c.

References fielddef_t, i, name, fielddef_s::name, and strcmp().

Referenced by ReadStructure().

00061 {
00062     int i;
00063 
00064     for (i = 0; defs[i].name; i++)
00065     {
00066         if (!strcmp(defs[i].name, name)) return &defs[i];
00067     } //end for
00068     return NULL;
00069 } //end of the function FindField

Here is the call graph for this function:

qboolean ReadChar source_t source,
fielddef_t fd,
void *  p
 

Definition at line 191 of file l_struct.c.

References fielddef_t, p, PC_ExpectAnyToken(), PC_UnreadLastToken(), qboolean, ReadNumber(), source, source_t, token_s::string, StripSingleQuotes(), token, token_t, and token_s::type.

Referenced by ReadStructure().

00192 {
00193     token_t token;
00194 
00195     if (!PC_ExpectAnyToken(source, &token)) return 0;
00196 
00197     //take literals into account
00198     if (token.type == TT_LITERAL)
00199     {
00200         StripSingleQuotes(token.string);
00201         *(char *) p = token.string[0];
00202     } //end if
00203     else
00204     {
00205         PC_UnreadLastToken(source);
00206         if (!ReadNumber(source, fd, p)) return 0;
00207     } //end if
00208     return 1;
00209 } //end of the function ReadChar

Here is the call graph for this function:

qboolean ReadNumber source_t source,
fielddef_t fd,
void *  p
 

Definition at line 76 of file l_struct.c.

References fielddef_t, fielddef_s::floatmax, fielddef_s::floatmin, token_s::floatvalue, FT_CHAR, token_s::intvalue, Maximum, Minimum, p, PC_ExpectAnyToken(), qboolean, source, source_t, SourceError(), strcmp(), token_s::string, token_s::subtype, token, token_t, fielddef_s::type, and token_s::type.

Referenced by ReadChar(), and ReadStructure().

00077 {
00078     token_t token;
00079     int negative = qfalse;
00080     long int intval, intmin = 0, intmax = 0;
00081     double floatval;
00082 
00083     if (!PC_ExpectAnyToken(source, &token)) return 0;
00084 
00085     //check for minus sign
00086     if (token.type == TT_PUNCTUATION)
00087     {
00088         if (fd->type & FT_UNSIGNED)
00089         {
00090             SourceError(source, "expected unsigned value, found %s", token.string);
00091             return 0;
00092         } //end if
00093         //if not a minus sign
00094         if (strcmp(token.string, "-"))
00095         {
00096             SourceError(source, "unexpected punctuation %s", token.string);
00097             return 0;
00098         } //end if
00099         negative = qtrue;
00100         //read the number
00101         if (!PC_ExpectAnyToken(source, &token)) return 0;
00102     } //end if
00103     //check if it is a number
00104     if (token.type != TT_NUMBER)
00105     {
00106         SourceError(source, "expected number, found %s", token.string);
00107         return 0;
00108     } //end if
00109     //check for a float value
00110     if (token.subtype & TT_FLOAT)
00111     {
00112         if ((fd->type & FT_TYPE) != FT_FLOAT)
00113         {
00114             SourceError(source, "unexpected float");
00115             return 0;
00116         } //end if
00117         floatval = token.floatvalue;
00118         if (negative) floatval = -floatval;
00119         if (fd->type & FT_BOUNDED)
00120         {
00121             if (floatval < fd->floatmin || floatval > fd->floatmax)
00122             {
00123                 SourceError(source, "float out of range [%f, %f]", fd->floatmin, fd->floatmax);
00124                 return 0;
00125             } //end if
00126         } //end if
00127         *(float *) p = (float) floatval;
00128         return 1;
00129     } //end if
00130     //
00131     intval = token.intvalue;
00132     if (negative) intval = -intval;
00133     //check bounds
00134     if ((fd->type & FT_TYPE) == FT_CHAR)
00135     {
00136         if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 255;}
00137         else {intmin = -128; intmax = 127;}
00138     } //end if
00139     if ((fd->type & FT_TYPE) == FT_INT)
00140     {
00141         if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 65535;}
00142         else {intmin = -32768; intmax = 32767;}
00143     } //end else if
00144     if ((fd->type & FT_TYPE) == FT_CHAR || (fd->type & FT_TYPE) == FT_INT)
00145     {
00146         if (fd->type & FT_BOUNDED)
00147         {
00148             intmin = Maximum(intmin, fd->floatmin);
00149             intmax = Minimum(intmax, fd->floatmax);
00150         } //end if
00151         if (intval < intmin || intval > intmax)
00152         {
00153             SourceError(source, "value %d out of range [%d, %d]", intval, intmin, intmax);
00154             return 0;
00155         } //end if
00156     } //end if
00157     else if ((fd->type & FT_TYPE) == FT_FLOAT)
00158     {
00159         if (fd->type & FT_BOUNDED)
00160         {
00161             if (intval < fd->floatmin || intval > fd->floatmax)
00162             {
00163                 SourceError(source, "value %d out of range [%f, %f]", intval, fd->floatmin, fd->floatmax);
00164                 return 0;
00165             } //end if
00166         } //end if
00167     } //end else if
00168     //store the value
00169     if ((fd->type & FT_TYPE) == FT_CHAR)
00170     {
00171         if (fd->type & FT_UNSIGNED) *(unsigned char *) p = (unsigned char) intval;
00172         else *(char *) p = (char) intval;
00173     } //end if
00174     else if ((fd->type & FT_TYPE) == FT_INT)
00175     {
00176         if (fd->type & FT_UNSIGNED) *(unsigned int *) p = (unsigned int) intval;
00177         else *(int *) p = (int) intval;
00178     } //end else
00179     else if ((fd->type & FT_TYPE) == FT_FLOAT)
00180     {
00181         *(float *) p = (float) intval;
00182     } //end else
00183     return 1;
00184 } //end of the function ReadNumber

Here is the call graph for this function:

int ReadString source_t source,
fielddef_t fd,
void *  p
 

Definition at line 216 of file l_struct.c.

References fielddef_t, MAX_STRINGFIELD, p, PC_ExpectTokenType(), source, source_t, token_s::string, StripDoubleQuotes(), strncpy(), token, token_t, and TT_STRING.

Referenced by ReadStructure().

00217 {
00218     token_t token;
00219 
00220     if (!PC_ExpectTokenType(source, TT_STRING, 0, &token)) return 0;
00221     //remove the double quotes
00222     StripDoubleQuotes(token.string);
00223     //copy the string
00224     strncpy((char *) p, token.string, MAX_STRINGFIELD);
00225     //make sure the string is closed with a zero
00226     ((char *)p)[MAX_STRINGFIELD-1] = '\0';
00227     //
00228     return 1;
00229 } //end of the function ReadString

Here is the call graph for this function:

int ReadStructure source_t source,
structdef_t def,
char *  structure
 

Definition at line 236 of file l_struct.c.

References fielddef_t, structdef_s::fields, FindField(), FT_CHAR, FT_FLOAT, FT_INT, FT_STRING, FT_STRUCT, fielddef_s::maxarray, fielddef_s::offset, p, PC_CheckTokenString(), PC_ExpectAnyToken(), PC_ExpectTokenString(), ReadChar(), ReadNumber(), ReadString(), structdef_s::size, source, source_t, SourceError(), strcmp(), token_s::string, structdef_t, fielddef_s::substruct, token, token_t, and fielddef_s::type.

Referenced by LoadCfgFile(), LoadItemConfig(), and LoadWeaponConfig().

00237 {
00238     token_t token;
00239     fielddef_t *fd;
00240     void *p;
00241     int num;
00242 
00243     if (!PC_ExpectTokenString(source, "{")) return 0;
00244     while(1)
00245     {
00246         if (!PC_ExpectAnyToken(source, &token)) return qfalse;
00247         //if end of structure
00248         if (!strcmp(token.string, "}")) break;
00249         //find the field with the name
00250         fd = FindField(def->fields, token.string);
00251         if (!fd)
00252         {
00253             SourceError(source, "unknown structure field %s", token.string);
00254             return qfalse;
00255         } //end if
00256         if (fd->type & FT_ARRAY)
00257         {
00258             num = fd->maxarray;
00259             if (!PC_ExpectTokenString(source, "{")) return qfalse;
00260         } //end if
00261         else
00262         {
00263             num = 1;
00264         } //end else
00265         p = (void *)(structure + fd->offset);
00266         while (num-- > 0)
00267         {
00268             if (fd->type & FT_ARRAY)
00269             {
00270                 if (PC_CheckTokenString(source, "}")) break;
00271             } //end if
00272             switch(fd->type & FT_TYPE)
00273             {
00274                 case FT_CHAR:
00275                 {
00276                     if (!ReadChar(source, fd, p)) return qfalse;
00277                     p = (char *) p + sizeof(char);
00278                     break;
00279                 } //end case
00280                 case FT_INT:
00281                 {
00282                     if (!ReadNumber(source, fd, p)) return qfalse;
00283                     p = (char *) p + sizeof(int);
00284                     break;
00285                 } //end case
00286                 case FT_FLOAT:
00287                 {
00288                     if (!ReadNumber(source, fd, p)) return qfalse;
00289                     p = (char *) p + sizeof(float);
00290                     break;
00291                 } //end case
00292                 case FT_STRING:
00293                 {
00294                     if (!ReadString(source, fd, p)) return qfalse;
00295                     p = (char *) p + MAX_STRINGFIELD;
00296                     break;
00297                 } //end case
00298                 case FT_STRUCT:
00299                 {
00300                     if (!fd->substruct)
00301                     {
00302                         SourceError(source, "BUG: no sub structure defined");
00303                         return qfalse;
00304                     } //end if
00305                     ReadStructure(source, fd->substruct, (char *) p);
00306                     p = (char *) p + fd->substruct->size;
00307                     break;
00308                 } //end case
00309             } //end switch
00310             if (fd->type & FT_ARRAY)
00311             {
00312                 if (!PC_ExpectAnyToken(source, &token)) return qfalse;
00313                 if (!strcmp(token.string, "}")) break;
00314                 if (strcmp(token.string, ","))
00315                 {
00316                     SourceError(source, "expected a comma, found %s", token.string);
00317                     return qfalse;
00318                 } //end if
00319             } //end if
00320         } //end while
00321     } //end while
00322     return qtrue;
00323 } //end of the function ReadStructure

Here is the call graph for this function:

int WriteFloat FILE fp,
float  value
 

Definition at line 344 of file l_struct.c.

00345 {
00346     char buf[128];
00347     int l;
00348 
00349     sprintf(buf, "%f", value);
00350     l = strlen(buf);
00351     //strip any trailing zeros
00352     while(l-- > 1)
00353     {
00354         if (buf[l] != '0' && buf[l] != '.') break;
00355         if (buf[l] == '.')
00356         {
00357             buf[l] = 0;
00358             break;
00359         } //end if
00360         buf[l] = 0;
00361     } //end while
00362     //write the float to file
00363     if (fprintf(fp, "%s", buf) < 0) return 0;
00364     return 1;
00365 } //end of the function WriteFloat

int WriteIndent FILE fp,
int  indent
 

Definition at line 330 of file l_struct.c.

References fp, and fprintf().

Referenced by WriteStructWithIndent().

00331 {
00332     while(indent-- > 0)
00333     {
00334         if (fprintf(fp, "\t") < 0) return qfalse;
00335     } //end while
00336     return qtrue;
00337 } //end of the function WriteIndent

Here is the call graph for this function:

int WriteStructure FILE fp,
structdef_t def,
char *  structure
 

Definition at line 458 of file l_struct.c.

References fp, structdef_t, and WriteStructWithIndent().

00459 {
00460     return WriteStructWithIndent(fp, def, structure, 0);
00461 } //end of the function WriteStructure

Here is the call graph for this function:

int WriteStructWithIndent FILE fp,
structdef_t def,
char *  structure,
int  indent
 

Definition at line 372 of file l_struct.c.

References fielddef_t, structdef_s::fields, fp, fprintf(), FT_CHAR, FT_FLOAT, FT_INT, FT_STRING, FT_STRUCT, i, fielddef_s::maxarray, fielddef_s::name, fielddef_s::offset, p, structdef_s::size, structdef_t, fielddef_s::substruct, fielddef_s::type, WriteFloat(), and WriteIndent().

Referenced by WriteStructure().

00373 {
00374     int i, num;
00375     void *p;
00376     fielddef_t *fd;
00377 
00378     if (!WriteIndent(fp, indent)) return qfalse;
00379     if (fprintf(fp, "{\r\n") < 0) return qfalse;
00380 
00381     indent++;
00382     for (i = 0; def->fields[i].name; i++)
00383     {
00384         fd = &def->fields[i];
00385         if (!WriteIndent(fp, indent)) return qfalse;
00386         if (fprintf(fp, "%s\t", fd->name) < 0) return qfalse;
00387         p = (void *)(structure + fd->offset);
00388         if (fd->type & FT_ARRAY)
00389         {
00390             num = fd->maxarray;
00391             if (fprintf(fp, "{") < 0) return qfalse;
00392         } //end if
00393         else
00394         {
00395             num = 1;
00396         } //end else
00397         while(num-- > 0)
00398         {
00399             switch(fd->type & FT_TYPE)
00400             {
00401                 case FT_CHAR:
00402                 {
00403                     if (fprintf(fp, "%d", *(char *) p) < 0) return qfalse;
00404                     p = (char *) p + sizeof(char);
00405                     break;
00406                 } //end case
00407                 case FT_INT:
00408                 {
00409                     if (fprintf(fp, "%d", *(int *) p) < 0) return qfalse;
00410                     p = (char *) p + sizeof(int);
00411                     break;
00412                 } //end case
00413                 case FT_FLOAT:
00414                 {
00415                     if (!WriteFloat(fp, *(float *)p)) return qfalse;
00416                     p = (char *) p + sizeof(float);
00417                     break;
00418                 } //end case
00419                 case FT_STRING:
00420                 {
00421                     if (fprintf(fp, "\"%s\"", (char *) p) < 0) return qfalse;
00422                     p = (char *) p + MAX_STRINGFIELD;
00423                     break;
00424                 } //end case
00425                 case FT_STRUCT:
00426                 {
00427                     if (!WriteStructWithIndent(fp, fd->substruct, structure, indent)) return qfalse;
00428                     p = (char *) p + fd->substruct->size;
00429                     break;
00430                 } //end case
00431             } //end switch
00432             if (fd->type & FT_ARRAY)
00433             {
00434                 if (num > 0)
00435                 {
00436                     if (fprintf(fp, ",") < 0) return qfalse;
00437                 } //end if
00438                 else
00439                 {
00440                     if (fprintf(fp, "}") < 0) return qfalse;
00441                 } //end else
00442             } //end if
00443         } //end while
00444         if (fprintf(fp, "\r\n") < 0) return qfalse;
00445     } //end for
00446     indent--;
00447 
00448     if (!WriteIndent(fp, indent)) return qfalse;
00449     if (fprintf(fp, "}\r\n") < 0) return qfalse;
00450     return qtrue;
00451 } //end of the function WriteStructWithIndent

Here is the call graph for this function:


Generated on Thu Aug 25 12:44:36 2005 for Quake III Arena by  doxygen 1.3.9.1