708 lines
14 KiB
C
708 lines
14 KiB
C
![]() |
/*
|
||
|
* Copyright Robert J. Amstadt, 1993
|
||
|
*/
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
#define VARTYPE_BYTE 0
|
||
|
#define VARTYPE_SIGNEDWORD 0
|
||
|
#define VARTYPE_WORD 1
|
||
|
#define VARTYPE_LONG 2
|
||
|
#define VARTYPE_FARPTR 3
|
||
|
|
||
|
#define FUNCTYPE_PASCAL 16
|
||
|
#define FUNCTYPE_C 17
|
||
|
#define FUNCTYPE_REG 19
|
||
|
|
||
|
#define EQUATETYPE_ABS 18
|
||
|
|
||
|
#define MAX_ORDINALS 1024
|
||
|
|
||
|
typedef struct ordinal_definition_s
|
||
|
{
|
||
|
int valid;
|
||
|
int type;
|
||
|
char export_name[80];
|
||
|
void *additional_data;
|
||
|
} ORDDEF;
|
||
|
|
||
|
typedef struct ordinal_variable_definition_s
|
||
|
{
|
||
|
int n_values;
|
||
|
int *values;
|
||
|
} ORDVARDEF;
|
||
|
|
||
|
typedef struct ordinal_function_definition_s
|
||
|
{
|
||
|
int n_args_16;
|
||
|
int arg_types_16[16];
|
||
|
int arg_16_offsets[16];
|
||
|
int arg_16_size;
|
||
|
char internal_name[80];
|
||
|
int n_args_32;
|
||
|
int arg_indices_32[16];
|
||
|
} ORDFUNCDEF;
|
||
|
|
||
|
ORDDEF OrdinalDefinitions[MAX_ORDINALS];
|
||
|
|
||
|
char LowerDLLName[80];
|
||
|
char UpperDLLName[80];
|
||
|
int Limit;
|
||
|
int DLLId;
|
||
|
FILE *SpecFp;
|
||
|
|
||
|
char *ParseBuffer = NULL;
|
||
|
char *ParseNext;
|
||
|
char ParseSaveChar;
|
||
|
int Line;
|
||
|
|
||
|
int IsNumberString(char *s)
|
||
|
{
|
||
|
while (*s != '\0')
|
||
|
if (!isdigit(*s++))
|
||
|
return 0;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
char *strlower(char *s)
|
||
|
{
|
||
|
char *p;
|
||
|
|
||
|
for(p = s; *p != '\0'; p++)
|
||
|
*p = tolower(*p);
|
||
|
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
char *strupper(char *s)
|
||
|
{
|
||
|
char *p;
|
||
|
|
||
|
for(p = s; *p != '\0'; p++)
|
||
|
*p = toupper(*p);
|
||
|
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
int stricmp(char *s1, char *s2)
|
||
|
{
|
||
|
if (strlen(s1) != strlen(s2))
|
||
|
return -1;
|
||
|
|
||
|
while (*s1 != '\0')
|
||
|
if (*s1++ != *s2++)
|
||
|
return -1;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
GetTokenInLine(void)
|
||
|
{
|
||
|
char *p;
|
||
|
char *token;
|
||
|
|
||
|
if (ParseNext != ParseBuffer)
|
||
|
{
|
||
|
if (ParseSaveChar == '\0')
|
||
|
return NULL;
|
||
|
*ParseNext = ParseSaveChar;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Remove initial white space.
|
||
|
*/
|
||
|
for (p = ParseNext; isspace(*p); p++)
|
||
|
;
|
||
|
|
||
|
if (*p == '\0')
|
||
|
return NULL;
|
||
|
|
||
|
/*
|
||
|
* Find end of token.
|
||
|
*/
|
||
|
token = p++;
|
||
|
if (*token != '(' && *token != ')')
|
||
|
while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
|
||
|
p++;
|
||
|
|
||
|
ParseSaveChar = *p;
|
||
|
ParseNext = p;
|
||
|
*p = '\0';
|
||
|
|
||
|
return token;
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
GetToken(void)
|
||
|
{
|
||
|
char *token;
|
||
|
|
||
|
if (ParseBuffer == NULL)
|
||
|
{
|
||
|
ParseBuffer = malloc(512);
|
||
|
ParseNext = ParseBuffer;
|
||
|
Line++;
|
||
|
if (fgets(ParseBuffer, 511, SpecFp) == NULL)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
while ((token = GetTokenInLine()) == NULL)
|
||
|
{
|
||
|
ParseNext = ParseBuffer;
|
||
|
Line++;
|
||
|
if (fgets(ParseBuffer, 511, SpecFp) == NULL)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return token;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ParseVariable(int ordinal, int type)
|
||
|
{
|
||
|
ORDDEF *odp;
|
||
|
ORDVARDEF *vdp;
|
||
|
char export_name[80];
|
||
|
char *token;
|
||
|
char *endptr;
|
||
|
int *value_array;
|
||
|
int n_values;
|
||
|
int value_array_size;
|
||
|
|
||
|
strcpy(export_name, GetToken());
|
||
|
|
||
|
token = GetToken();
|
||
|
if (*token != '(')
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
n_values = 0;
|
||
|
value_array_size = 25;
|
||
|
value_array = malloc(sizeof(*value_array) * value_array_size);
|
||
|
|
||
|
while ((token = GetToken()) != NULL)
|
||
|
{
|
||
|
if (*token == ')')
|
||
|
break;
|
||
|
|
||
|
value_array[n_values++] = strtol(token, &endptr, 0);
|
||
|
if (n_values == value_array_size)
|
||
|
{
|
||
|
value_array_size += 25;
|
||
|
value_array = realloc(value_array,
|
||
|
sizeof(*value_array) * value_array_size);
|
||
|
}
|
||
|
|
||
|
if (endptr == NULL || *endptr != '\0')
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
|
||
|
token);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (token == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "%d: End of file in variable declaration\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if (ordinal >= MAX_ORDINALS)
|
||
|
{
|
||
|
fprintf(stderr, "%d: Ordinal number too large\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
odp = &OrdinalDefinitions[ordinal];
|
||
|
odp->valid = 1;
|
||
|
odp->type = type;
|
||
|
strcpy(odp->export_name, export_name);
|
||
|
|
||
|
vdp = malloc(sizeof(*vdp));
|
||
|
odp->additional_data = vdp;
|
||
|
|
||
|
vdp->n_values = n_values;
|
||
|
vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ParseExportFunction(int ordinal, int type)
|
||
|
{
|
||
|
char *token;
|
||
|
ORDDEF *odp;
|
||
|
ORDFUNCDEF *fdp;
|
||
|
int arg_types[16];
|
||
|
int i;
|
||
|
int arg_num;
|
||
|
int current_offset;
|
||
|
int arg_size;
|
||
|
|
||
|
|
||
|
if (ordinal >= MAX_ORDINALS)
|
||
|
{
|
||
|
fprintf(stderr, "%d: Ordinal number too large\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
odp = &OrdinalDefinitions[ordinal];
|
||
|
strcpy(odp->export_name, GetToken());
|
||
|
odp->valid = 1;
|
||
|
odp->type = type;
|
||
|
fdp = malloc(sizeof(*fdp));
|
||
|
odp->additional_data = fdp;
|
||
|
|
||
|
token = GetToken();
|
||
|
if (*token != '(')
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
fdp->arg_16_size = 0;
|
||
|
for (i = 0; i < 16; i++)
|
||
|
{
|
||
|
token = GetToken();
|
||
|
if (*token == ')')
|
||
|
break;
|
||
|
|
||
|
if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
|
||
|
{
|
||
|
fdp->arg_types_16[i] = VARTYPE_WORD;
|
||
|
fdp->arg_16_size += 2;
|
||
|
fdp->arg_16_offsets[i] = 2;
|
||
|
}
|
||
|
else if (stricmp(token, "s_byte") == 0 ||
|
||
|
stricmp(token, "s_word") == 0)
|
||
|
{
|
||
|
fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
|
||
|
fdp->arg_16_size += 2;
|
||
|
fdp->arg_16_offsets[i] = 2;
|
||
|
}
|
||
|
else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
|
||
|
{
|
||
|
fdp->arg_types_16[i] = VARTYPE_LONG;
|
||
|
fdp->arg_16_size += 4;
|
||
|
fdp->arg_16_offsets[i] = 4;
|
||
|
}
|
||
|
else if (stricmp(token, "ptr") == 0)
|
||
|
{
|
||
|
fdp->arg_types_16[i] = VARTYPE_FARPTR;
|
||
|
fdp->arg_16_size += 4;
|
||
|
fdp->arg_16_offsets[i] = 4;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
fdp->n_args_16 = i;
|
||
|
|
||
|
if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
|
||
|
{
|
||
|
current_offset = 0;
|
||
|
for (i--; i >= 0; i--)
|
||
|
{
|
||
|
arg_size = fdp->arg_16_offsets[i];
|
||
|
fdp->arg_16_offsets[i] = current_offset;
|
||
|
current_offset += arg_size;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
current_offset = 0;
|
||
|
for (i = 0; i < fdp->n_args_16; i++)
|
||
|
{
|
||
|
arg_size = fdp->arg_16_offsets[i];
|
||
|
fdp->arg_16_offsets[i] = current_offset;
|
||
|
current_offset += arg_size;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
strcpy(fdp->internal_name, GetToken());
|
||
|
token = GetToken();
|
||
|
if (*token != '(')
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
|
||
|
exit(1);
|
||
|
}
|
||
|
for (i = 0; i < 16; i++)
|
||
|
{
|
||
|
token = GetToken();
|
||
|
if (*token == ')')
|
||
|
break;
|
||
|
|
||
|
fdp->arg_indices_32[i] = atoi(token);
|
||
|
if (fdp->arg_indices_32[i] < 1 ||
|
||
|
fdp->arg_indices_32[i] > fdp->n_args_16)
|
||
|
{
|
||
|
fprintf(stderr, "%d: Bad argument index %d\n", Line,
|
||
|
fdp->arg_indices_32[i]);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
fdp->n_args_32 = i;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ParseEquate(int ordinal)
|
||
|
{
|
||
|
ORDDEF *odp;
|
||
|
char *token;
|
||
|
char *endptr;
|
||
|
int value;
|
||
|
|
||
|
if (ordinal >= MAX_ORDINALS)
|
||
|
{
|
||
|
fprintf(stderr, "%d: Ordinal number too large\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
odp = &OrdinalDefinitions[ordinal];
|
||
|
strcpy(odp->export_name, GetToken());
|
||
|
|
||
|
token = GetToken();
|
||
|
value = strtol(token, &endptr, 0);
|
||
|
if (endptr == NULL || *endptr != '\0')
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
|
||
|
token);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
odp->valid = 1;
|
||
|
odp->type = EQUATETYPE_ABS;
|
||
|
odp->additional_data = (void *) value;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ParseOrdinal(int ordinal)
|
||
|
{
|
||
|
char *token;
|
||
|
|
||
|
token = GetToken();
|
||
|
if (token == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected type after ordinal\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if (stricmp(token, "byte") == 0)
|
||
|
return ParseVariable(ordinal, VARTYPE_BYTE);
|
||
|
else if (stricmp(token, "word") == 0)
|
||
|
return ParseVariable(ordinal, VARTYPE_WORD);
|
||
|
else if (stricmp(token, "long") == 0)
|
||
|
return ParseVariable(ordinal, VARTYPE_LONG);
|
||
|
else if (stricmp(token, "c") == 0)
|
||
|
return ParseExportFunction(ordinal, FUNCTYPE_C);
|
||
|
else if (stricmp(token, "p") == 0)
|
||
|
return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
|
||
|
else if (stricmp(token, "pascal") == 0)
|
||
|
return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
|
||
|
else if (stricmp(token, "register") == 0)
|
||
|
return ParseExportFunction(ordinal, FUNCTYPE_REG);
|
||
|
else if (stricmp(token, "equate") == 0)
|
||
|
return ParseEquate(ordinal);
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr,
|
||
|
"%d: Expected type after ordinal, found '%s' instead\n",
|
||
|
Line, token);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ParseTopLevel(void)
|
||
|
{
|
||
|
char *token;
|
||
|
|
||
|
while ((token = GetToken()) != NULL)
|
||
|
{
|
||
|
if (stricmp(token, "name") == 0)
|
||
|
{
|
||
|
strcpy(LowerDLLName, GetToken());
|
||
|
strlower(LowerDLLName);
|
||
|
|
||
|
strcpy(UpperDLLName, LowerDLLName);
|
||
|
strupper(UpperDLLName);
|
||
|
}
|
||
|
else if (stricmp(token, "id") == 0)
|
||
|
{
|
||
|
token = GetToken();
|
||
|
if (!IsNumberString(token))
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected number after id\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
DLLId = atoi(token);
|
||
|
}
|
||
|
else if (stricmp(token, "length") == 0)
|
||
|
{
|
||
|
token = GetToken();
|
||
|
if (!IsNumberString(token))
|
||
|
{
|
||
|
fprintf(stderr, "%d: Expected number after length\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
Limit = atoi(token);
|
||
|
}
|
||
|
else if (IsNumberString(token))
|
||
|
{
|
||
|
int ordinal;
|
||
|
int rv;
|
||
|
|
||
|
ordinal = atoi(token);
|
||
|
if ((rv = ParseOrdinal(ordinal)) < 0)
|
||
|
return rv;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr,
|
||
|
"%d: Expected name, id, length or ordinal\n", Line);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
|
||
|
{
|
||
|
ORDVARDEF *vdp;
|
||
|
int i;
|
||
|
|
||
|
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
|
||
|
|
||
|
vdp = odp->additional_data;
|
||
|
for (i = 0; i < vdp->n_values; i++)
|
||
|
{
|
||
|
if ((i & 7) == 0)
|
||
|
fprintf(fp, "\t%s\t", storage);
|
||
|
|
||
|
fprintf(fp, "%d", vdp->values[i]);
|
||
|
|
||
|
if ((i & 7) == 7 || i == vdp->n_values - 1)
|
||
|
fprintf(fp, "\n");
|
||
|
else
|
||
|
fprintf(fp, ", ");
|
||
|
}
|
||
|
fprintf(fp, "\n");
|
||
|
}
|
||
|
|
||
|
main(int argc, char **argv)
|
||
|
{
|
||
|
ORDDEF *odp;
|
||
|
ORDFUNCDEF *fdp;
|
||
|
FILE *fp;
|
||
|
char filename[80];
|
||
|
char buffer[80];
|
||
|
char *p;
|
||
|
int i;
|
||
|
|
||
|
if (argc < 2)
|
||
|
{
|
||
|
fprintf(stderr, "usage: build SPECNAME\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
SpecFp = fopen(argv[1], "r");
|
||
|
if (SpecFp == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
ParseTopLevel();
|
||
|
|
||
|
sprintf(filename, "dll_%s.S", LowerDLLName);
|
||
|
fp = fopen(filename, "w");
|
||
|
|
||
|
fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
|
||
|
fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
|
||
|
fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
|
||
|
fprintf(fp, "\tjmp\t_CallTo32\n\n");
|
||
|
|
||
|
odp = OrdinalDefinitions;
|
||
|
for (i = 0; i <= Limit; i++, odp++)
|
||
|
{
|
||
|
fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
|
||
|
|
||
|
if (!odp->valid)
|
||
|
{
|
||
|
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
|
||
|
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
|
||
|
fprintf(fp, "\tpushw\t$0\n");
|
||
|
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fdp = odp->additional_data;
|
||
|
|
||
|
switch (odp->type)
|
||
|
{
|
||
|
case EQUATETYPE_ABS:
|
||
|
fprintf(fp, "_%s_Ordinal_%d = %d\n\n",
|
||
|
UpperDLLName, i, (int) odp->additional_data);
|
||
|
break;
|
||
|
|
||
|
case VARTYPE_BYTE:
|
||
|
OutputVariableCode(fp, ".byte", odp);
|
||
|
break;
|
||
|
|
||
|
case VARTYPE_WORD:
|
||
|
OutputVariableCode(fp, ".word", odp);
|
||
|
break;
|
||
|
|
||
|
case VARTYPE_LONG:
|
||
|
OutputVariableCode(fp, ".long", odp);
|
||
|
break;
|
||
|
|
||
|
case FUNCTYPE_REG:
|
||
|
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
|
||
|
fprintf(fp, "\tpushw\t%%ax\n");
|
||
|
fprintf(fp, "\tpushw\t%%cx\n");
|
||
|
fprintf(fp, "\tpushw\t%%dx\n");
|
||
|
fprintf(fp, "\tpushw\t%%bx\n");
|
||
|
fprintf(fp, "\tpushw\t%%sp\n");
|
||
|
fprintf(fp, "\tpushw\t%%bp\n");
|
||
|
fprintf(fp, "\tpushw\t%%si\n");
|
||
|
fprintf(fp, "\tpushw\t%%di\n");
|
||
|
fprintf(fp, "\tpushw\t%%ds\n");
|
||
|
fprintf(fp, "\tpushw\t%%es\n");
|
||
|
fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
|
||
|
fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
|
||
|
fprintf(fp, "\tpushl\t20(%%ebp)\n");
|
||
|
fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
|
||
|
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
|
||
|
fprintf(fp, "\tpushw\t$24\n");
|
||
|
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
|
||
|
break;
|
||
|
|
||
|
case FUNCTYPE_PASCAL:
|
||
|
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
|
||
|
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
|
||
|
fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
|
||
|
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
|
||
|
break;
|
||
|
|
||
|
case FUNCTYPE_C:
|
||
|
default:
|
||
|
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
|
||
|
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
|
||
|
fprintf(fp, "\tpushw\t$0\n");
|
||
|
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fclose(fp);
|
||
|
|
||
|
sprintf(filename, "dll_%s_tab.c", LowerDLLName);
|
||
|
fp = fopen(filename, "w");
|
||
|
|
||
|
fprintf(fp, "#include <stdio.h>\n");
|
||
|
fprintf(fp, "#include <stdlib.h>\n");
|
||
|
fprintf(fp, "#include \042dlls.h\042\n\n");
|
||
|
|
||
|
for (i = 0; i <= Limit; i++)
|
||
|
{
|
||
|
fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
|
||
|
}
|
||
|
|
||
|
odp = OrdinalDefinitions;
|
||
|
for (i = 0; i <= Limit; i++, odp++)
|
||
|
{
|
||
|
if (odp->valid &&
|
||
|
(odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
|
||
|
odp->type == FUNCTYPE_REG))
|
||
|
{
|
||
|
fdp = odp->additional_data;
|
||
|
fprintf(fp, "extern int %s();\n", fdp->internal_name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n",
|
||
|
UpperDLLName, Limit + 1);
|
||
|
fprintf(fp, "{\n");
|
||
|
odp = OrdinalDefinitions;
|
||
|
for (i = 0; i <= Limit; i++, odp++)
|
||
|
{
|
||
|
fdp = odp->additional_data;
|
||
|
|
||
|
if (!odp->valid)
|
||
|
odp->type = -1;
|
||
|
|
||
|
switch (odp->type)
|
||
|
{
|
||
|
case FUNCTYPE_PASCAL:
|
||
|
case FUNCTYPE_REG:
|
||
|
fprintf(fp, " { 0x23, %s_Ordinal_%d, ", UpperDLLName, i);
|
||
|
fprintf(fp, "\042%s\042, ", odp->export_name);
|
||
|
fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
|
||
|
fprintf(fp, "%d, ", fdp->n_args_32);
|
||
|
if (fdp->n_args_32 > 0)
|
||
|
{
|
||
|
int argnum;
|
||
|
|
||
|
fprintf(fp, "\n {\n");
|
||
|
for (argnum = 0; argnum < fdp->n_args_32; argnum++)
|
||
|
{
|
||
|
fprintf(fp, " { %d, %d },\n",
|
||
|
fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
|
||
|
fdp->arg_types_16[argnum]);
|
||
|
}
|
||
|
fprintf(fp, " }\n ");
|
||
|
}
|
||
|
fprintf(fp, "}, \n");
|
||
|
break;
|
||
|
|
||
|
case FUNCTYPE_C:
|
||
|
fprintf(fp, " { 0x23, %s_Ordinal_%d, ", UpperDLLName, i);
|
||
|
fprintf(fp, "\042%s\042, ", odp->export_name);
|
||
|
fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
|
||
|
fprintf(fp, "%d, ", fdp->n_args_32);
|
||
|
if (fdp->n_args_32 > 0)
|
||
|
{
|
||
|
int argnum;
|
||
|
|
||
|
fprintf(fp, "\n {\n");
|
||
|
for (argnum = 0; argnum < fdp->n_args_32; argnum++)
|
||
|
{
|
||
|
fprintf(fp, " { %d, %d },\n",
|
||
|
fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
|
||
|
fdp->arg_types_16[argnum]);
|
||
|
}
|
||
|
fprintf(fp, " }\n ");
|
||
|
}
|
||
|
fprintf(fp, "}, \n");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf(fp, " { 0x23, %s_Ordinal_%d, \042\042, NULL },\n",
|
||
|
UpperDLLName, i);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
fprintf(fp, "};\n");
|
||
|
|
||
|
fclose(fp);
|
||
|
}
|
||
|
|