Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhpp.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
1.7.6.1
|