mirror of
https://github.com/reactos/reactos.git
synced 2025-06-11 04:47:22 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
631
sdk/tools/hpp/hpp.c
Normal file
631
sdk/tools/hpp/hpp.c
Normal file
|
@ -0,0 +1,631 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Header preprocessor
|
||||
* PURPOSE: Generates header files from other header files
|
||||
* PROGRAMMER; Timo Kreuzer
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
//#define DBG 1
|
||||
|
||||
#if DBG
|
||||
#define trace printf
|
||||
#else
|
||||
#define trace if (0) printf
|
||||
#endif
|
||||
|
||||
typedef struct _DEFINE
|
||||
{
|
||||
struct _DEFINE *pNext;
|
||||
int val;
|
||||
char *pszName;
|
||||
unsigned int cchName;
|
||||
char *pszValue;
|
||||
unsigned int cchValue;
|
||||
char achBuffer[1];
|
||||
} DEFINE, *PDEFINE;
|
||||
|
||||
DEFINE *gpDefines = 0;
|
||||
int iLine;
|
||||
const char *gpszCurFile;
|
||||
|
||||
char*
|
||||
convert_path(const char* origpath)
|
||||
{
|
||||
char* newpath;
|
||||
int i;
|
||||
|
||||
newpath = strdup(origpath);
|
||||
|
||||
i = 0;
|
||||
while (newpath[i] != 0)
|
||||
{
|
||||
#ifdef UNIX_PATHS
|
||||
if (newpath[i] == '\\')
|
||||
{
|
||||
newpath[i] = '/';
|
||||
}
|
||||
#else
|
||||
#ifdef DOS_PATHS
|
||||
if (newpath[i] == '/')
|
||||
{
|
||||
newpath[i] = '\\';
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
return newpath;
|
||||
}
|
||||
|
||||
char*
|
||||
GetFolder(const char* pszFullPath)
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
|
||||
void*
|
||||
LoadFile(const char* pszFileName, size_t* pFileSize)
|
||||
{
|
||||
FILE* file;
|
||||
void* pFileData = NULL;
|
||||
int iFileSize;
|
||||
|
||||
trace("Loading file...");
|
||||
|
||||
file = fopen(pszFileName, "rb");
|
||||
if (!file)
|
||||
{
|
||||
trace("Could not open file\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(file, 0L, SEEK_END);
|
||||
iFileSize = ftell(file);
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
*pFileSize = iFileSize;
|
||||
trace("ok. Size is %d\n", iFileSize);
|
||||
|
||||
pFileData = malloc(iFileSize + 1);
|
||||
|
||||
if (pFileData != NULL)
|
||||
{
|
||||
if (iFileSize != fread(pFileData, 1, iFileSize, file))
|
||||
{
|
||||
free(pFileData);
|
||||
pFileData = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace("Could not allocate memory for file\n");
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return pFileData;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
error(char *format, ...)
|
||||
{
|
||||
va_list valist;
|
||||
int res;
|
||||
va_start(valist, format);
|
||||
res = vfprintf(stderr, format, valist);
|
||||
va_end(valist);
|
||||
return res;
|
||||
}
|
||||
|
||||
char*
|
||||
GetNextChar(const char *psz)
|
||||
{
|
||||
while (*psz == ' ' || *psz == '\t') psz++;
|
||||
return (char*)psz;
|
||||
}
|
||||
|
||||
char*
|
||||
GetNextLine(char *pszLine)
|
||||
{
|
||||
/* Walk to the end of the line */
|
||||
while (*pszLine != 13 && *pszLine != 10 && *pszLine != 0) pszLine++;
|
||||
|
||||
/* Skip one CR/LF */
|
||||
if (pszLine[0] == 13 && pszLine[1] == 10)
|
||||
pszLine += 2;
|
||||
else if (pszLine[0] == 13 || pszLine[0] == 10)
|
||||
pszLine++;
|
||||
|
||||
if (*pszLine == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pszLine;
|
||||
}
|
||||
|
||||
int
|
||||
strxlen(const char *psz)
|
||||
{
|
||||
int len = 0;
|
||||
while (isalnum(*psz) || *psz == '_')
|
||||
{
|
||||
psz++;
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
PDEFINE
|
||||
FindDefine(const char *p, char **pNext)
|
||||
{
|
||||
PDEFINE pDefine;
|
||||
int cchName;
|
||||
|
||||
cchName = strxlen(p);
|
||||
if (pNext)
|
||||
*pNext = (char*)p + cchName;
|
||||
|
||||
/* search for the define in the global list */
|
||||
pDefine = gpDefines;
|
||||
while (pDefine != 0)
|
||||
{
|
||||
trace("found a define: %s\n", pDefine->pszName);
|
||||
if (pDefine->cchName == cchName)
|
||||
{
|
||||
if (strncmp(p, pDefine->pszName, cchName) == 0)
|
||||
{
|
||||
return pDefine;
|
||||
}
|
||||
}
|
||||
pDefine = pDefine->pNext;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WriteLine(char *pchLine, FILE *fileOut)
|
||||
{
|
||||
char *pch, *pchLineEnd, *pchVariable;
|
||||
int len;
|
||||
PDEFINE pDefine;
|
||||
|
||||
pchLineEnd = strchr(pchLine, '\n');
|
||||
if (pchLineEnd == 0)
|
||||
return;
|
||||
|
||||
len = pchLineEnd - pchLine + 1;
|
||||
|
||||
pch = pchLine;
|
||||
while (len > 0)
|
||||
{
|
||||
/* Check if there is a $ variable in the line */
|
||||
pchVariable = strchr(pch, '$');
|
||||
if (pchVariable && (pchVariable < pchLineEnd))
|
||||
{
|
||||
/* Write all characters up to the $ */
|
||||
fwrite(pch, 1, pchVariable - pch, fileOut);
|
||||
|
||||
/* Try to find the define */
|
||||
pDefine = FindDefine(pchVariable + 1, &pch);
|
||||
if (pDefine != 0)
|
||||
{
|
||||
/* We have a define, write the value */
|
||||
fwrite(pDefine->pszValue, 1, pDefine->cchValue, fileOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = strxlen(pchVariable + 1) + 1;
|
||||
error("Could not find variable '%.*s'\n", len, pchVariable);
|
||||
fwrite(pchVariable, 1, pch - pchVariable, fileOut);
|
||||
}
|
||||
|
||||
len = pchLineEnd - pch + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite(pch, 1, len, fileOut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
EvaluateConstant(const char *p, char **pNext)
|
||||
{
|
||||
PDEFINE pDefine;
|
||||
|
||||
pDefine = FindDefine(p, pNext);
|
||||
if (!pDefine)
|
||||
return 0;
|
||||
|
||||
return pDefine->val;
|
||||
}
|
||||
|
||||
int
|
||||
EvaluateExpression(char *pExpression, char **pNext)
|
||||
{
|
||||
char *p, *pstart;
|
||||
int inv, thisval, val = 0;
|
||||
|
||||
trace("evaluating expression\n");
|
||||
|
||||
pstart = GetNextChar(pExpression);
|
||||
if (*pstart != '(')
|
||||
{
|
||||
error("Parse error: expected '(' \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Get the start of the real expression */
|
||||
p = pstart;
|
||||
if ((p[0] == '&' && p[1] == '&') ||
|
||||
(p[0] == '|' && p[1] == '|'))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
p = GetNextChar(p + 1);
|
||||
|
||||
/* Check for inversion modifier */
|
||||
if (*p == '!')
|
||||
{
|
||||
inv = 1;
|
||||
p = GetNextChar(p + 1);
|
||||
}
|
||||
else
|
||||
inv = 0;
|
||||
|
||||
/* Beginning of a new subexpression? */
|
||||
if (*p == '(')
|
||||
{
|
||||
/* Evaluate subexpression */
|
||||
thisval = EvaluateExpression(p, &p);
|
||||
}
|
||||
else if (isdigit(*p))
|
||||
{
|
||||
thisval = strtod(p, &p);
|
||||
trace("found a num: %d\n", thisval);
|
||||
}
|
||||
else if (isalpha(*p) || *p == '_')
|
||||
{
|
||||
thisval = EvaluateConstant(p, &p);
|
||||
}
|
||||
else
|
||||
{
|
||||
error("..Parse error, expected '(' or constant in line %d\n",
|
||||
iLine);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (inv)
|
||||
thisval = !thisval;
|
||||
|
||||
/* Check how to combine the current value */
|
||||
if (pstart[0] == '(')
|
||||
{
|
||||
val = thisval;
|
||||
}
|
||||
else if (pstart[0] == '&' && pstart[1] == '&')
|
||||
{
|
||||
val = val && thisval;
|
||||
}
|
||||
else if (pstart[0] == '&' && pstart[1] != '&')
|
||||
{
|
||||
val = val & thisval;
|
||||
}
|
||||
else if (pstart[0] == '|' && pstart[1] == '|')
|
||||
{
|
||||
trace("found || val = %d, thisval = %d\n", val, thisval);
|
||||
val = val || thisval;
|
||||
}
|
||||
else if (pstart[0] == '|' && pstart[1] != '|')
|
||||
{
|
||||
val = val | thisval;
|
||||
}
|
||||
else if (pstart[0] == '+')
|
||||
{
|
||||
val = val + thisval;
|
||||
}
|
||||
else
|
||||
{
|
||||
error("+Parse error: expected '(' or operator in Line %d, got %c\n",
|
||||
iLine, pstart[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = GetNextChar(p);
|
||||
|
||||
/* End of current subexpression? */
|
||||
if (*p == ')')
|
||||
{
|
||||
if (pNext)
|
||||
{
|
||||
*pNext = p + 1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Continue with a new start position */
|
||||
pstart = p;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
ParseInputFile(const char *pszInFile, FILE *fileOut)
|
||||
{
|
||||
char* pInputData, *pCurrentLine, *p1, *p2;
|
||||
size_t cbInFileLenth;
|
||||
int iIfLevel, iCopyLevel;
|
||||
|
||||
trace("parsing input file: %s\n", pszInFile);
|
||||
|
||||
/* Set the global file name */
|
||||
gpszCurFile = pszInFile;
|
||||
|
||||
/* Load the input file into memory */
|
||||
pInputData = LoadFile(pszInFile, &cbInFileLenth);
|
||||
if (!pInputData)
|
||||
{
|
||||
error("Could not load input file %s\n", pszInFile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Zero terminate the file */
|
||||
pInputData[cbInFileLenth] = 0;
|
||||
|
||||
pCurrentLine = pInputData;
|
||||
iLine = 1;
|
||||
iCopyLevel = iIfLevel = 0;
|
||||
|
||||
/* The main processing loop */
|
||||
do
|
||||
{
|
||||
trace("line %d: ", iLine);
|
||||
|
||||
/* If this is a normal line ... */
|
||||
if (pCurrentLine[0] != '$')
|
||||
{
|
||||
/* Check if we are to copy this line */
|
||||
if (iCopyLevel == iIfLevel)
|
||||
{
|
||||
trace("copying\n");
|
||||
WriteLine(pCurrentLine, fileOut);
|
||||
}
|
||||
else
|
||||
trace("skipping\n");
|
||||
|
||||
/* Continue with next line */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for $endif */
|
||||
if (strncmp(pCurrentLine, "$endif", 6) == 0)
|
||||
{
|
||||
trace("found $endif\n");
|
||||
if (iIfLevel <= 0)
|
||||
{
|
||||
error("Parse error: $endif without $if in %s:%d\n", pszInFile, iLine);
|
||||
return -1;
|
||||
}
|
||||
if (iCopyLevel == iIfLevel)
|
||||
{
|
||||
iCopyLevel--;
|
||||
}
|
||||
iIfLevel--;
|
||||
|
||||
/* Continue with next line */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The rest is only parsed when we are in a true block */
|
||||
if (iCopyLevel < iIfLevel)
|
||||
{
|
||||
trace("skipping\n");
|
||||
|
||||
/* Continue with next line */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for $define */
|
||||
if (strncmp(pCurrentLine, "$define", 7) == 0)
|
||||
{
|
||||
PDEFINE pDefine;
|
||||
char *pchName, *pchValue;
|
||||
size_t cchName, cchValue;
|
||||
|
||||
trace("found $define\n");
|
||||
p1 = GetNextChar(pCurrentLine + 7);
|
||||
if (*p1 != '(')
|
||||
{
|
||||
error("Parse error: expected '(' at %s:%d\n",
|
||||
pszInFile, iLine);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pchName = GetNextChar(p1 + 1);
|
||||
cchName = strxlen(pchName);
|
||||
p1 = GetNextChar(pchName + cchName);
|
||||
|
||||
/* Check for assignment */
|
||||
if (*p1 == '=')
|
||||
{
|
||||
trace("found $define with assignment\n");
|
||||
pchValue = GetNextChar(p1 + 1);
|
||||
cchValue = strxlen(pchValue);
|
||||
p1 = GetNextChar(pchValue + cchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
pchValue = 0;
|
||||
cchValue = 0;
|
||||
}
|
||||
|
||||
/* Allocate a DEFINE structure */
|
||||
pDefine = malloc(sizeof(DEFINE) + cchName + cchValue + 2);
|
||||
if (pDefine == 0)
|
||||
{
|
||||
error("Failed to allocate %u bytes\n",
|
||||
sizeof(DEFINE) + cchName + cchValue + 2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pDefine->pszName = pDefine->achBuffer;
|
||||
strncpy(pDefine->pszName, pchName, cchName);
|
||||
pDefine->pszName[cchName] = 0;
|
||||
pDefine->cchName = cchName;
|
||||
pDefine->val = 1;
|
||||
|
||||
if (pchValue != 0)
|
||||
{
|
||||
pDefine->pszValue = &pDefine->achBuffer[cchName + 1];
|
||||
strncpy(pDefine->pszValue, pchValue, cchValue);
|
||||
pDefine->pszValue[cchValue] = 0;
|
||||
pDefine->cchValue = cchValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDefine->pszValue = 0;
|
||||
pDefine->cchValue = 0;
|
||||
}
|
||||
|
||||
/* Insert the new define into the global list */
|
||||
pDefine->pNext = gpDefines;
|
||||
gpDefines = pDefine;
|
||||
|
||||
/* Check for closing ')' */
|
||||
if (*p1 != ')')
|
||||
{
|
||||
error("Parse error: expected ')' at %s:%d\n",
|
||||
pszInFile, iLine);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for $if */
|
||||
else if (strncmp(pCurrentLine, "$if", 3) == 0)
|
||||
{
|
||||
int val;
|
||||
|
||||
trace("found $if\n");
|
||||
/* Increase the if-level */
|
||||
iIfLevel++;
|
||||
|
||||
/* Get beginning of the expression */
|
||||
p1 = GetNextChar(pCurrentLine + 3);
|
||||
|
||||
/* evaluate the expression */
|
||||
val = EvaluateExpression(p1, 0);
|
||||
|
||||
if (val)
|
||||
{
|
||||
iCopyLevel = iIfLevel;
|
||||
}
|
||||
else if (val == -1)
|
||||
{
|
||||
/* Parse error */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for $include */
|
||||
else if (strncmp(pCurrentLine, "$include", 8) == 0)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trace("found $include\n");
|
||||
p1 = GetNextChar(pCurrentLine + 8);
|
||||
if (*p1 != '(')
|
||||
{
|
||||
error("Parse error: expected '(' at %s:%d, found '%c'\n",
|
||||
pszInFile, iLine, *p1);
|
||||
return -1;
|
||||
}
|
||||
p1++;
|
||||
p2 = strchr(p1, ')');
|
||||
*p2 = 0;
|
||||
|
||||
/* Parse the included file */
|
||||
ret = ParseInputFile(p1, fileOut);
|
||||
|
||||
/* Restore the global file name */
|
||||
gpszCurFile = pszInFile;
|
||||
|
||||
/* Restore the zeroed character */
|
||||
*p2 = ')';
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for $$ comment */
|
||||
else if (strncmp(pCurrentLine, "$$", 2) == 0)
|
||||
{
|
||||
trace("$$ ignored\n");
|
||||
/* continue with next line */
|
||||
continue;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
trace("wot:%s\n", pCurrentLine);
|
||||
}
|
||||
|
||||
/* Continue with next line */
|
||||
}
|
||||
while (pCurrentLine = GetNextLine(pCurrentLine),
|
||||
iLine++,
|
||||
pCurrentLine != 0);
|
||||
|
||||
/* Free the file data */
|
||||
free(pInputData);
|
||||
|
||||
trace("Done with file.\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
char *pszInFile, *pszOutFile;
|
||||
FILE* fileOut;
|
||||
int ret;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
error("Usage: hpp <inputfile> <outputfile>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pszInFile = convert_path(argv[1]);
|
||||
pszOutFile = convert_path(argv[2]);
|
||||
|
||||
fileOut = fopen(pszOutFile, "wb");
|
||||
if (fileOut == NULL)
|
||||
{
|
||||
error("Cannot open output file %s", pszOutFile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = ParseInputFile(pszInFile, fileOut);
|
||||
|
||||
fclose(fileOut);
|
||||
free(pszInFile);
|
||||
free(pszOutFile);
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue