ReactOS 0.4.15-dev-7906-g1b85a5f
hpp.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Header preprocessor
4 * PURPOSE: Generates header files from other header files
5 * PROGRAMMER; Timo Kreuzer
6 *
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <stdarg.h>
12#include <string.h>
13#include <ctype.h>
14
15//#define DBG 1
16
17#if DBG
18#define trace printf
19#else
20#define trace if (0) printf
21#endif
22
23typedef struct _DEFINE
24{
25 struct _DEFINE *pNext;
26 int val;
27 char *pszName;
28 unsigned int cchName;
29 char *pszValue;
30 unsigned int cchValue;
31 char achBuffer[1];
33
36const char *gpszCurFile;
37
38char*
39convert_path(const char* origpath)
40{
41 char* newpath;
42 int i;
43
44 newpath = strdup(origpath);
45
46 i = 0;
47 while (newpath[i] != 0)
48 {
49#ifdef UNIX_PATHS
50 if (newpath[i] == '\\')
51 {
52 newpath[i] = '/';
53 }
54#else
55#ifdef DOS_PATHS
56 if (newpath[i] == '/')
57 {
58 newpath[i] = '\\';
59 }
60#endif
61#endif
62 i++;
63 }
64 return newpath;
65}
66
67char*
68GetFolder(const char* pszFullPath)
69{
70 return ".";
71}
72
73void*
74LoadFile(const char* pszFileName, size_t* pFileSize)
75{
76 FILE* file;
77 void* pFileData = NULL;
78 int iFileSize;
79
80 trace("Loading file...");
81
82 file = fopen(pszFileName, "rb");
83 if (!file)
84 {
85 trace("Could not open file\n");
86 return NULL;
87 }
88
89 fseek(file, 0L, SEEK_END);
90 iFileSize = ftell(file);
91 fseek(file, 0L, SEEK_SET);
92 *pFileSize = iFileSize;
93 trace("ok. Size is %d\n", iFileSize);
94
95 pFileData = malloc(iFileSize + 1);
96
97 if (pFileData != NULL)
98 {
99 if (iFileSize != fread(pFileData, 1, iFileSize, file))
100 {
101 free(pFileData);
102 pFileData = NULL;
103 }
104 }
105 else
106 {
107 trace("Could not allocate memory for file\n");
108 }
109
110 fclose(file);
111
112 return pFileData;
113}
114
115
116int
117error(char *format, ...)
118{
120 int res;
123 va_end(valist);
124 return res;
125}
126
127char*
128GetNextChar(const char *psz)
129{
130 while (*psz == ' ' || *psz == '\t') psz++;
131 return (char*)psz;
132}
133
134char*
135GetNextLine(char *pszLine)
136{
137 /* Walk to the end of the line */
138 while (*pszLine != 13 && *pszLine != 10 && *pszLine != 0) pszLine++;
139
140 /* Skip one CR/LF */
141 if (pszLine[0] == 13 && pszLine[1] == 10)
142 pszLine += 2;
143 else if (pszLine[0] == 13 || pszLine[0] == 10)
144 pszLine++;
145
146 if (*pszLine == 0)
147 {
148 return 0;
149 }
150
151 return pszLine;
152}
153
154int
155strxlen(const char *psz)
156{
157 int len = 0;
158 while (isalnum(*psz) || *psz == '_')
159 {
160 psz++;
161 len++;
162 }
163 return len;
164}
165
167FindDefine(const char *p, char **pNext)
168{
169 PDEFINE pDefine;
170 int cchName;
171
172 cchName = strxlen(p);
173 if (pNext)
174 *pNext = (char*)p + cchName;
175
176 /* search for the define in the global list */
177 pDefine = gpDefines;
178 while (pDefine != 0)
179 {
180 trace("found a define: %s\n", pDefine->pszName);
181 if (pDefine->cchName == cchName)
182 {
183 if (strncmp(p, pDefine->pszName, cchName) == 0)
184 {
185 return pDefine;
186 }
187 }
188 pDefine = pDefine->pNext;
189 }
190 return 0;
191}
192
193void
194WriteLine(char *pchLine, FILE *fileOut)
195{
196 char *pch, *pchLineEnd, *pchVariable;
197 int len;
198 PDEFINE pDefine;
199
200 pchLineEnd = strchr(pchLine, '\n');
201 if (pchLineEnd == 0)
202 return;
203
204 len = pchLineEnd - pchLine + 1;
205
206 pch = pchLine;
207 while (len > 0)
208 {
209 /* Check if there is a $ variable in the line */
210 pchVariable = strchr(pch, '$');
211 if (pchVariable && (pchVariable < pchLineEnd))
212 {
213 /* Write all characters up to the $ */
214 fwrite(pch, 1, pchVariable - pch, fileOut);
215
216 /* Try to find the define */
217 pDefine = FindDefine(pchVariable + 1, &pch);
218 if (pDefine != 0)
219 {
220 /* We have a define, write the value */
221 fwrite(pDefine->pszValue, 1, pDefine->cchValue, fileOut);
222 }
223 else
224 {
225 len = strxlen(pchVariable + 1) + 1;
226 error("Could not find variable '%.*s'\n", len, pchVariable);
227 fwrite(pchVariable, 1, pch - pchVariable, fileOut);
228 }
229
230 len = pchLineEnd - pch + 1;
231 }
232 else
233 {
234 fwrite(pch, 1, len, fileOut);
235 break;
236 }
237 }
238}
239
240int
241EvaluateConstant(const char *p, char **pNext)
242{
243 PDEFINE pDefine;
244
245 pDefine = FindDefine(p, pNext);
246 if (!pDefine)
247 return 0;
248
249 return pDefine->val;
250}
251
252int
253EvaluateExpression(char *pExpression, char **pNext)
254{
255 char *p, *pstart;
256 int inv, thisval, val = 0;
257
258 trace("evaluating expression\n");
259
260 pstart = GetNextChar(pExpression);
261 if (*pstart != '(')
262 {
263 error("Parse error: expected '(' \n");
264 return -1;
265 }
266
267 while (1)
268 {
269 /* Get the start of the real expression */
270 p = pstart;
271 if ((p[0] == '&' && p[1] == '&') ||
272 (p[0] == '|' && p[1] == '|'))
273 {
274 p++;
275 }
276 p = GetNextChar(p + 1);
277
278 /* Check for inversion modifier */
279 if (*p == '!')
280 {
281 inv = 1;
282 p = GetNextChar(p + 1);
283 }
284 else
285 inv = 0;
286
287 /* Beginning of a new subexpression? */
288 if (*p == '(')
289 {
290 /* Evaluate subexpression */
291 thisval = EvaluateExpression(p, &p);
292 }
293 else if (isdigit(*p))
294 {
295 thisval = strtod(p, &p);
296 trace("found a num: %d\n", thisval);
297 }
298 else if (isalpha(*p) || *p == '_')
299 {
300 thisval = EvaluateConstant(p, &p);
301 }
302 else
303 {
304 error("..Parse error, expected '(' or constant in line %d\n",
305 iLine);
306 return -1;
307 }
308
309 if (inv)
310 thisval = !thisval;
311
312 /* Check how to combine the current value */
313 if (pstart[0] == '(')
314 {
315 val = thisval;
316 }
317 else if (pstart[0] == '&' && pstart[1] == '&')
318 {
319 val = val && thisval;
320 }
321 else if (pstart[0] == '&' && pstart[1] != '&')
322 {
323 val = val & thisval;
324 }
325 else if (pstart[0] == '|' && pstart[1] == '|')
326 {
327 trace("found || val = %d, thisval = %d\n", val, thisval);
328 val = val || thisval;
329 }
330 else if (pstart[0] == '|' && pstart[1] != '|')
331 {
332 val = val | thisval;
333 }
334 else if (pstart[0] == '+')
335 {
336 val = val + thisval;
337 }
338 else
339 {
340 error("+Parse error: expected '(' or operator in Line %d, got %c\n",
341 iLine, pstart[0]);
342 return -1;
343 }
344
345 p = GetNextChar(p);
346
347 /* End of current subexpression? */
348 if (*p == ')')
349 {
350 if (pNext)
351 {
352 *pNext = p + 1;
353 }
354 return val;
355 }
356
357 /* Continue with a new start position */
358 pstart = p;
359 }
360
361 return val;
362}
363
364int
365ParseInputFile(const char *pszInFile, FILE *fileOut)
366{
367 char* pInputData, *pCurrentLine, *p1, *p2;
368 size_t cbInFileLenth;
369 int iIfLevel, iCopyLevel;
370
371 trace("parsing input file: %s\n", pszInFile);
372
373 /* Set the global file name */
374 gpszCurFile = pszInFile;
375
376 /* Load the input file into memory */
377 pInputData = LoadFile(pszInFile, &cbInFileLenth);
378 if (!pInputData)
379 {
380 error("Could not load input file %s\n", pszInFile);
381 return -1;
382 }
383
384 /* Zero terminate the file */
385 pInputData[cbInFileLenth] = 0;
386
387 pCurrentLine = pInputData;
388 iLine = 1;
389 iCopyLevel = iIfLevel = 0;
390
391 /* The main processing loop */
392 do
393 {
394 trace("line %d: ", iLine);
395
396 /* If this is a normal line ... */
397 if (pCurrentLine[0] != '$')
398 {
399 /* Check if we are to copy this line */
400 if (iCopyLevel == iIfLevel)
401 {
402 trace("copying\n");
403 WriteLine(pCurrentLine, fileOut);
404 }
405 else
406 trace("skipping\n");
407
408 /* Continue with next line */
409 continue;
410 }
411
412 /* Check for $endif */
413 if (strncmp(pCurrentLine, "$endif", 6) == 0)
414 {
415 trace("found $endif\n");
416 if (iIfLevel <= 0)
417 {
418 error("Parse error: $endif without $if in %s:%d\n", pszInFile, iLine);
419 return -1;
420 }
421 if (iCopyLevel == iIfLevel)
422 {
423 iCopyLevel--;
424 }
425 iIfLevel--;
426
427 /* Continue with next line */
428 continue;
429 }
430
431 /* The rest is only parsed when we are in a true block */
432 if (iCopyLevel < iIfLevel)
433 {
434 trace("skipping\n");
435
436 /* Continue with next line */
437 continue;
438 }
439
440 /* Check for $define */
441 if (strncmp(pCurrentLine, "$define", 7) == 0)
442 {
443 PDEFINE pDefine;
444 char *pchName, *pchValue;
445 size_t cchName, cchValue;
446
447 trace("found $define\n");
448 p1 = GetNextChar(pCurrentLine + 7);
449 if (*p1 != '(')
450 {
451 error("Parse error: expected '(' at %s:%d\n",
452 pszInFile, iLine);
453 return -1;
454 }
455
456 pchName = GetNextChar(p1 + 1);
457 cchName = strxlen(pchName);
458 p1 = GetNextChar(pchName + cchName);
459
460 /* Check for assignment */
461 if (*p1 == '=')
462 {
463 trace("found $define with assignment\n");
464 pchValue = GetNextChar(p1 + 1);
465 cchValue = strxlen(pchValue);
466 p1 = GetNextChar(pchValue + cchValue);
467 }
468 else
469 {
470 pchValue = 0;
471 cchValue = 0;
472 }
473
474 /* Allocate a DEFINE structure */
475 pDefine = malloc(sizeof(DEFINE) + cchName + cchValue + 2);
476 if (pDefine == 0)
477 {
478 error("Failed to allocate %u bytes\n",
479 sizeof(DEFINE) + cchName + cchValue + 2);
480 return -1;
481 }
482
483 pDefine->pszName = pDefine->achBuffer;
484 strncpy(pDefine->pszName, pchName, cchName);
485 pDefine->pszName[cchName] = 0;
486 pDefine->cchName = cchName;
487 pDefine->val = 1;
488
489 if (pchValue != 0)
490 {
491 pDefine->pszValue = &pDefine->achBuffer[cchName + 1];
492 strncpy(pDefine->pszValue, pchValue, cchValue);
493 pDefine->pszValue[cchValue] = 0;
494 pDefine->cchValue = cchValue;
495 }
496 else
497 {
498 pDefine->pszValue = 0;
499 pDefine->cchValue = 0;
500 }
501
502 /* Insert the new define into the global list */
503 pDefine->pNext = gpDefines;
504 gpDefines = pDefine;
505
506 /* Check for closing ')' */
507 if (*p1 != ')')
508 {
509 error("Parse error: expected ')' at %s:%d\n",
510 pszInFile, iLine);
511 return -1;
512 }
513 }
514
515 /* Check for $if */
516 else if (strncmp(pCurrentLine, "$if", 3) == 0)
517 {
518 int val;
519
520 trace("found $if\n");
521 /* Increase the if-level */
522 iIfLevel++;
523
524 /* Get beginning of the expression */
525 p1 = GetNextChar(pCurrentLine + 3);
526
527 /* evaluate the expression */
528 val = EvaluateExpression(p1, 0);
529
530 if (val)
531 {
532 iCopyLevel = iIfLevel;
533 }
534 else if (val == -1)
535 {
536 /* Parse error */
537 return -1;
538 }
539 }
540
541 /* Check for $include */
542 else if (strncmp(pCurrentLine, "$include", 8) == 0)
543 {
544 int ret;
545
546 trace("found $include\n");
547 p1 = GetNextChar(pCurrentLine + 8);
548 if (*p1 != '(')
549 {
550 error("Parse error: expected '(' at %s:%d, found '%c'\n",
551 pszInFile, iLine, *p1);
552 return -1;
553 }
554 p1++;
555 p2 = strchr(p1, ')');
556 *p2 = 0;
557
558 /* Parse the included file */
559 ret = ParseInputFile(p1, fileOut);
560
561 /* Restore the global file name */
562 gpszCurFile = pszInFile;
563
564 /* Restore the zeroed character */
565 *p2 = ')';
566
567 if (ret == -1)
568 {
569 return -1;
570 }
571 }
572
573 /* Check for $$ comment */
574 else if (strncmp(pCurrentLine, "$$", 2) == 0)
575 {
576 trace("$$ ignored\n");
577 /* continue with next line */
578 continue;
579 }
580
581 else
582 {
583 trace("wot:%s\n", pCurrentLine);
584 }
585
586 /* Continue with next line */
587 }
588 while (pCurrentLine = GetNextLine(pCurrentLine),
589 iLine++,
590 pCurrentLine != 0);
591
592 /* Free the file data */
593 free(pInputData);
594
595 trace("Done with file.\n\n");
596
597 return 0;
598}
599
600
601int
602main(int argc, char* argv[])
603{
604 char *pszInFile, *pszOutFile;
605 FILE* fileOut;
606 int ret;
607
608 if (argc != 3)
609 {
610 error("Usage: hpp <inputfile> <outputfile>\n");
611 exit(1);
612 }
613
614 pszInFile = convert_path(argv[1]);
615 pszOutFile = convert_path(argv[2]);
616
617 fileOut = fopen(pszOutFile, "wb");
618 if (fileOut == NULL)
619 {
620 error("Cannot open output file %s", pszOutFile);
621 exit(1);
622 }
623
624 ret = ParseInputFile(pszInFile, fileOut);
625
626 fclose(fileOut);
627 free(pszInFile);
628 free(pszOutFile);
629
630 return ret;
631}
static int argc
Definition: ServiceArgs.c:12
#define isalpha(c)
Definition: acclib.h:74
#define isdigit(c)
Definition: acclib.h:68
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define SEEK_END
Definition: cabinet.c:29
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
int main()
Definition: test.c:6
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLuint res
Definition: glext.h:9613
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
char * convert_path(const char *origpath)
Definition: hpp.c:39
char * GetNextLine(char *pszLine)
Definition: hpp.c:135
void WriteLine(char *pchLine, FILE *fileOut)
Definition: hpp.c:194
int ParseInputFile(const char *pszInFile, FILE *fileOut)
Definition: hpp.c:365
#define trace
Definition: hpp.c:20
int EvaluateExpression(char *pExpression, char **pNext)
Definition: hpp.c:253
struct _DEFINE DEFINE
void * LoadFile(const char *pszFileName, size_t *pFileSize)
Definition: hpp.c:74
int iLine
Definition: hpp.c:35
struct _DEFINE * PDEFINE
int strxlen(const char *psz)
Definition: hpp.c:155
DEFINE * gpDefines
Definition: hpp.c:34
char * GetNextChar(const char *psz)
Definition: hpp.c:128
PDEFINE FindDefine(const char *p, char **pNext)
Definition: hpp.c:167
const char * gpszCurFile
Definition: hpp.c:36
int EvaluateConstant(const char *p, char **pNext)
Definition: hpp.c:241
char * GetFolder(const char *pszFullPath)
Definition: hpp.c:68
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ double __cdecl strtod(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr)
#define SEEK_SET
Definition: jmemansi.c:26
#define error(str)
Definition: mkdosfs.c:1605
#define pch(ap)
Definition: match.c:418
static __ms_va_list valist
Definition: printf.c:66
#define argv
Definition: mplay32.c:18
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
#define exit(n)
Definition: config.h:202
Definition: hpp.c:24
char achBuffer[1]
Definition: hpp.c:31
struct _DEFINE * pNext
Definition: hpp.c:25
char * pszValue
Definition: hpp.c:29
unsigned int cchName
Definition: hpp.c:28
int val
Definition: hpp.c:26
unsigned int cchValue
Definition: hpp.c:30
char * pszName
Definition: hpp.c:27
Definition: fci.c:127
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
int ret
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2767