ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hpp.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:             See COPYING in the top level directory
00003  * PROJECT:               Header preprocessor
00004  * PURPOSE:               Generates header files from other header files
00005  * PROGRAMMER;            Timo Kreuzer
00006  *
00007  */
00008 
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <stdarg.h>
00012 #include <string.h>
00013 #include <ctype.h>
00014 
00015 //#define DBG 1
00016 
00017 #if DBG
00018 #define trace printf
00019 #else
00020 #define trace if (0) printf
00021 #endif
00022 
00023 typedef struct _DEFINE
00024 {
00025     struct _DEFINE *pNext;
00026     int len;
00027     int val;
00028     char szName[1];
00029 } DEFINE, *PDEFINE;
00030 
00031 DEFINE *gpDefines = 0;
00032 int iLine;
00033 const char *gpszCurFile;
00034 
00035 char*
00036 convert_path(const char* origpath)
00037 {
00038     char* newpath;
00039     int i;
00040 
00041     newpath = strdup(origpath);
00042 
00043     i = 0;
00044     while (newpath[i] != 0)
00045     {
00046 #ifdef UNIX_PATHS
00047         if (newpath[i] == '\\')
00048         {
00049             newpath[i] = '/';
00050         }
00051 #else
00052 #ifdef DOS_PATHS
00053         if (newpath[i] == '/')
00054         {
00055             newpath[i] = '\\';
00056         }
00057 #endif
00058 #endif
00059         i++;
00060     }
00061     return(newpath);
00062 }
00063 
00064 char*
00065 GetFolder(const char* pszFullPath)
00066 {
00067     return ".";
00068 }
00069 
00070 void*
00071 LoadFile(const char* pszFileName, size_t* pFileSize)
00072 {
00073     FILE* file;
00074     void* pFileData = NULL;
00075     int iFileSize;
00076 
00077     trace("Loading file...");
00078 
00079     file = fopen(pszFileName, "rb");
00080     if (!file)
00081     {
00082         trace("Could not open file\n");
00083         return NULL;
00084     }
00085 
00086     fseek(file, 0L, SEEK_END);
00087     iFileSize = ftell(file);
00088     fseek(file, 0L, SEEK_SET);
00089     *pFileSize = iFileSize;
00090     trace("ok. Size is %d\n", iFileSize);
00091 
00092     pFileData = malloc(iFileSize + 1);
00093 
00094     if (pFileData != NULL)
00095     {
00096         if (iFileSize != fread(pFileData, 1, iFileSize, file))
00097         {
00098             free(pFileData);
00099             pFileData = NULL;
00100         }
00101     }
00102     else
00103     {
00104         trace("Could not allocate memory for file\n");
00105     }
00106 
00107     fclose(file);
00108 
00109     return pFileData;
00110 }
00111 
00112 
00113 int
00114 error(char *format, ...)
00115 {
00116     va_list valist;
00117     int res;
00118     va_start(valist, format);
00119     res = vfprintf(stderr, format, valist);
00120     va_end(valist);
00121     return res;
00122 }
00123 
00124 char*
00125 GetNextChar(const char *psz)
00126 {
00127     while (*psz == ' ' || *psz == '\t') psz++;
00128     return (char*)psz;
00129 }
00130 
00131 char*
00132 GetNextLine(char *pszLine)
00133 {
00134     /* Walk to the end of the line */
00135     while (*pszLine != 13 && *pszLine != 10 && *pszLine != 0) pszLine++;
00136 
00137     /* Skip one CR/LF */
00138     if (pszLine[0] == 13 && pszLine[1] == 10)
00139         pszLine += 2;
00140     else if (pszLine[0] == 13 || pszLine[0] == 10)
00141         pszLine++;
00142 
00143     if (*pszLine == 0)
00144     {
00145         return 0;
00146     }
00147 
00148     return pszLine;
00149 }
00150 
00151 int
00152 strxlen(const char *psz)
00153 {
00154     int len = 0;
00155     while (isalnum(*psz) || *psz == '_')
00156     {
00157         psz++;
00158         len++;
00159     }
00160     return len;
00161 }
00162 
00163 
00164 void
00165 WriteLine(char *pszLine, FILE *fileOut)
00166 {
00167     char * pszEnd;
00168 
00169     pszEnd = strchr(pszLine, '\n');
00170     if (pszEnd)
00171     {
00172         int len = pszEnd - pszLine + 1;
00173         fwrite(pszLine, 1, len, fileOut);
00174     }
00175 }
00176 
00177 int
00178 EvaluateConstant(const char *p, char **pNext)
00179 {
00180     PDEFINE pDefine;
00181     int len;
00182 
00183     len = strxlen(p);
00184     if (pNext)
00185         *pNext = (char*)p + len;
00186 
00187     /* search for the define in the global list */
00188     pDefine = gpDefines;
00189     while (pDefine != 0)
00190     {
00191         trace("found a define: %s\n", pDefine->szName);
00192         if (pDefine->len == len)
00193         {
00194             if (strncmp(p, pDefine->szName, len) == 0)
00195             {
00196                 return pDefine->val;
00197             }
00198         }
00199         pDefine = pDefine->pNext;
00200     }
00201     return 0;
00202 }
00203 
00204 int
00205 EvaluateExpression(char *pExpression, char **pNext)
00206 {
00207     char *p, *pstart;
00208     int inv, thisval, val = 0;
00209 
00210     trace("evaluating expression\n");
00211 
00212     pstart = GetNextChar(pExpression);
00213     if (*pstart != '(')
00214     {
00215         error("Parse error: expected '(' \n");
00216         return -1;
00217     }
00218 
00219     while (1)
00220     {
00221         /* Get the start of the real expression */
00222         p = pstart;
00223         if ((p[0] == '&' && p[1] == '&') ||
00224             (p[0] == '|' && p[1] == '|'))
00225         {
00226             p++;
00227         }
00228         p = GetNextChar(p + 1);
00229 
00230         /* Check for inversion modifier */
00231         if (*p == '!')
00232         {
00233             inv = 1;
00234             p = GetNextChar(p + 1);
00235         }
00236         else
00237             inv = 0;
00238 
00239         /* Beginning of a new subexpression? */
00240         if (*p == '(')
00241         {
00242             /* Evaluate subexpression */
00243             thisval = EvaluateExpression(p, &p);
00244         }
00245         else if (isdigit(*p))
00246         {
00247             thisval = strtod(p, &p);
00248             trace("found a num: %d\n", thisval);
00249         }
00250         else if (isalpha(*p) || *p == '_')
00251         {
00252             thisval = EvaluateConstant(p, &p);
00253         }
00254         else
00255         {
00256             error("..Parse error, expected '(' or constant in line %d\n",
00257                   iLine);
00258             return -1;
00259         }
00260 
00261         if (inv)
00262             thisval = !thisval;
00263 
00264         /* Check how to combine the current value */
00265         if (pstart[0] == '(')
00266         {
00267             val = thisval;
00268         }
00269         else if (pstart[0] == '&' && pstart[1] == '&')
00270         {
00271             val = val && thisval;
00272         }
00273         else if (pstart[0] == '&' && pstart[1] != '&')
00274         {
00275             val = val & thisval;
00276         }
00277         else if (pstart[0] == '|' && pstart[1] == '|')
00278         {
00279             trace("found || val = %d, thisval = %d\n", val, thisval);
00280             val = val || thisval;
00281         }
00282         else if (pstart[0] == '|' && pstart[1] != '|')
00283         {
00284             val = val | thisval;
00285         }
00286         else if (pstart[0] == '+')
00287         {
00288             val = val + thisval;
00289         }
00290         else
00291         {
00292             error("+Parse error: expected '(' or operator in Line %d, got %c\n", 
00293                   iLine, pstart[0]);
00294             return -1;
00295         }
00296 
00297         p = GetNextChar(p);
00298 
00299         /* End of current subexpression? */
00300         if (*p == ')')
00301         {
00302             if (pNext)
00303             {
00304                 *pNext = p + 1;
00305             }
00306             return val;
00307         }
00308 
00309         /* Continue with a new start position */
00310         pstart = p;
00311     }
00312 
00313     return val;
00314 }
00315 
00316 int
00317 ParseInputFile(const char *pszInFile, FILE *fileOut)
00318 {
00319     char* pInputData, *pCurrentLine, *p1, *p2;
00320     size_t cbInFileLenth, len;
00321     int iIfLevel, iCopyLevel;
00322 
00323     trace("parsing input file: %s\n", pszInFile);
00324 
00325     /* Set the global file name */
00326     gpszCurFile = pszInFile;
00327 
00328     /* Load the input file into memory */
00329     pInputData = LoadFile(pszInFile, &cbInFileLenth);
00330     if (!pInputData)
00331     {
00332         error("Could not load input file %s\n", pszInFile);
00333         return -1;
00334     }
00335 
00336     /* Zero terminate the file */
00337     pInputData[cbInFileLenth] = 0;
00338 
00339     pCurrentLine = pInputData;
00340     iLine = 1;
00341     iCopyLevel = iIfLevel = 0;
00342 
00343     /* The main processing loop */
00344     do
00345     {
00346         trace("line %d: ", iLine);
00347 
00348         /* If this is a normal line ... */
00349         if (pCurrentLine[0] != '$')
00350         {
00351             /* Check if we are to copy this line */
00352             if (iCopyLevel == iIfLevel)
00353             {
00354                 trace("copying\n");
00355                 WriteLine(pCurrentLine, fileOut);
00356             }
00357             else
00358                 trace("skipping\n");
00359 
00360             /* Continue with next line */
00361             continue;
00362         }
00363 
00364         /* Check for $endif */
00365         if (strncmp(pCurrentLine, "$endif", 6) == 0)
00366         {
00367             trace("found $endif\n");
00368             if (iIfLevel <= 0)
00369             {
00370                 error("Parse error: $endif without $if in %s:%d\n", pszInFile, iLine);
00371                 return -1;
00372             }
00373             if (iCopyLevel == iIfLevel)
00374             {
00375                 iCopyLevel--;
00376             }
00377             iIfLevel--;
00378 
00379             /* Continue with next line */
00380             continue;
00381         }
00382 
00383         /* The rest is only parsed when we are in a true block */
00384         if (iCopyLevel < iIfLevel)
00385         {
00386             trace("skipping\n");
00387 
00388             /* Continue with next line */
00389             continue;
00390         }
00391 
00392         /* Check for $define */
00393         if (strncmp(pCurrentLine, "$define", 7) == 0)
00394         {
00395             PDEFINE pDefine;
00396 
00397             trace("found $define\n");
00398             p1 = GetNextChar(pCurrentLine + 7);
00399             if (*p1 != '(')
00400             {
00401                 error("Parse error: expected '(' at %s:%d\n", 
00402                       pszInFile, iLine);
00403                 return -1;
00404             }
00405             p1 = GetNextChar(p1 + 1);
00406             len = strxlen(p1);
00407             p2 = p1 + len;
00408             if (*p2 != ')')
00409             {
00410                 error("Parse error: expected ')' at %s:%d\n",
00411                       pszInFile, iLine);
00412                 return -1;
00413             }
00414 
00415             /* Insert the new define into the global list */
00416             pDefine = malloc(sizeof(DEFINE) + len);
00417             strncpy(pDefine->szName, p1, len);
00418             pDefine->szName[len] = 0;
00419             pDefine->len = len;
00420             pDefine->val = 1;
00421             pDefine->pNext = gpDefines;
00422             gpDefines = pDefine;
00423         }
00424 
00425         /* Check for $if */
00426         else if (strncmp(pCurrentLine, "$if", 3) == 0)
00427         {
00428             int val;
00429 
00430             trace("found $if\n");
00431             /* Increase the if-level */
00432             iIfLevel++;
00433 
00434             /* Get beginning of the expression */
00435             p1 = GetNextChar(pCurrentLine + 3);
00436 
00437             /* evaluate the expression */
00438             val = EvaluateExpression(p1, 0);
00439 
00440             if (val)
00441             {
00442                 iCopyLevel = iIfLevel;
00443             }
00444             else if (val == -1)
00445             {
00446                 /* Parse error */
00447                 return -1;
00448             }
00449         }
00450 
00451         /* Check for $include */
00452         else if (strncmp(pCurrentLine, "$include", 8) == 0)
00453         {
00454             int ret;
00455 
00456             trace("found $include\n");
00457             p1 = GetNextChar(pCurrentLine + 8);
00458             if (*p1 != '(')
00459             {
00460                 error("Parse error: expected '(' at %s:%d, found '%c'\n", 
00461                       pszInFile, iLine, *p1);
00462                 return -1;
00463             }
00464             p1++;
00465             p2 = strchr(p1, ')');
00466             *p2 = 0;
00467 
00468             /* Parse the included file */
00469             ret = ParseInputFile(p1, fileOut);
00470 
00471             /* Restore the global file name */
00472             gpszCurFile = pszInFile;
00473             
00474             /* Restore the zeroed character */
00475             *p2 = ')';
00476 
00477             if (ret == -1)
00478             {
00479                 return -1;
00480             }
00481         }
00482 
00483         /* Check for $$ comment */
00484         else if (strncmp(pCurrentLine, "$$", 2) == 0)
00485         {
00486             trace("$$ ignored\n");
00487             /* continue with next line */
00488             continue;
00489         }
00490 
00491         else
00492         {
00493             trace("wot:%s\n", pCurrentLine);
00494         }
00495 
00496         /* Continue with next line */
00497     }
00498     while (pCurrentLine = GetNextLine(pCurrentLine),
00499            iLine++,
00500            pCurrentLine != 0);
00501 
00502     /* Free the file data */
00503     free(pInputData);
00504 
00505     trace("Done with file.\n\n");
00506 
00507     return 0;
00508 }
00509 
00510 
00511 int
00512 main(int argc, char* argv[])
00513 {
00514     char *pszInFile, *pszOutFile;
00515     FILE* fileOut;
00516     int ret;
00517 
00518     if (argc != 3)
00519     {
00520         error("Usage: hpp <inputfile> <outputfile>\n");
00521         exit(1);
00522     }
00523 
00524     pszInFile = convert_path(argv[1]);
00525     pszOutFile = convert_path(argv[2]);
00526 
00527     fileOut = fopen(pszOutFile, "wb");
00528     if (fileOut == NULL)
00529     {
00530         error("Cannot open output file %s", pszOutFile);
00531         exit(1);
00532     }
00533 
00534     ret = ParseInputFile(pszInFile, fileOut);
00535 
00536     fclose(fileOut);
00537     free(pszInFile);
00538     free(pszOutFile);
00539 
00540     return ret;
00541 }

Generated on Sun May 27 2012 04:37:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.