[ros-diffs] [tkreuzer] 49462: [SPEC2PDEF] This tool will make me rich. Dedicated to Amine and Richard.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Thu Nov 4 00:54:06 UTC 2010


Author: tkreuzer
Date: Thu Nov  4 00:54:04 2010
New Revision: 49462

URL: http://svn.reactos.org/svn/reactos?rev=49462&view=rev
Log:
[SPEC2PDEF]
This tool will make me rich.
Dedicated to Amine and Richard.

Added:
    branches/cmake-bringup/tools/spec2pdef/   (with props)
    branches/cmake-bringup/tools/spec2pdef/spec2pdef.c   (with props)

Propchange: branches/cmake-bringup/tools/spec2pdef/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Thu Nov  4 00:54:04 2010
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)

Propchange: branches/cmake-bringup/tools/spec2pdef/
------------------------------------------------------------------------------
    bugtraq:message = See issue #%BUGID% for more details.

Propchange: branches/cmake-bringup/tools/spec2pdef/
------------------------------------------------------------------------------
    bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%

Propchange: branches/cmake-bringup/tools/spec2pdef/
------------------------------------------------------------------------------
    tsvn:logminsize = 10

Added: branches/cmake-bringup/tools/spec2pdef/spec2pdef.c
URL: http://svn.reactos.org/svn/reactos/branches/cmake-bringup/tools/spec2pdef/spec2pdef.c?rev=49462&view=auto
==============================================================================
--- branches/cmake-bringup/tools/spec2pdef/spec2pdef.c (added)
+++ branches/cmake-bringup/tools/spec2pdef/spec2pdef.c [iso-8859-1] Thu Nov  4 00:54:04 2010
@@ -1,0 +1,348 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+enum
+{
+    CC_STDCALL,
+    CC_CDECL,
+    CC_FASTCALL,
+    CC_EXTERN,
+};
+
+char* astrCallingConventions[] =
+{
+    "STDCALL",
+    "CDECL",
+    "FASTCALL",
+    "EXTERN"
+};
+
+int
+_strcmpx(const char *string1, const char *string2)
+{
+    while (*string2)
+    {
+        if (*string1 != *string2) return (*string1 - *string2);
+        string1++;
+        string2++;
+    }
+    return 0;
+}
+
+char *
+NextLine(char *pc)
+{
+    /* Skip until the next line or EOF */
+    while (*pc != '\n' && *pc != '\r' && *pc != 0) pc++;
+    if (*pc++ == '\r') pc++;
+    return pc;
+}
+
+char *
+NextToken(char *pc)
+{
+    /* Skip string */
+    while (isprint(*pc) && !isspace(*pc)) pc++;
+
+    /* Skip white spaces */
+    while (*pc == ' ' || *pc == '\t') pc++;
+
+    return pc;
+}
+
+typedef struct
+{
+    char *pcName;
+    int nNameLength;
+    char *pcRedirection;
+    int nRedirectionLength;
+    int nCallingConvention;
+    int nOrdinal;
+    int nStackBytes;
+} EXPORT;
+
+int
+ParseLine(char* pcLine, int nLine, EXPORT *pexp)
+{
+    char *pcCurrent;
+
+    //fprintf(stderr, "info: line %d, pcLine:'%.30s'\n", nLine, pcLine);
+
+    pcCurrent = pcLine;
+
+    /* skip white spaces */
+    while (*pcCurrent == ' ') pcCurrent++;
+
+    /* Check for line break */
+    if (*pcCurrent == '\n' || *pcCurrent == '\r' || *pcCurrent == 0) return 0;
+
+    /* Check for comment */
+    if (*pcCurrent == '#' || *pcCurrent == ';') return 0;
+
+    /* Now we should get either an ordinal or @ */
+    if (*pcCurrent == '@') pexp->nOrdinal = -1;
+    else pexp->nOrdinal = atol(pcCurrent);
+
+    /* Go to next token */
+    pcCurrent = NextToken(pcCurrent);
+
+    //fprintf(stderr, "info: Token:'%.10s'\n", pcCurrent);
+
+    /* Now we should get the calling convention */
+    if (_strcmpx(pcCurrent, "stdcall ") == 0)
+    {
+        pexp->nCallingConvention = CC_STDCALL;
+    }
+    else if (_strcmpx(pcCurrent, "cdecl ") == 0)
+    {
+        pexp->nCallingConvention = CC_CDECL;
+    }
+    else if (_strcmpx(pcCurrent, "fastcall ") == 0 ||
+             _strcmpx(pcCurrent, "FASTCALL ") == 0)
+    {
+        pexp->nCallingConvention = CC_FASTCALL;
+    }
+    else if (_strcmpx(pcCurrent, "extern ") == 0)
+    {
+        pexp->nCallingConvention = CC_EXTERN;
+    }
+    else
+    {
+        fprintf(stderr, "error: line %d, expected cc, got (%p) %d\n", nLine, pcCurrent, *pcCurrent);
+        return -1;
+    }
+
+    //fprintf(stderr, "info: nCallingConvention: %d\n", pexp->nCallingConvention);
+
+    /* Go to next token */
+    pcCurrent = NextToken(pcCurrent);
+
+    /* Handle option */
+    while (*pcCurrent == '-')
+    {
+        fprintf(stderr, "info: got option: '%.10s'\n", pcCurrent);
+        // FIXME: handle options
+
+        /* Go to next token */
+        pcCurrent = NextToken(pcCurrent);
+    }
+
+    //fprintf(stderr, "info: Name:'%.10s'\n", pcCurrent);
+
+    /* Get name */
+    pexp->pcName = pcCurrent;
+    while (isprint(*pcCurrent) && *pcCurrent != '(') pcCurrent++;
+    pexp->nNameLength = pcCurrent - pexp->pcName;
+
+    /* Handle parameters */
+    pexp->nStackBytes = 0;
+    if (pexp->nCallingConvention != CC_EXTERN)
+    {
+        //fprintf(stderr, "info: options:'%.10s'\n", pcCurrent);
+
+        /* Syntax check */
+        if (*pcCurrent++ != '(')
+        {
+            fprintf(stderr, "error: line %d, expected '('\n", nLine);
+            return -1;
+        }
+        
+        pexp->nStackBytes = 0;
+        while (isalpha(*pcCurrent))
+        {
+            if (_strcmpx(pcCurrent, "long") == 0)
+                pexp->nStackBytes += 4;
+            else if (_strcmpx(pcCurrent, "double") == 0)
+                pexp->nStackBytes += 8;
+            else if (_strcmpx(pcCurrent, "ptr") == 0 ||
+                     _strcmpx(pcCurrent, "str") == 0 ||
+                     _strcmpx(pcCurrent, "wstr") == 0)
+                pexp->nStackBytes += sizeof(void*);
+            else
+                fprintf(stderr, "error: line %d, expected type, got: %.10s\n", nLine, pcCurrent);
+
+            /* Go to next parameter */
+            while (isalpha(*pcCurrent)) pcCurrent++;
+            while (isspace(*pcCurrent)) pcCurrent++;
+        }
+
+        /* Check syntax */
+        if (*pcCurrent++ != ')')
+        {
+            fprintf(stderr, "error: line %d, expected ')'\n", nLine);
+            return -1;
+        }
+
+        /* Skip white spaces */
+        while (*pcCurrent == ' ' || *pcCurrent == '\t') pcCurrent++;
+    }
+    
+    /* Get optional redirection */
+    if (isprint(*pcCurrent))
+    {
+        pexp->pcRedirection = pcCurrent;
+        while (isprint(*pcCurrent) && !isspace(*pcCurrent)) pcCurrent++;
+        pexp->nRedirectionLength = pcCurrent - pexp->pcRedirection;
+    }
+    else
+    {
+        pexp->pcRedirection = 0;
+        pexp->nRedirectionLength = 0;
+    }
+    
+    return 1;
+}
+
+int
+OutputLine_def(FILE *fileDest, EXPORT *exp)
+{
+    fprintf(fileDest, " ");
+    if (exp->nCallingConvention == CC_FASTCALL) fprintf(fileDest, "@");
+    fprintf(fileDest, "%.*s", exp->nNameLength, exp->pcName);
+
+    if (exp->nCallingConvention == CC_STDCALL || 
+        exp->nCallingConvention == CC_FASTCALL)
+    {
+        fprintf(fileDest, "@%d", exp->nStackBytes);
+    }
+
+    if (exp->pcRedirection)
+    {
+        if (exp->nCallingConvention == CC_FASTCALL) fprintf(fileDest, "@");
+        fprintf(fileDest, "=%.*s", exp->nRedirectionLength, exp->pcRedirection);
+        if (exp->nCallingConvention == CC_STDCALL || 
+            exp->nCallingConvention == CC_FASTCALL)
+        {
+            fprintf(fileDest, "@%d", exp->nStackBytes);
+        }
+    }
+
+    if (exp->nOrdinal != -1)
+    {
+        fprintf(fileDest, " @%d", exp->nOrdinal);
+    }
+
+    if (exp->nCallingConvention == CC_EXTERN)
+    {
+        fprintf(fileDest, " DATA");
+    }
+
+    fprintf(fileDest, "\n");
+
+    return 1;
+}
+
+int
+OutputLine(FILE *fileDest, EXPORT *exp)
+{
+    fprintf(fileDest, "_NAME(%.*s,%s,%d)",
+            exp->nNameLength, exp->pcName,
+            astrCallingConventions[exp->nCallingConvention],
+            exp->nStackBytes);
+
+    if (exp->pcRedirection)
+    {
+        fprintf(fileDest, "= _NAME(%.*s,%s,%d)",
+                exp->nRedirectionLength, exp->pcRedirection,
+                astrCallingConventions[exp->nCallingConvention],
+                exp->nStackBytes);
+    }
+
+    if (exp->nOrdinal != -1)
+    {
+        fprintf(fileDest, " @%d", exp->nOrdinal);
+    }
+
+    if (exp->nCallingConvention == CC_EXTERN)
+    {
+        fprintf(fileDest, " DATA");
+    }
+
+    fprintf(fileDest, "\n");
+
+    return 1;
+}
+
+void
+OutputHeader(FILE *file)
+{
+    fprintf(file, 
+            "; File generated automatically, do not edit!\n\n"
+            "LIBRARY ntoskrnl.exe\n\n"
+            "EXPORTS\n"
+            "#define FOOL(x) x\n"
+            "#ifdef _MSC_VER\n"
+            "#define _NAME_STDCALL(name, stackbytes) name\n"
+            "#define _NAME_FASTCALL(name, stackbytes) name\n"
+            "#define _NAME_CDECL(name, stackbytes) name\n"
+            "#else\n"
+            "#define _NAME_STDCALL(name, stackbytes) FOOL(name)@stackbytes\n"
+            "#define _NAME_FASTCALL(name, stackbytes) FOOL(@)FOOL(name)@stackbytes\n"
+            "#define _NAME_CDECL(name, stackbytes) FOOL(name)\n"
+            "#endif\n"
+            "#define _NAME_EXTERN(name, stackbytes) name\n"
+            "#define _NAME(name, cc, stackbytes) _NAME_##cc(name, stackbytes)\n");
+}
+
+
+int main(int argc, char *argv[])
+{
+    size_t nFileSize;
+    char *pszSource, *pcLine;
+    int nLine, result;
+    FILE *fileSource, *fileDest;
+    EXPORT exp;
+
+    /* Open input file argv[1] */
+    fileSource = fopen(argv[1], "r");
+    if (!fileSource)
+    {
+        fprintf(stderr, "error: could not open file %s ", argv[1]);
+        return -1;
+    }
+
+    /* Get file size */
+    fseek(fileSource, 0, SEEK_END);
+    nFileSize = ftell(fileSource);
+    rewind(fileSource);
+
+    /* Allocate memory buffer */
+    pszSource = malloc(nFileSize + 1);
+    if (!pszSource) return -1;
+
+    /* Load input file into memory */
+    nFileSize = fread(pszSource, 1, nFileSize, fileSource);
+
+    /* Zero terminate the source */
+    pszSource[nFileSize] = '\0';
+
+    // open output file argv[2]
+    fileDest = fopen(argv[2], "w");
+    if (!fileDest)
+    {
+        fprintf(stderr, "error: could not open output file %s ", argv[2]);
+        return -1;
+    }
+
+    OutputHeader(fileDest);
+
+    pcLine = pszSource;
+    for (nLine = 1; *pcLine != 0; pcLine = NextLine(pcLine), nLine++)
+    {
+        /* Parse the spec file line */
+        result = ParseLine(pcLine, nLine, &exp);
+
+        if (result == 1)
+        {
+            OutputLine(fileDest, &exp);
+        }
+        else if (result == -1) break;
+
+        
+    }
+
+    fclose(fileDest);
+    fclose(fileSource);
+    return 0;
+}

Propchange: branches/cmake-bringup/tools/spec2pdef/spec2pdef.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list