ReactOS 0.4.15-dev-5667-ged97270
spec2def.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
Include dependency graph for spec2def.c:

Go to the source code of this file.

Classes

struct  _STRING
 
struct  EXPORT
 

Macros

#define ARRAYSIZE(a)   (sizeof(a) / sizeof((a)[0]))
 
#define DbgPrint(...)   (!gbDebug || fprintf(stderr, __VA_ARGS__))
 

Typedefs

typedef struct _STRING STRING
 
typedef struct _STRINGPSTRING
 
typedef int(* PFNOUTLINE) (FILE *, EXPORT *)
 

Enumerations

enum  _ARCH {
  ARCH_X86 , ARCH_AMD64 , ARCH_IA64 , ARCH_ARM ,
  ARCH_ARM64 , ARCH_PPC
}
 
enum  {
  FL_PRIVATE = 1 , FL_STUB = 2 , FL_NONAME = 4 , FL_ORDINAL = 8 ,
  FL_NORELAY = 16 , FL_RET64 = 32 , FL_REGISTER = 64
}
 
enum  {
  CC_STDCALL , CC_CDECL , CC_FASTCALL , CC_THISCALL ,
  CC_EXTERN , CC_STUB
}
 
enum  {
  ARG_LONG , ARG_PTR , ARG_STR , ARG_WSTR ,
  ARG_DBL , ARG_INT64 , ARG_INT128 , ARG_FLOAT
}
 

Functions

static int IsSeparator (char chr)
 
int CompareToken (const char *token, const char *comparand)
 
const charScanToken (const char *token, char chr)
 
const charNextLine (const char *pc)
 
int TokenLength (const char *pc)
 
const charNextToken (const char *pc)
 
void OutputHeader_stub (FILE *file)
 
int OutputLine_stub (FILE *file, EXPORT *pexp)
 
void OutputHeader_asmstub (FILE *file, char *libname)
 
void Output_stublabel (FILE *fileDest, char *pszSymbolName)
 
int OutputLine_asmstub (FILE *fileDest, EXPORT *pexp)
 
void OutputHeader_def (FILE *file, char *libname)
 
void PrintName (FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
 
void OutputLine_def_MS (FILE *fileDest, EXPORT *pexp)
 
void OutputLine_def_GCC (FILE *fileDest, EXPORT *pexp)
 
int OutputLine_def (FILE *fileDest, EXPORT *pexp)
 
void Fatalv (const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format, va_list argptr)
 
void Fatal (const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format,...)
 
EXPORTParseFile (char *pcStart, FILE *fileDest, unsigned *cExports)
 
int ApplyOrdinals (EXPORT *pexports, unsigned cExports)
 
void usage (void)
 
int main (int argc, char *argv[])
 

Variables

int gbMSComp = 0
 
int gbImportLib = 0
 
int gbNotPrivateNoWarn = 0
 
int gbTracing = 0
 
int giArch = ARCH_X86
 
charpszArchString = "i386"
 
charpszArchString2
 
charpszSourceFileName = NULL
 
charpszDllName = NULL
 
chargpszUnderscore = ""
 
int gbDebug
 
unsigned guOsVersion = 0x502
 
const charastrCallingConventions []
 
static const charastrOlePrivateExports []
 

Macro Definition Documentation

◆ ARRAYSIZE

#define ARRAYSIZE (   a)    (sizeof(a) / sizeof((a)[0]))

Definition at line 12 of file spec2def.c.

◆ DbgPrint

#define DbgPrint (   ...)    (!gbDebug || fprintf(stderr, __VA_ARGS__))

Definition at line 77 of file spec2def.c.

Typedef Documentation

◆ PFNOUTLINE

typedef int(* PFNOUTLINE) (FILE *, EXPORT *)

Definition at line 64 of file spec2def.c.

◆ PSTRING

typedef struct _STRING * PSTRING

◆ STRING

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
FL_PRIVATE 
FL_STUB 
FL_NONAME 
FL_ORDINAL 
FL_NORELAY 
FL_RET64 
FL_REGISTER 

Definition at line 79 of file spec2def.c.

80{
81 FL_PRIVATE = 1,
82 FL_STUB = 2,
83 FL_NONAME = 4,
84 FL_ORDINAL = 8,
85 FL_NORELAY = 16,
86 FL_RET64 = 32,
87 FL_REGISTER = 64,
88};
@ FL_PRIVATE
Definition: spec2def.c:81
@ FL_REGISTER
Definition: spec2def.c:87
@ FL_NONAME
Definition: spec2def.c:83
@ FL_ORDINAL
Definition: spec2def.c:84
@ FL_RET64
Definition: spec2def.c:86
@ FL_NORELAY
Definition: spec2def.c:85
@ FL_STUB
Definition: spec2def.c:82

◆ anonymous enum

anonymous enum
Enumerator
CC_STDCALL 
CC_CDECL 
CC_FASTCALL 
CC_THISCALL 
CC_EXTERN 
CC_STUB 

Definition at line 90 of file spec2def.c.

91{
97 CC_STUB,
98};
@ CC_STUB
Definition: spec2def.c:97
@ CC_CDECL
Definition: spec2def.c:93
@ CC_STDCALL
Definition: spec2def.c:92
@ CC_FASTCALL
Definition: spec2def.c:94
@ CC_THISCALL
Definition: spec2def.c:95
@ CC_EXTERN
Definition: spec2def.c:96

◆ anonymous enum

anonymous enum
Enumerator
ARG_LONG 
ARG_PTR 
ARG_STR 
ARG_WSTR 
ARG_DBL 
ARG_INT64 
ARG_INT128 
ARG_FLOAT 

Definition at line 100 of file spec2def.c.

101{
102 ARG_LONG,
103 ARG_PTR,
104 ARG_STR,
105 ARG_WSTR,
106 ARG_DBL,
107 ARG_INT64,
110};
@ ARG_DBL
Definition: spec2def.c:106
@ ARG_FLOAT
Definition: spec2def.c:109
@ ARG_LONG
Definition: spec2def.c:102
@ ARG_PTR
Definition: spec2def.c:103
@ ARG_INT64
Definition: spec2def.c:107
@ ARG_STR
Definition: spec2def.c:104
@ ARG_WSTR
Definition: spec2def.c:105
@ ARG_INT128
Definition: spec2def.c:108

◆ _ARCH

Enumerator
ARCH_X86 
ARCH_AMD64 
ARCH_IA64 
ARCH_ARM 
ARCH_ARM64 
ARCH_PPC 

Definition at line 54 of file spec2def.c.

55{
62};
@ ARCH_IA64
Definition: spec2def.c:58
@ ARCH_AMD64
Definition: spec2def.c:57
@ ARCH_X86
Definition: spec2def.c:56
@ ARCH_ARM64
Definition: spec2def.c:60
@ ARCH_ARM
Definition: spec2def.c:59
@ ARCH_PPC
Definition: spec2def.c:61

Function Documentation

◆ ApplyOrdinals()

int ApplyOrdinals ( EXPORT pexports,
unsigned  cExports 
)

Definition at line 1352 of file spec2def.c.

1353{
1354 unsigned short i, j;
1355 char* used;
1356
1357 /* Allocate a table to mark used ordinals */
1358 used = malloc(65536);
1359 if (used == NULL)
1360 {
1361 fprintf(stderr, "Failed to allocate memory for ordinal use table\n");
1362 return -1;
1363 }
1364 memset(used, 0, 65536);
1365
1366 /* Pass 1: mark the ordinals that are already used */
1367 for (i = 0; i < cExports; i++)
1368 {
1369 if (pexports[i].uFlags & FL_ORDINAL)
1370 {
1371 if (used[pexports[i].nOrdinal] != 0)
1372 {
1373 fprintf(stderr, "Found duplicate ordinal: %u\n", pexports[i].nOrdinal);
1374 return -1;
1375 }
1376 used[pexports[i].nOrdinal] = 1;
1377 }
1378 }
1379
1380 /* Pass 2: apply available ordinals */
1381 for (i = 0, j = 1; i < cExports; i++)
1382 {
1383 if ((pexports[i].uFlags & FL_ORDINAL) == 0 && pexports[i].bVersionIncluded)
1384 {
1385 while (used[j] != 0)
1386 j++;
1387
1388 pexports[i].nOrdinal = j;
1389 used[j] = 1;
1390 }
1391 }
1392
1393 free(used);
1394 return 0;
1395}
static int used
Definition: adh-main.c:39
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
UINT uFlags
Definition: api.c:59
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
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 GLint GLint j
Definition: glfuncs.h:250
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define memset(x, y, z)
Definition: compat.h:39
int nOrdinal
Definition: spec2def.c:25

Referenced by main().

◆ CompareToken()

int CompareToken ( const char token,
const char comparand 
)

Definition at line 154 of file spec2def.c.

155{
156 while (*comparand)
157 {
158 if (*token != *comparand) return 0;
159 token++;
160 comparand++;
161 }
162 if (IsSeparator(comparand[-1])) return 1;
163 if (!IsSeparator(*token)) return 0;
164 return 1;
165}
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 token
Definition: glfuncs.h:210
static int IsSeparator(char chr)
Definition: spec2def.c:147

Referenced by ParseFile().

◆ Fatal()

void Fatal ( const char filename,
unsigned  nLine,
const char pcLine,
const char pc,
size_t  errorlen,
const char format,
  ... 
)

Definition at line 851 of file spec2def.c.

859{
860 va_list argptr;
861
862 va_start(argptr, format);
863 Fatalv(filename, nLine, pcLine, pc, errorlen, format, argptr);
864 va_end(argptr);
865}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
const char * filename
Definition: ioapi.h:137
void Fatalv(const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format, va_list argptr)
Definition: spec2def.c:801

Referenced by AcpiExOpcode_3A_0T_0R(), and ParseFile().

◆ Fatalv()

void Fatalv ( const char filename,
unsigned  nLine,
const char pcLine,
const char pc,
size_t  errorlen,
const char format,
va_list  argptr 
)

Definition at line 801 of file spec2def.c.

809{
810 unsigned i, errorpos, len;
811 const char* pcLineEnd;
812
813 /* Get the length of the line */
814 pcLineEnd = strpbrk(pcLine, "\r\n");
815 len = (unsigned)(pcLineEnd - pcLine);
816
817 if (pc == NULL)
818 {
819 pc = pcLine + len - 1;
820 errorlen = 1;
821 }
822
823 errorpos = (unsigned)(pc - pcLine);
824
825 /* Output the error message */
826 fprintf(stderr, "ERROR: (%s:%u:%u): ", filename, nLine, errorpos);
827 vfprintf(stderr, format, argptr);
828 fprintf(stderr, "\n");
829
830 /* Output the line with the error */
831 fprintf(stderr, "> %.*s\n", len, pcLine);
832
833 if (errorlen == 0)
834 {
835 errorlen = TokenLength(pc);
836 }
837
838 for (i = 0; i < errorpos + 2; i++)
839 {
840 fprintf(stderr, " ");
841 }
842 for (i = 0; i < errorlen; i++)
843 {
844 fprintf(stderr, "~");
845 }
846 fprintf(stderr, "\n");
847 exit(-1);
848}
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
static unsigned(__cdecl *hash_bstr)(bstr_t s)
#define exit(n)
Definition: config.h:202
int TokenLength(const char *pc)
Definition: spec2def.c:191

Referenced by Fatal().

◆ IsSeparator()

static int IsSeparator ( char  chr)
static

Definition at line 147 of file spec2def.c.

148{
149 return ((chr <= ',' && chr != '$' && chr != '#') ||
150 (chr >= ':' && chr < '?') );
151}

Referenced by CompareToken(), NextToken(), ScanToken(), and TokenLength().

◆ main()

int main ( int argc  ,
char argv[] 
)

Definition at line 1413 of file spec2def.c.

1414{
1415 size_t nFileSize;
1416 char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
1417 const char* pszVersionOption = "--version=0x";
1418 char achDllName[40];
1419 FILE *file;
1420 unsigned cExports = 0, i;
1421 EXPORT *pexports;
1422
1423 if (argc < 2)
1424 {
1425 usage();
1426 return -1;
1427 }
1428
1429 /* Read options */
1430 for (i = 1; i < (unsigned)argc && *argv[i] == '-'; i++)
1431 {
1432 if ((strcasecmp(argv[i], "--help") == 0) ||
1433 (strcasecmp(argv[i], "-h") == 0))
1434 {
1435 usage();
1436 return 0;
1437 }
1438 else if (argv[i][1] == 'd' && argv[i][2] == '=')
1439 {
1440 pszDefFileName = argv[i] + 3;
1441 }
1442 else if (argv[i][1] == 'l' && argv[i][2] == '=')
1443 {
1444 pszLibStubName = argv[i] + 3;
1445 }
1446 else if (argv[i][1] == 's' && argv[i][2] == '=')
1447 {
1448 pszStubFileName = argv[i] + 3;
1449 }
1450 else if (argv[i][1] == 'n' && argv[i][2] == '=')
1451 {
1452 pszDllName = argv[i] + 3;
1453 }
1454 else if (strncasecmp(argv[i], pszVersionOption, strlen(pszVersionOption)) == 0)
1455 {
1456 guOsVersion = strtoul(argv[i] + strlen(pszVersionOption), NULL, 16);
1457 }
1458 else if (strcasecmp(argv[i], "--implib") == 0)
1459 {
1460 gbImportLib = 1;
1461 }
1462 else if (strcasecmp(argv[i], "--ms") == 0)
1463 {
1464 gbMSComp = 1;
1465 }
1466 else if (strcasecmp(argv[i], "--no-private-warnings") == 0)
1467 {
1469 }
1470 else if (strcasecmp(argv[i], "--with-tracing") == 0)
1471 {
1472 if (!pszStubFileName)
1473 {
1474 fprintf(stderr, "Error: cannot use --with-tracing without -s option.\n");
1475 return -1;
1476 }
1477 gbTracing = 1;
1478 }
1479 else if (argv[i][1] == 'a' && argv[i][2] == '=')
1480 {
1481 pszArchString = argv[i] + 3;
1482 }
1483 else
1484 {
1485 fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
1486 return -1;
1487 }
1488 }
1489
1490 if (strcasecmp(pszArchString, "i386") == 0)
1491 {
1492 giArch = ARCH_X86;
1493 gpszUnderscore = "_";
1494 }
1495 else if (strcasecmp(pszArchString, "x86_64") == 0) giArch = ARCH_AMD64;
1496 else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64;
1497 else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM;
1498 else if (strcasecmp(pszArchString, "arm64") == 0) giArch = ARCH_ARM64;
1499 else if (strcasecmp(pszArchString, "ppc") == 0) giArch = ARCH_PPC;
1500
1501 if ((giArch == ARCH_AMD64) || (giArch == ARCH_IA64))
1502 {
1503 pszArchString2 = "win64";
1504 }
1505 else
1506 pszArchString2 = "win32";
1507
1508 /* Set a default dll name */
1509 if (!pszDllName)
1510 {
1511 char *p1, *p2;
1512 size_t len;
1513
1514 p1 = strrchr(argv[i], '\\');
1515 if (!p1) p1 = strrchr(argv[i], '/');
1516 p2 = p1 = p1 ? p1 + 1 : argv[i];
1517
1518 /* walk up to '.' */
1519 while (*p2 != '.' && *p2 != 0) p2++;
1520 len = p2 - p1;
1521 if (len >= sizeof(achDllName) - 5)
1522 {
1523 fprintf(stderr, "name too long: %s\n", p1);
1524 return -2;
1525 }
1526
1527 strncpy(achDllName, p1, len);
1528 strncpy(achDllName + len, ".dll", sizeof(achDllName) - len);
1529 pszDllName = achDllName;
1530 }
1531
1532 /* Open input file */
1535 if (!file)
1536 {
1537 fprintf(stderr, "error: could not open file %s\n", pszSourceFileName);
1538 return -3;
1539 }
1540
1541 /* Get file size */
1542 fseek(file, 0, SEEK_END);
1543 nFileSize = ftell(file);
1544 rewind(file);
1545
1546 /* Allocate memory buffer */
1547 pszSource = malloc(nFileSize + 1);
1548 if (!pszSource)
1549 {
1550 fclose(file);
1551 return -4;
1552 }
1553
1554 /* Load input file into memory */
1555 nFileSize = fread(pszSource, 1, nFileSize, file);
1556 fclose(file);
1557
1558 /* Zero terminate the source */
1559 pszSource[nFileSize] = '\0';
1560
1561 pexports = ParseFile(pszSource, file, &cExports);
1562 if (pexports == NULL)
1563 {
1564 fprintf(stderr, "error: could not parse file!\n");
1565 return -1;
1566 }
1567
1568 if (!gbMSComp)
1569 {
1570 if (ApplyOrdinals(pexports, cExports) < 0)
1571 {
1572 fprintf(stderr, "error: could not apply ordinals!\n");
1573 return -1;
1574 }
1575 }
1576
1577 if (pszDefFileName)
1578 {
1579 /* Open output file */
1580 file = fopen(pszDefFileName, "w");
1581 if (!file)
1582 {
1583 fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1584 return -5;
1585 }
1586
1588
1589 for (i = 0; i < cExports; i++)
1590 {
1591 if (pexports[i].bVersionIncluded)
1592 OutputLine_def(file, &pexports[i]);
1593 }
1594
1595 fclose(file);
1596 }
1597
1598 if (pszStubFileName)
1599 {
1600 /* Open output file */
1601 file = fopen(pszStubFileName, "w");
1602 if (!file)
1603 {
1604 fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1605 return -5;
1606 }
1607
1609
1610 for (i = 0; i < cExports; i++)
1611 {
1612 if (pexports[i].bVersionIncluded)
1613 OutputLine_stub(file, &pexports[i]);
1614 }
1615
1616 fclose(file);
1617 }
1618
1619 if (pszLibStubName)
1620 {
1621 /* Open output file */
1622 file = fopen(pszLibStubName, "w");
1623 if (!file)
1624 {
1625 fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1626 return -5;
1627 }
1628
1630
1631 for (i = 0; i < cExports; i++)
1632 {
1633 if (pexports[i].bVersionIncluded)
1634 OutputLine_asmstub(file, &pexports[i]);
1635 }
1636
1637 fprintf(file, "\n END\n");
1638 fclose(file);
1639 }
1640
1641 free(pexports);
1642
1643 return 0;
1644}
static int argc
Definition: ServiceArgs.c:12
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define SEEK_END
Definition: cabinet.c:27
#define strncasecmp
Definition: fake.h:10
#define strcasecmp
Definition: fake.h:9
_CRTIMP void __cdecl rewind(_Inout_ FILE *_File)
_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)
#define argv
Definition: mplay32.c:18
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
unsigned guOsVersion
Definition: spec2def.c:76
void OutputHeader_stub(FILE *file)
Definition: spec2def.c:219
int OutputLine_stub(FILE *file, EXPORT *pexp)
Definition: spec2def.c:242
char * pszArchString2
Definition: spec2def.c:71
void OutputHeader_def(FILE *file, char *libname)
Definition: spec2def.c:537
char * pszSourceFileName
Definition: spec2def.c:72
int gbNotPrivateNoWarn
Definition: spec2def.c:67
char * pszDllName
Definition: spec2def.c:73
int giArch
Definition: spec2def.c:69
int gbMSComp
Definition: spec2def.c:65
void OutputHeader_asmstub(FILE *file, char *libname)
Definition: spec2def.c:441
int ApplyOrdinals(EXPORT *pexports, unsigned cExports)
Definition: spec2def.c:1352
int gbImportLib
Definition: spec2def.c:66
char * pszArchString
Definition: spec2def.c:70
int OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:479
void usage(void)
Definition: spec2def.c:1397
int OutputLine_def(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:748
int gbTracing
Definition: spec2def.c:68
EXPORT * ParseFile(char *pcStart, FILE *fileDest, unsigned *cExports)
Definition: spec2def.c:868
char * gpszUnderscore
Definition: spec2def.c:74
Definition: fci.c:127

◆ NextLine()

const char * NextLine ( const char pc)

Definition at line 179 of file spec2def.c.

180{
181 while (*pc != 0)
182 {
183 if (pc[0] == '\n' && pc[1] == '\r') return pc + 2;
184 else if (pc[0] == '\n') return pc + 1;
185 pc++;
186 }
187 return pc;
188}

Referenced by ParseFile().

◆ NextToken()

const char * NextToken ( const char pc)

Definition at line 201 of file spec2def.c.

202{
203 /* Skip token */
204 while (!IsSeparator(*pc)) pc++;
205
206 /* Skip white spaces */
207 while (*pc == ' ' || *pc == '\t') pc++;
208
209 /* Check for end of line */
210 if (*pc == '\n' || *pc == '\r' || *pc == 0) return 0;
211
212 /* Check for comment */
213 if (*pc == '#' || *pc == ';') return 0;
214
215 return pc;
216}

Referenced by ParseFile().

◆ Output_stublabel()

void Output_stublabel ( FILE fileDest,
char pszSymbolName 
)

Definition at line 460 of file spec2def.c.

461{
462 if (giArch == ARCH_ARM || giArch == ARCH_ARM64)
463 {
464 fprintf(fileDest,
465 "\tEXPORT |%s| [FUNC]\n|%s|\n",
466 pszSymbolName,
467 pszSymbolName);
468 }
469 else
470 {
471 fprintf(fileDest,
472 "PUBLIC %s\n%s: nop\n",
473 pszSymbolName,
474 pszSymbolName);
475 }
476}

Referenced by OutputLine_asmstub().

◆ OutputHeader_asmstub()

void OutputHeader_asmstub ( FILE file,
char libname 
)

Definition at line 441 of file spec2def.c.

442{
443 fprintf(file, "; File generated automatically, do not edit!\n\n");
444
445 if (giArch == ARCH_X86)
446 {
447 fprintf(file, ".586\n.model flat\n.code\n");
448 }
449 else if (giArch == ARCH_AMD64)
450 {
451 fprintf(file, ".code\n");
452 }
453 else if (giArch == ARCH_ARM || giArch == ARCH_ARM64)
454 {
455 fprintf(file, " AREA |.text|,ALIGN=2,CODE,READONLY\n\n");
456 }
457}

Referenced by main().

◆ OutputHeader_def()

void OutputHeader_def ( FILE file,
char libname 
)

Definition at line 537 of file spec2def.c.

538{
540 "; File generated automatically, do not edit!\n\n"
541 "NAME %s\n\n"
542 "EXPORTS\n",
543 libname);
544}

Referenced by main().

◆ OutputHeader_stub()

void OutputHeader_stub ( FILE file)

Definition at line 219 of file spec2def.c.

220{
221 fprintf(file, "/* This file is autogenerated, do not edit. */\n\n"
222 "#include <stubs.h>\n");
223
224 if (gbTracing)
225 {
226 fprintf(file, "#include <wine/debug.h>\n");
227 fprintf(file, "#include <inttypes.h>\n");
228 fprintf(file, "WINE_DECLARE_DEBUG_CHANNEL(relay);\n");
229 }
230
231 /* __int128 is not supported on x86, so use a custom type */
232 fprintf(file, "\n"
233 "typedef struct {\n"
234 " __int64 lower;\n"
235 " __int64 upper;\n"
236 "} MyInt128;\n");
237
238 fprintf(file, "\n");
239}

Referenced by main().

◆ OutputLine_asmstub()

int OutputLine_asmstub ( FILE fileDest,
EXPORT pexp 
)

Definition at line 479 of file spec2def.c.

480{
481 char szNameBuffer[128];
482
483 /* Handle autoname */
484 if (pexp->strName.len == 1 && pexp->strName.buf[0] == '@')
485 {
486 sprintf(szNameBuffer, "%s_stub_ordinal%d",
487 gpszUnderscore, pexp->nOrdinal);
488 }
489 else if (giArch != ARCH_X86)
490 {
491 /* Does the string already have stdcall decoration? */
492 const char *pcAt = ScanToken(pexp->strName.buf, '@');
493 if (pcAt && (pcAt < (pexp->strName.buf + pexp->strName.len)) &&
494 (pexp->strName.buf[0] == '_'))
495 {
496 /* Skip leading underscore and remove trailing decoration */
497 sprintf(szNameBuffer, "_stub_%.*s",
498 (int)(pcAt - pexp->strName.buf - 1),
499 pexp->strName.buf + 1);
500 }
501 else
502 {
503 sprintf(szNameBuffer, "_stub_%.*s",
504 pexp->strName.len, pexp->strName.buf);
505 }
506 }
507 else if (pexp->nCallingConvention == CC_STDCALL)
508 {
509 sprintf(szNameBuffer, "__stub_%.*s@%d",
510 pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
511 }
512 else if (pexp->nCallingConvention == CC_FASTCALL)
513 {
514 sprintf(szNameBuffer, "@_stub_%.*s@%d",
515 pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
516 }
517 else if ((pexp->nCallingConvention == CC_CDECL) ||
518 (pexp->nCallingConvention == CC_THISCALL) ||
519 (pexp->nCallingConvention == CC_EXTERN) ||
520 (pexp->nCallingConvention == CC_STUB))
521 {
522 sprintf(szNameBuffer, "__stub_%.*s",
523 pexp->strName.len, pexp->strName.buf);
524 }
525 else
526 {
527 fprintf(stderr, "Invalid calling convention");
528 return 0;
529 }
530
531 Output_stublabel(fileDest, szNameBuffer);
532
533 return 1;
534}
#define sprintf(buf, format,...)
Definition: sprintf.c:55
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:168
void Output_stublabel(FILE *fileDest, char *pszSymbolName)
Definition: spec2def.c:460
STRING strName
Definition: spec2def.c:22
int nCallingConvention
Definition: spec2def.c:24
int nStackBytes
Definition: spec2def.c:26
const char * buf
Definition: spec2def.c:16
int len
Definition: spec2def.c:17

Referenced by main().

◆ OutputLine_def()

int OutputLine_def ( FILE fileDest,
EXPORT pexp 
)

Definition at line 748 of file spec2def.c.

749{
750 /* Don't add private exports to the import lib */
751 if (gbImportLib && (pexp->uFlags & FL_PRIVATE))
752 {
753 DbgPrint("OutputLine_def: skipping private export '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
754 return 1;
755 }
756
757 /* For MS linker, forwarded externs are managed via #pragma comment(linker,"/export:_data=org.data,DATA") */
758 if (gbMSComp && !gbImportLib && (pexp->nCallingConvention == CC_EXTERN) &&
759 (pexp->strTarget.buf != NULL) && !!ScanToken(pexp->strTarget.buf, '.'))
760 {
761 DbgPrint("OutputLine_def: skipping forwarded extern export '%.*s' ->'%.*s'...\n",
762 pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
763 return 1;
764 }
765
766 DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
767 fprintf(fileDest, " ");
768
769 if (gbMSComp)
770 OutputLine_def_MS(fileDest, pexp);
771 else
772 OutputLine_def_GCC(fileDest, pexp);
773
774 /* On GCC builds we force ordinals */
775 if ((pexp->uFlags & FL_ORDINAL) || (!gbMSComp && !gbImportLib))
776 {
777 fprintf(fileDest, " @%d", pexp->nOrdinal);
778 }
779
780 if (pexp->uFlags & FL_NONAME)
781 {
782 fprintf(fileDest, " NONAME");
783 }
784
785 /* Either PRIVATE or DATA */
786 if (pexp->uFlags & FL_PRIVATE)
787 {
788 fprintf(fileDest, " PRIVATE");
789 }
790 else if (pexp->nCallingConvention == CC_EXTERN)
791 {
792 fprintf(fileDest, " DATA");
793 }
794
795 fprintf(fileDest, "\n");
796
797 return 1;
798}
#define DbgPrint(...)
Definition: spec2def.c:77
void OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:630
void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:681
STRING strTarget
Definition: spec2def.c:23
unsigned int uFlags
Definition: spec2def.c:29

Referenced by main().

◆ OutputLine_def_GCC()

void OutputLine_def_GCC ( FILE fileDest,
EXPORT pexp 
)

Definition at line 681 of file spec2def.c.

682{
683 int bTracing = 0;
684 /* Print the function name, with decoration for export libs */
685 PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
686 DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
687
688 /* Check if this is a forwarded export */
689 if (pexp->strTarget.buf)
690 {
691 int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
692 DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
693
694 /* print the target name, don't decorate if it is external */
695 fprintf(fileDest, "=");
696 PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
697 }
698 else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
699 (pexp->strName.buf[0] == '?'))
700 {
701 /* C++ stubs are forwarded to C stubs */
702 fprintf(fileDest, "=stub_function%d", pexp->nNumber);
703 }
704 else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) &&
705 (pexp->nCallingConvention == CC_STDCALL) &&
706 (pexp->strName.buf[0] != '?'))
707 {
708 /* Redirect it to the relay-tracing trampoline */
709 char buf[256];
710 STRING strTarget;
711 fprintf(fileDest, "=");
712 sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
713 strTarget.buf = buf;
714 strTarget.len = pexp->strName.len + 12;
715 PrintName(fileDest, pexp, &strTarget, 1);
716 bTracing = 1;
717 }
718
719 /* Special handling for stdcall and fastcall, but not C++ exports*/
720 if ((giArch == ARCH_X86) &&
721 (pexp->strName.buf[0] != '?') &&
722 ((pexp->nCallingConvention == CC_STDCALL) ||
724 {
725 /* Is this the import lib? */
726 if (gbImportLib)
727 {
728 /* Is the name in the spec file decorated? */
729 const char* pcDeco = ScanToken(pexp->strName.buf, '@');
730 if (pcDeco &&
731 (pexp->strName.len > 1) &&
732 (pcDeco < pexp->strName.buf + pexp->strName.len))
733 {
734 /* Write the name including the leading @ */
735 fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
736 }
737 }
738 else if ((!pexp->strTarget.buf) && !(bTracing))
739 {
740 /* Write a forwarder to the actual decorated symbol */
741 fprintf(fileDest, "=");
742 PrintName(fileDest, pexp, &pexp->strName, 1);
743 }
744 }
745}
std::wstring STRING
Definition: fontsub.cpp:33
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:547
int nNumber
Definition: spec2def.c:30

Referenced by OutputLine_def().

◆ OutputLine_def_MS()

void OutputLine_def_MS ( FILE fileDest,
EXPORT pexp 
)

Definition at line 630 of file spec2def.c.

631{
632 PrintName(fileDest, pexp, &pexp->strName, 0);
633
634 if (gbImportLib)
635 {
636 /* Redirect to a stub function, to get the right decoration in the lib */
637 fprintf(fileDest, "=_stub_");
638 PrintName(fileDest, pexp, &pexp->strName, 0);
639 }
640 else if (pexp->strTarget.buf)
641 {
642 if (pexp->strName.buf[0] == '?')
643 {
644 //fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
645 // pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
646 }
647 else
648 {
649 fprintf(fileDest, "=");
650
651 /* If the original name was decorated, use decoration in the forwarder as well */
652 if ((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
653 !ScanToken(pexp->strTarget.buf, '@') &&
654 ((pexp->nCallingConvention == CC_STDCALL) ||
655 (pexp->nCallingConvention == CC_FASTCALL)) )
656 {
657 PrintName(fileDest, pexp, &pexp->strTarget, 1);
658 }
659 else
660 {
661 /* Write the undecorated redirection name */
662 fprintf(fileDest, "%.*s", pexp->strTarget.len, pexp->strTarget.buf);
663 }
664 }
665 }
666 else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
667 (pexp->strName.buf[0] == '?'))
668 {
669 /* C++ stubs are forwarded to C stubs */
670 fprintf(fileDest, "=stub_function%d", pexp->nNumber);
671 }
672 else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
673 (pexp->strName.buf[0] != '?'))
674 {
675 /* Redirect it to the relay-tracing trampoline */
676 fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
677 }
678}

Referenced by OutputLine_def().

◆ OutputLine_stub()

int OutputLine_stub ( FILE file,
EXPORT pexp 
)

Definition at line 242 of file spec2def.c.

243{
244 int i;
245 int bRelay = 0;
246 int bInPrototype = 0;
247
248 /* Workaround for forwarded externs. See here for an explanation:
249 * https://stackoverflow.com/questions/4060143/forwarding-data-in-a-dll */
250 if (gbMSComp &&
251 (pexp->nCallingConvention == CC_EXTERN) &&
252 (pexp->strTarget.buf != NULL) &&
253 (!!ScanToken(pexp->strTarget.buf, '.')))
254 {
255 fprintf(file, "#pragma comment(linker,\"/export:%s%.*s=%.*s,DATA\")\n\n",
256 gpszUnderscore, pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
257 return 0;
258 }
259
260 if (pexp->nCallingConvention != CC_STUB &&
261 (pexp->uFlags & FL_STUB) == 0)
262 {
263 /* Only relay trace stdcall C functions */
264 if (!gbTracing || (pexp->nCallingConvention != CC_STDCALL)
265 || (pexp->uFlags & FL_NORELAY)
266 || (pexp->strName.buf[0] == '?'))
267 {
268 return 0;
269 }
270 bRelay = 1;
271 }
272
273 /* Declare the "real" function */
274 if (bRelay)
275 {
276 fprintf(file, "extern ");
277 bInPrototype = 1;
278 }
279
280 do
281 {
282 if (pexp->uFlags & FL_REGISTER)
283 {
284 /* FIXME: Not sure this is right */
285 fprintf(file, "void ");
286 }
287 else if (pexp->uFlags & FL_RET64)
288 {
289 fprintf(file, "__int64 ");
290 }
291 else
292 {
293 fprintf(file, "int ");
294 }
295
296 if ((giArch == ARCH_X86) &&
298 {
299 fprintf(file, "__stdcall ");
300 }
301
302 /* Check for C++ */
303 if (pexp->strName.buf[0] == '?')
304 {
305 fprintf(file, "stub_function%d(", pexp->nNumber);
306 }
307 else
308 {
309 if (!bRelay || bInPrototype)
310 fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
311 else
312 fprintf(file, "$relaytrace$%.*s(", pexp->strName.len, pexp->strName.buf);
313 }
314
315 for (i = 0; i < pexp->nArgCount; i++)
316 {
317 if (i != 0) fprintf(file, ", ");
318 switch (pexp->anArgs[i])
319 {
320 case ARG_LONG: fprintf(file, "long"); break;
321 case ARG_PTR: fprintf(file, "void*"); break;
322 case ARG_STR: fprintf(file, "char*"); break;
323 case ARG_WSTR: fprintf(file, "wchar_t*"); break;
324 case ARG_DBL: fprintf(file, "double"); break;
325 case ARG_INT64: fprintf(file, "__int64"); break;
326 /* __int128 is not supported on x86, so use a custom type */
327 case ARG_INT128: fprintf(file, "MyInt128"); break;
328 case ARG_FLOAT: fprintf(file, "float"); break;
329 }
330 fprintf(file, " a%d", i);
331 }
332
333 if (bInPrototype)
334 {
335 fprintf(file, ");\n\n");
336 }
337 } while (bInPrototype--);
338
339 if (!bRelay)
340 {
341 fprintf(file, ")\n{\n\tDbgPrint(\"WARNING: calling stub %.*s(",
342 pexp->strName.len, pexp->strName.buf);
343 }
344 else
345 {
346 fprintf(file, ")\n{\n");
347 if (pexp->uFlags & FL_REGISTER)
348 {
349 /* No return value */
350 }
351 else if (pexp->uFlags & FL_RET64)
352 {
353 fprintf(file, "\t__int64 retval;\n");
354 }
355 else
356 {
357 fprintf(file, "\tint retval;\n");
358 }
359 fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s(",
360 pszDllName, pexp->strName.len, pexp->strName.buf);
361 }
362
363 for (i = 0; i < pexp->nArgCount; i++)
364 {
365 if (i != 0) fprintf(file, ",");
366 switch (pexp->anArgs[i])
367 {
368 case ARG_LONG: fprintf(file, "0x%%lx"); break;
369 case ARG_PTR: fprintf(file, "0x%%p"); break;
370 case ARG_STR: fprintf(file, "'%%s'"); break;
371 case ARG_WSTR: fprintf(file, "'%%ws'"); break;
372 case ARG_DBL: fprintf(file, "%%f"); break;
373 case ARG_INT64: fprintf(file, "0x%%\"PRIx64\""); break;
374 case ARG_INT128: fprintf(file, "0x%%\"PRIx64\"-0x%%\"PRIx64\""); break;
375 case ARG_FLOAT: fprintf(file, "%%f"); break;
376 }
377 }
378 fprintf(file, ")\\n\"");
379
380 for (i = 0; i < pexp->nArgCount; i++)
381 {
382 fprintf(file, ", ");
383 switch (pexp->anArgs[i])
384 {
385 case ARG_LONG: case ARG_PTR: case ARG_STR:
386 case ARG_WSTR: case ARG_DBL: case ARG_INT64:
387 fprintf(file, "a%d", i); break;
388 case ARG_INT128:
389 fprintf(file, "a%d.lower, a%d.upper", i, i); break;
390 case ARG_FLOAT:
391 fprintf(file, "a%d", i); break;
392 }
393 }
394 fprintf(file, ");\n");
395
396 if (pexp->nCallingConvention == CC_STUB)
397 {
398 fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName);
399 }
400 else if (bRelay)
401 {
402 if (pexp->uFlags & FL_REGISTER)
403 {
404 fprintf(file,"\t");
405 }
406 else
407 {
408 fprintf(file, "\tretval = ");
409 }
410 fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
411
412 for (i = 0; i < pexp->nArgCount; i++)
413 {
414 if (i != 0) fprintf(file, ", ");
415 fprintf(file, "a%d", i);
416 }
417 fprintf(file, ");\n");
418 }
419
420 if (!bRelay)
421 fprintf(file, "\treturn 0;\n}\n\n");
422 else if ((pexp->uFlags & FL_REGISTER) == 0)
423 {
424 if (pexp->uFlags & FL_RET64)
425 {
426 fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s: retval = 0x%%\"PRIx64\"\\n\", retval);\n",
427 pszDllName, pexp->strName.len, pexp->strName.buf);
428 }
429 else
430 {
431 fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s: retval = 0x%%lx\\n\", retval);\n",
432 pszDllName, pexp->strName.len, pexp->strName.buf);
433 }
434 fprintf(file, "\treturn retval;\n}\n\n");
435 }
436
437 return 1;
438}
int anArgs[30]
Definition: spec2def.c:28
int nArgCount
Definition: spec2def.c:27

Referenced by main().

◆ ParseFile()

EXPORT * ParseFile ( char pcStart,
FILE fileDest,
unsigned cExports 
)

Definition at line 868 of file spec2def.c.

869{
870 EXPORT *pexports;
871 const char *pc, *pcLine;
872 int cLines, nLine;
873 EXPORT exp;
874 int included;
875 unsigned int i;
876
877 *cExports = 0;
878
879 //fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart);
880
881 /* Count the lines */
882 for (cLines = 1, pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), cLines++)
883 {
884 /* Nothing */
885 }
886
887 /* Allocate an array of EXPORT structures */
888 pexports = malloc(cLines * sizeof(EXPORT));
889 if (pexports == NULL)
890 {
891 fprintf(stderr, "ERROR: %s: failed to allocate EXPORT array of %u elements\n", pszSourceFileName, cLines);
892 return NULL;
893 }
894
895 /* Loop all lines */
896 nLine = 1;
897 exp.nNumber = 0;
898 for (pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), nLine++)
899 {
900 pc = pcLine;
901
902 exp.strName.buf = NULL;
903 exp.strName.len = 0;
904 exp.strTarget.buf = NULL;
905 exp.strTarget.len = 0;
906 exp.nArgCount = 0;
907 exp.uFlags = 0;
908 exp.nNumber++;
909 exp.nStartVersion = 0;
910 exp.nEndVersion = 0xFFFFFFFF;
911 exp.bVersionIncluded = 1;
912
913 /* Skip white spaces */
914 while (*pc == ' ' || *pc == '\t') pc++;
915
916 /* Check for line break or comment */
917 if ((*pc == '\r') || (*pc == '\n') ||
918 (*pc == ';') || (*pc == '#'))
919 {
920 continue;
921 }
922
923 /* On EOF we are done */
924 if (*pc == 0)
925 {
926 return pexports;
927 }
928
929 /* Now we should get either an ordinal or @ */
930 if (*pc == '@')
931 {
932 exp.nOrdinal = -1;
933 }
934 else if ((*pc >= '0') && (*pc <= '9'))
935 {
936 char* end;
937 long int number = strtol(pc, &end, 10);
938 if ((*end != ' ') && (*end != '\t'))
939 {
940 Fatal(pszSourceFileName, nLine, pcLine, end, 0, "Unexpected character(s) after ordinal");
941 }
942
943 if ((number < 0) || (number > 0xFFFE))
944 {
945 Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Invalid value for ordinal");
946 }
947
948 exp.nOrdinal = number;
949
950 /* The import lib should contain the ordinal only if -ordinal was specified */
951 if (!gbImportLib)
952 exp.uFlags |= FL_ORDINAL;
953 }
954 else
955 {
956 Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Expected '@' or ordinal");
957 }
958
959 /* Go to next token (type) */
960 if (!(pc = NextToken(pc)))
961 {
962 Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
963 }
964
965 //fprintf(stderr, "info: Token:'%.*s'\n", TokenLength(pc), pc);
966
967 /* Now we should get the type */
968 if (CompareToken(pc, "stdcall"))
969 {
970 exp.nCallingConvention = CC_STDCALL;
971 }
972 else if (CompareToken(pc, "cdecl") ||
973 CompareToken(pc, "varargs"))
974 {
975 exp.nCallingConvention = CC_CDECL;
976 }
977 else if (CompareToken(pc, "fastcall"))
978 {
979 exp.nCallingConvention = CC_FASTCALL;
980 }
981 else if (CompareToken(pc, "thiscall"))
982 {
983 exp.nCallingConvention = CC_THISCALL;
984 }
985 else if (CompareToken(pc, "extern"))
986 {
987 exp.nCallingConvention = CC_EXTERN;
988 }
989 else if (CompareToken(pc, "stub"))
990 {
991 exp.nCallingConvention = CC_STUB;
992 }
993 else
994 {
995 Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Invalid calling convention");
996 }
997
998 /* Go to next token (options or name) */
999 if (!(pc = NextToken(pc)))
1000 {
1001 Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
1002 }
1003
1004 /* Handle options */
1005 included = 1;
1006 while (*pc == '-')
1007 {
1008 if (CompareToken(pc, "-arch="))
1009 {
1010 /* Default to not included */
1011 included = 0;
1012 pc += 5;
1013
1014 /* Look if we are included */
1015 do
1016 {
1017 pc++;
1018 if (CompareToken(pc, pszArchString) ||
1020 {
1021 included = 1;
1022 }
1023
1024 /* Skip to next arch or end */
1025 while (*pc > ',') pc++;
1026 } while (*pc == ',');
1027 }
1028 else if (CompareToken(pc, "-i386"))
1029 {
1030 if (giArch != ARCH_X86) included = 0;
1031 }
1032 else if (CompareToken(pc, "-version="))
1033 {
1034 const char *pcVersionStart = pc + 9;
1035
1036 /* Default to not included */
1037 exp.bVersionIncluded = 0;
1038 pc += 8;
1039
1040 /* Look if we are included */
1041 do
1042 {
1043 unsigned version, endversion;
1044
1045 /* Optionally skip leading '0x' */
1046 pc++;
1047 if ((pc[0] == '0') && (pc[1] == 'x')) pc += 2;
1048
1049 /* Now get the version number */
1050 endversion = version = strtoul(pc, (char**)&pc, 16);
1051
1052 /* Check if it's a range */
1053 if (pc[0] == '+')
1054 {
1055 endversion = 0xFFF;
1056 pc++;
1057 }
1058 else if (pc[0] == '-')
1059 {
1060 /* Optionally skip leading '0x' */
1061 pc++;
1062 if ((pc[0] == '0') && (pc[1] == 'x')) pc += 2;
1063 endversion = strtoul(pc, (char**)&pc, 16);
1064 }
1065
1066 /* Check for degenerate range */
1067 if (version > endversion)
1068 {
1070 nLine,
1071 pcLine,
1072 pcVersionStart,
1073 pc - pcVersionStart,
1074 "Invalid version range");
1075 }
1076
1077 exp.nStartVersion = version;
1078 exp.nEndVersion = endversion;
1079
1080 /* Now compare the range with our version */
1081 if ((guOsVersion >= version) &&
1082 (guOsVersion <= endversion))
1083 {
1084 exp.bVersionIncluded = 1;
1085 }
1086
1087 /* Skip to next arch or end */
1088 while (*pc > ',') pc++;
1089
1090 } while (*pc == ',');
1091 }
1092 else if (CompareToken(pc, "-private"))
1093 {
1094 exp.uFlags |= FL_PRIVATE;
1095 }
1096 else if (CompareToken(pc, "-noname"))
1097 {
1098 exp.uFlags |= FL_ORDINAL | FL_NONAME;
1099 }
1100 else if (CompareToken(pc, "-ordinal"))
1101 {
1102 exp.uFlags |= FL_ORDINAL;
1103 /* GCC doesn't automatically import by ordinal if an ordinal
1104 * is found in the def file. Force it. */
1105 if (gbImportLib && !gbMSComp)
1106 exp.uFlags |= FL_NONAME;
1107 }
1108 else if (CompareToken(pc, "-stub"))
1109 {
1110 exp.uFlags |= FL_STUB;
1111 }
1112 else if (CompareToken(pc, "-norelay"))
1113 {
1114 exp.uFlags |= FL_NORELAY;
1115 }
1116 else if (CompareToken(pc, "-ret64"))
1117 {
1118 exp.uFlags |= FL_RET64;
1119 }
1120 else if (CompareToken(pc, "-register"))
1121 {
1122 exp.uFlags |= FL_REGISTER;
1123 }
1124 else
1125 {
1127 "INFO: %s line %d: Ignored option: '%.*s'\n",
1129 nLine,
1130 TokenLength(pc),
1131 pc);
1132 }
1133
1134 /* Go to next token */
1135 pc = NextToken(pc);
1136 }
1137
1138 //fprintf(stderr, "info: Name:'%.10s'\n", pc);
1139
1140 /* If arch didn't match ours, skip this entry */
1141 if (!included) continue;
1142
1143 /* Get name */
1144 exp.strName.buf = pc;
1145 exp.strName.len = TokenLength(pc);
1146 //DbgPrint("Got name: '%.*s'\n", exp.strName.len, exp.strName.buf);
1147
1148 /* Check for autoname */
1149 if ((exp.strName.len == 1) && (exp.strName.buf[0] == '@'))
1150 {
1151 exp.uFlags |= FL_ORDINAL | FL_NONAME;
1152 }
1153
1154 /* Handle parameters */
1155 exp.nStackBytes = 0;
1156 pc = NextToken(pc);
1157 /* Extern can't have parameters, and it's optional to provide ones for stubs. All other exports must have them */
1158 if (!pc && (exp.nCallingConvention != CC_EXTERN && exp.nCallingConvention != CC_STUB))
1159 {
1160 Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
1161 }
1162
1163 if (pc && (exp.nCallingConvention != CC_EXTERN))
1164 {
1165 /* Verify syntax */
1166 if (*pc++ != '(')
1167 {
1168 Fatal(pszSourceFileName, nLine, pcLine, pc - 1, 0, "Expected '('");
1169 }
1170
1171 /* Skip whitespaces */
1172 while (*pc == ' ' || *pc == '\t') pc++;
1173
1174 exp.nStackBytes = 0;
1175 while (*pc >= '0')
1176 {
1177 if (CompareToken(pc, "long"))
1178 {
1179 exp.nStackBytes += 4;
1180 exp.anArgs[exp.nArgCount] = ARG_LONG;
1181 }
1182 else if (CompareToken(pc, "double"))
1183 {
1184 exp.nStackBytes += 8;
1185 exp.anArgs[exp.nArgCount] = ARG_DBL;
1186 }
1187 else if (CompareToken(pc, "ptr"))
1188 {
1189 exp.nStackBytes += 4; // sizeof(void*) on x86
1190 exp.anArgs[exp.nArgCount] = ARG_PTR;
1191 }
1192 else if (CompareToken(pc, "str"))
1193 {
1194 exp.nStackBytes += 4; // sizeof(void*) on x86
1195 exp.anArgs[exp.nArgCount] = ARG_STR;
1196 }
1197 else if (CompareToken(pc, "wstr"))
1198 {
1199 exp.nStackBytes += 4; // sizeof(void*) on x86
1200 exp.anArgs[exp.nArgCount] = ARG_WSTR;
1201 }
1202 else if (CompareToken(pc, "int64"))
1203 {
1204 exp.nStackBytes += 8;
1205 exp.anArgs[exp.nArgCount] = ARG_INT64;
1206 }
1207 else if (CompareToken(pc, "int128"))
1208 {
1209 exp.nStackBytes += 16;
1210 exp.anArgs[exp.nArgCount] = ARG_INT128;
1211 }
1212 else if (CompareToken(pc, "float"))
1213 {
1214 exp.nStackBytes += 4;
1215 exp.anArgs[exp.nArgCount] = ARG_FLOAT;
1216 }
1217 else
1218 {
1219 Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Unrecognized type");
1220 }
1221
1222 exp.nArgCount++;
1223
1224 /* Go to next parameter */
1225 if (!(pc = NextToken(pc)))
1226 {
1227 Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
1228 }
1229 }
1230
1231 /* Check syntax */
1232 if (*pc++ != ')')
1233 {
1234 Fatal(pszSourceFileName, nLine, pcLine, pc - 1, 0, "Expected ')'");
1235 }
1236
1237 /* Go to next token */
1238 pc = NextToken(pc);
1239 }
1240
1241 /* Handle special stub cases */
1242 if (exp.nCallingConvention == CC_STUB)
1243 {
1244 /* If we got parameters, assume STDCALL */
1245 if (exp.nArgCount != 0)
1246 {
1247 exp.nCallingConvention = CC_STDCALL;
1248 exp.uFlags |= FL_STUB;
1249 }
1250
1251 /* Check for c++ mangled name */
1252 if (exp.strName.buf[0] == '?')
1253 {
1254 //printf("Found c++ mangled name...\n");
1255 //
1256 }
1257 else
1258 {
1259 /* Check for stdcall name */
1260 const char *p = ScanToken(exp.strName.buf, '@');
1261 if (p && (p - exp.strName.buf < exp.strName.len))
1262 {
1263 int i;
1264
1265 /* Truncate the name to before the @ */
1266 exp.strName.len = (int)(p - exp.strName.buf);
1267 if (exp.strName.len < 1)
1268 {
1269 Fatal(pszSourceFileName, nLine, pcLine, p, 1, "Unexpected @");
1270 }
1271 exp.nStackBytes = atoi(p + 1);
1272 exp.nArgCount = exp.nStackBytes / 4;
1273 exp.nCallingConvention = CC_STDCALL;
1274 exp.uFlags |= FL_STUB;
1275 for (i = 0; i < exp.nArgCount; i++)
1276 exp.anArgs[i] = ARG_LONG;
1277 }
1278 }
1279 }
1280
1281 /* Check optional redirection */
1282 if (pc)
1283 {
1284 exp.strTarget.buf = pc;
1285 exp.strTarget.len = TokenLength(pc);
1286
1287 /* Check syntax (end of line) */
1288 if (NextToken(pc))
1289 {
1290 Fatal(pszSourceFileName, nLine, pcLine, NextToken(pc), 0, "Excess token(s) at end of definition");
1291 }
1292
1293 /* Don't relay-trace forwarded functions */
1294 exp.uFlags |= FL_NORELAY;
1295 }
1296 else
1297 {
1298 exp.strTarget.buf = NULL;
1299 exp.strTarget.len = 0;
1300 }
1301
1302 /* Check for no-name without ordinal */
1303 if ((exp.uFlags & FL_ORDINAL) && (exp.nOrdinal == -1))
1304 {
1305 Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
1306 }
1307
1308 /*
1309 * Check for special handling of OLE exports, only when MSVC
1310 * is not used, since otherwise this is handled by MS LINK.EXE.
1311 */
1312 if (!gbMSComp)
1313 {
1314 /* Check whether the current export is not PRIVATE, or has an ordinal */
1315 int bIsNotPrivate = (!gbNotPrivateNoWarn && /*gbImportLib &&*/ !(exp.uFlags & FL_PRIVATE));
1316 int bHasOrdinal = (exp.uFlags & FL_ORDINAL);
1317
1318 /* Check whether the current export is an OLE export, in case any of these tests pass */
1319 if (bIsNotPrivate || bHasOrdinal)
1320 {
1321 for (i = 0; i < ARRAYSIZE(astrOlePrivateExports); ++i)
1322 {
1323 if (strlen(astrOlePrivateExports[i]) == exp.strName.len &&
1324 strncmp(exp.strName.buf, astrOlePrivateExports[i], exp.strName.len) == 0)
1325 {
1326 /* The current export is an OLE export: display the corresponding warning */
1327 if (bIsNotPrivate)
1328 {
1329 fprintf(stderr, "WARNING: %s line %d: Exported symbol '%.*s' should be PRIVATE\n",
1330 pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
1331 }
1332 if (bHasOrdinal)
1333 {
1334 fprintf(stderr, "WARNING: %s line %d: exported symbol '%.*s' should not be assigned an ordinal\n",
1335 pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
1336 }
1337 break;
1338 }
1339 }
1340 }
1341 }
1342
1343 pexports[*cExports] = exp;
1344 (*cExports)++;
1345 gbDebug = 0;
1346 }
1347
1348 return pexports;
1349}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static const WCHAR version[]
Definition: asmname.c:66
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GLuint GLuint end
Definition: gl.h:1545
GLfloat GLfloat p
Definition: glext.h:8902
#define stdout
Definition: stdio.h:99
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
static unsigned int number
Definition: dsound.c:1479
DWORD exp
Definition: msg.c:16058
const char * NextLine(const char *pc)
Definition: spec2def.c:179
int gbDebug
Definition: spec2def.c:75
const char * NextToken(const char *pc)
Definition: spec2def.c:201
void Fatal(const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format,...)
Definition: spec2def.c:851
int CompareToken(const char *token, const char *comparand)
Definition: spec2def.c:154
static const char * astrOlePrivateExports[]
Definition: spec2def.c:126
#define ARRAYSIZE(a)
Definition: spec2def.c:12

Referenced by main().

◆ PrintName()

void PrintName ( FILE fileDest,
EXPORT pexp,
PSTRING  pstr,
int  fDeco 
)

Definition at line 547 of file spec2def.c.

548{
549 const char *pcName = pstr->buf;
550 int nNameLength = pstr->len;
551 const char* pcDot, *pcAt;
552 char namebuffer[19];
553
554 if ((nNameLength == 1) && (pcName[0] == '@'))
555 {
556 sprintf(namebuffer, "ordinal%d", pexp->nOrdinal);
557 pcName = namebuffer;
558 nNameLength = strlen(namebuffer);
559 }
560
561 /* Check for non-x86 first */
562 if (giArch != ARCH_X86)
563 {
564 /* Does the string already have stdcall decoration? */
565 pcAt = ScanToken(pcName, '@');
566 if (pcAt && (pcAt < (pcName + nNameLength)) && (pcName[0] == '_'))
567 {
568 /* Skip leading underscore and remove trailing decoration */
569 pcName++;
570 nNameLength = (int)(pcAt - pcName);
571 }
572
573 /* Print the undecorated function name */
574 fprintf(fileDest, "%.*s", nNameLength, pcName);
575 }
576 else if (fDeco &&
577 ((pexp->nCallingConvention == CC_STDCALL) ||
579 {
580 /* Beware with C++ exports */
581 int is_cpp = pcName[0] == '?';
582
583 /* Scan for a dll forwarding dot */
584 pcDot = ScanToken(pcName, '.');
585 if (pcDot)
586 {
587 /* First print the dll name, followed by a dot */
588 nNameLength = (int)(pcDot - pcName);
589 fprintf(fileDest, "%.*s.", nNameLength, pcName);
590
591 /* Now the actual function name */
592 pcName = pcDot + 1;
593 nNameLength = pexp->strTarget.len - nNameLength - 1;
594 }
595
596 /* Does the string already have decoration? */
597 pcAt = ScanToken(pcName, '@');
598 if (pcAt && (pcAt < (pcName + nNameLength)))
599 {
600 /* On GCC, we need to remove the leading stdcall underscore, but not for C++ exports */
601 if (!gbMSComp && !is_cpp && (pexp->nCallingConvention == CC_STDCALL))
602 {
603 pcName++;
604 nNameLength--;
605 }
606
607 /* Print the already decorated function name */
608 fprintf(fileDest, "%.*s", nNameLength, pcName);
609 }
610 else
611 {
612 /* Print the prefix, but skip it for (GCC && stdcall) */
613 if (gbMSComp || (pexp->nCallingConvention != CC_STDCALL))
614 {
615 fprintf(fileDest, "%c", pexp->nCallingConvention == CC_FASTCALL ? '@' : '_');
616 }
617
618 /* Print the name with trailing decoration */
619 fprintf(fileDest, "%.*s@%d", nNameLength, pcName, pexp->nStackBytes);
620 }
621 }
622 else
623 {
624 /* Print the undecorated function name */
625 fprintf(fileDest, "%.*s", nNameLength, pcName);
626 }
627}

Referenced by OutputLine_def_GCC(), OutputLine_def_MS(), and Defragment::Start().

◆ ScanToken()

const char * ScanToken ( const char token,
char  chr 
)

Definition at line 168 of file spec2def.c.

169{
170 while (!IsSeparator(*token))
171 {
172 if (*token == chr) return token;
173 token++;
174 }
175 return 0;
176}

Referenced by OutputLine_asmstub(), OutputLine_def(), OutputLine_def_GCC(), OutputLine_def_MS(), OutputLine_stub(), ParseFile(), and PrintName().

◆ TokenLength()

int TokenLength ( const char pc)

Definition at line 191 of file spec2def.c.

192{
193 int length = 0;
194
195 while (!IsSeparator(*pc++)) length++;
196
197 return length;
198}
GLuint GLsizei GLsizei * length
Definition: glext.h:6040

Referenced by Fatalv(), ParseFile(), and SmpParseToken().

◆ usage()

void usage ( void  )

Definition at line 1397 of file spec2def.c.

1398{
1399 printf("syntax: spec2def [<options> ...] <spec file>\n"
1400 "Possible options:\n"
1401 " -h --help print this help screen\n"
1402 " -l=<file> generate an asm lib stub\n"
1403 " -d=<file> generate a def file\n"
1404 " -s=<file> generate a stub file\n"
1405 " --ms MSVC compatibility\n"
1406 " -n=<name> name of the dll\n"
1407 " --implib generate a def file for an import library\n"
1408 " --no-private-warnings suppress warnings about symbols that should be -private\n"
1409 " -a=<arch> set architecture to <arch> (i386, x86_64, arm, arm64)\n"
1410 " --with-tracing generate wine-like \"+relay\" trace trampolines (needs -s)\n");
1411}
#define printf
Definition: freeldr.h:94

Referenced by main().

Variable Documentation

◆ astrCallingConventions

const char* astrCallingConventions[]
Initial value:
=
{
"STDCALL",
"CDECL",
"FASTCALL",
"THISCALL",
"EXTERN"
}

Definition at line 112 of file spec2def.c.

◆ astrOlePrivateExports

const char* astrOlePrivateExports[]
static
Initial value:
=
{
"DllCanUnloadNow",
"DllGetClassObject",
"DllGetClassFactoryFromClassString",
"DllGetDocumentation",
"DllInitialize",
"DllInstall",
"DllRegisterServer",
"DllRegisterServerEx",
"DllRegisterServerExW",
"DllUnload",
"DllUnregisterServer",
"RasCustomDeleteEntryNotify",
"RasCustomDial",
"RasCustomDialDlg",
"RasCustomEntryDlg",
}

Definition at line 126 of file spec2def.c.

Referenced by ParseFile().

◆ gbDebug

int gbDebug

Definition at line 75 of file spec2def.c.

Referenced by ParseFile().

◆ gbImportLib

int gbImportLib = 0

Definition at line 66 of file spec2def.c.

Referenced by main(), OutputLine_def(), OutputLine_def_GCC(), OutputLine_def_MS(), and ParseFile().

◆ gbMSComp

int gbMSComp = 0

Definition at line 65 of file spec2def.c.

Referenced by main(), OutputLine_def(), OutputLine_stub(), ParseFile(), and PrintName().

◆ gbNotPrivateNoWarn

int gbNotPrivateNoWarn = 0

Definition at line 67 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ gbTracing

int gbTracing = 0

◆ giArch

◆ gpszUnderscore

char* gpszUnderscore = ""

Definition at line 74 of file spec2def.c.

Referenced by main(), OutputLine_asmstub(), and OutputLine_stub().

◆ guOsVersion

unsigned guOsVersion = 0x502

Definition at line 76 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString

char* pszArchString = "i386"

Definition at line 70 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString2

char* pszArchString2

Definition at line 71 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszDllName

char* pszDllName = NULL

Definition at line 73 of file spec2def.c.

Referenced by main(), and OutputLine_stub().

◆ pszSourceFileName

char* pszSourceFileName = NULL

Definition at line 72 of file spec2def.c.

Referenced by main(), and ParseFile().