Release 940804
[wine/gsoc-2012-control.git] / tools / build.c.save
blob9b0eadaff9769a63f997a130f6a5a03bf6583bf3
1 static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <ctype.h>
9 #ifdef linux
10 #define UTEXTSEL 0x23
11 #endif
12 #if defined(__NetBSD__) || defined(__FreeBSD__)
13 #define UTEXTSEL 0x1f
14 #endif
16 #define VARTYPE_BYTE    0
17 #define VARTYPE_SIGNEDWORD      0
18 #define VARTYPE_WORD    1
19 #define VARTYPE_LONG    2
20 #define VARTYPE_FARPTR  3
22 #define FUNCTYPE_PASCAL 16
23 #define FUNCTYPE_C      17
24 #define FUNCTYPE_REG    19
26 #define EQUATETYPE_ABS  18
27 #define TYPE_RETURN     20
29 #define MAX_ORDINALS    1024
31 typedef struct ordinal_definition_s
33     int valid;
34     int type;
35     char export_name[80];
36     void *additional_data;
37 } ORDDEF;
39 typedef struct ordinal_variable_definition_s
41     int n_values;
42     int *values;
43 } ORDVARDEF;
45 typedef struct ordinal_function_definition_s
47     int n_args_16;
48     int arg_types_16[16];
49     int arg_16_offsets[16];
50     int arg_16_size;
51     char internal_name[80];
52     int n_args_32;
53     int arg_indices_32[16];
54 } ORDFUNCDEF;
56 typedef struct ordinal_return_definition_s
58     int arg_size;
59     int ret_value;
60 } ORDRETDEF;
62 ORDDEF OrdinalDefinitions[MAX_ORDINALS];
64 char LowerDLLName[80];
65 char UpperDLLName[80];
66 int Limit;
67 int DLLId;
68 FILE *SpecFp;
70 char *ParseBuffer = NULL;
71 char *ParseNext;
72 char ParseSaveChar;
73 int Line;
75 int IsNumberString(char *s)
77     while (*s != '\0')
78         if (!isdigit(*s++))
79             return 0;
81     return 1;
84 char *strlower(char *s)
86     char *p;
87     
88     for(p = s; *p != '\0'; p++)
89         *p = tolower(*p);
91     return s;
94 char *strupper(char *s)
96     char *p;
97     
98     for(p = s; *p != '\0'; p++)
99         *p = toupper(*p);
101     return s;
104 int stricmp(char *s1, char *s2)
106     if (strlen(s1) != strlen(s2))
107         return -1;
108     
109     while (*s1 != '\0')
110         if (*s1++ != *s2++)
111             return -1;
112     
113     return 0;
116 char *
117 GetTokenInLine(void)
119     char *p;
120     char *token;
122     if (ParseNext != ParseBuffer)
123     {
124         if (ParseSaveChar == '\0')
125             return NULL;
126         *ParseNext = ParseSaveChar;
127     }
128     
129     /*
130      * Remove initial white space.
131      */
132     for (p = ParseNext; isspace(*p); p++)
133         ;
134     
135     if (*p == '\0')
136         return NULL;
137     
138     /*
139      * Find end of token.
140      */
141     token = p++;
142     if (*token != '(' && *token != ')')
143         while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
144             p++;
145     
146     ParseSaveChar = *p;
147     ParseNext = p;
148     *p = '\0';
150     return token;
153 char *
154 GetToken(void)
156     char *token;
158     if (ParseBuffer == NULL)
159     {
160         ParseBuffer = malloc(512);
161         ParseNext = ParseBuffer;
162         Line++;
163         while (1)
164         {
165             if (fgets(ParseBuffer, 511, SpecFp) == NULL)
166                 return NULL;
167             if (ParseBuffer[0] != '#')
168                 break;
169         }
170     }
172     while ((token = GetTokenInLine()) == NULL)
173     {
174         ParseNext = ParseBuffer;
175         Line++;
176         while (1)
177         {
178             if (fgets(ParseBuffer, 511, SpecFp) == NULL)
179                 return NULL;
180             if (ParseBuffer[0] != '#')
181                 break;
182         }
183     }
185     return token;
189 ParseVariable(int ordinal, int type)
191     ORDDEF *odp;
192     ORDVARDEF *vdp;
193     char export_name[80];
194     char *token;
195     char *endptr;
196     int *value_array;
197     int n_values;
198     int value_array_size;
199     
200     strcpy(export_name, GetToken());
202     token = GetToken();
203     if (*token != '(')
204     {
205         fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
206         exit(1);
207     }
209     n_values = 0;
210     value_array_size = 25;
211     value_array = malloc(sizeof(*value_array) * value_array_size);
212     
213     while ((token = GetToken()) != NULL)
214     {
215         if (*token == ')')
216             break;
218         value_array[n_values++] = strtol(token, &endptr, 0);
219         if (n_values == value_array_size)
220         {
221             value_array_size += 25;
222             value_array = realloc(value_array, 
223                                   sizeof(*value_array) * value_array_size);
224         }
225         
226         if (endptr == NULL || *endptr != '\0')
227         {
228             fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
229                     token);
230             exit(1);
231         }
232     }
233     
234     if (token == NULL)
235     {
236         fprintf(stderr, "%d: End of file in variable declaration\n", Line);
237         exit(1);
238     }
240     if (ordinal >= MAX_ORDINALS)
241     {
242         fprintf(stderr, "%d: Ordinal number too large\n", Line);
243         exit(1);
244     }
245     
246     odp = &OrdinalDefinitions[ordinal];
247     odp->valid = 1;
248     odp->type = type;
249     strcpy(odp->export_name, export_name);
250     
251     vdp = malloc(sizeof(*vdp));
252     odp->additional_data = vdp;
253     
254     vdp->n_values = n_values;
255     vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
257     return 0;
261 ParseExportFunction(int ordinal, int type)
263     char *token;
264     ORDDEF *odp;
265     ORDFUNCDEF *fdp;
266     int arg_types[16];
267     int i;
268     int arg_num;
269     int current_offset;
270     int arg_size;
271         
272     
273     if (ordinal >= MAX_ORDINALS)
274     {
275         fprintf(stderr, "%d: Ordinal number too large\n", Line);
276         exit(1);
277     }
278     
279     odp = &OrdinalDefinitions[ordinal];
280     strcpy(odp->export_name, GetToken());
281     odp->valid = 1;
282     odp->type = type;
283     fdp = malloc(sizeof(*fdp));
284     odp->additional_data = fdp;
286     token = GetToken();
287     if (*token != '(')
288     {
289         fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
290         exit(1);
291     }
293     fdp->arg_16_size = 0;
294     for (i = 0; i < 16; i++)
295     {
296         token = GetToken();
297         if (*token == ')')
298             break;
300         if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
301         {
302             fdp->arg_types_16[i] = VARTYPE_WORD;
303             fdp->arg_16_size += 2;
304             fdp->arg_16_offsets[i] = 2;
305         }
306         else if (stricmp(token, "s_byte") == 0 || 
307                  stricmp(token, "s_word") == 0)
308         {
309             fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
310             fdp->arg_16_size += 2;
311             fdp->arg_16_offsets[i] = 2;
312         }
313         else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
314         {
315             fdp->arg_types_16[i] = VARTYPE_LONG;
316             fdp->arg_16_size += 4;
317             fdp->arg_16_offsets[i] = 4;
318         }
319         else if (stricmp(token, "ptr") == 0)
320         {
321             fdp->arg_types_16[i] = VARTYPE_FARPTR;
322             fdp->arg_16_size += 4;
323             fdp->arg_16_offsets[i] = 4;
324         }
325         else
326         {
327             fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
328             exit(1);
329         }
330     }
331     fdp->n_args_16 = i;
333     if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
334     {
335         current_offset = 0;
336         for (i--; i >= 0; i--)
337         {
338             arg_size = fdp->arg_16_offsets[i];
339             fdp->arg_16_offsets[i] = current_offset;
340             current_offset += arg_size;
341         }
342     }
343     else
344     {
345         current_offset = 0;
346         for (i = 0; i < fdp->n_args_16; i++)
347         {
348             arg_size = fdp->arg_16_offsets[i];
349             fdp->arg_16_offsets[i] = current_offset;
350             current_offset += arg_size;
351         }
352     }
354     strcpy(fdp->internal_name, GetToken());
355     token = GetToken();
356     if (*token != '(')
357     {
358         fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
359         exit(1);
360     }
361     for (i = 0; i < 16; i++)
362     {
363         token = GetToken();
364         if (*token == ')')
365             break;
367         fdp->arg_indices_32[i] = atoi(token);
368         if (fdp->arg_indices_32[i] < 1 || 
369             fdp->arg_indices_32[i] > fdp->n_args_16)
370         {
371             fprintf(stderr, "%d: Bad argument index %d\n", Line,
372                     fdp->arg_indices_32[i]);
373             exit(1);
374         }
375     }
376     fdp->n_args_32 = i;
378     return 0;
382 ParseEquate(int ordinal)
384     ORDDEF *odp;
385     char *token;
386     char *endptr;
387     int value;
388     
389     if (ordinal >= MAX_ORDINALS)
390     {
391         fprintf(stderr, "%d: Ordinal number too large\n", Line);
392         exit(1);
393     }
394     
395     odp = &OrdinalDefinitions[ordinal];
396     strcpy(odp->export_name, GetToken());
398     token = GetToken();
399     value = strtol(token, &endptr, 0);
400     if (endptr == NULL || *endptr != '\0')
401     {
402         fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
403                 token);
404         exit(1);
405     }
407     odp->valid = 1;
408     odp->type = EQUATETYPE_ABS;
409     odp->additional_data = (void *) value;
411     return 0;
415 ParseReturn(int ordinal)
417     ORDDEF *odp;
418     ORDRETDEF *rdp;
419     char *token;
420     char *endptr;
421     int value;
422     
423     if (ordinal >= MAX_ORDINALS)
424     {
425         fprintf(stderr, "%d: Ordinal number too large\n", Line);
426         exit(1);
427     }
429     rdp = malloc(sizeof(*rdp));
430     
431     odp = &OrdinalDefinitions[ordinal];
432     strcpy(odp->export_name, GetToken());
433     odp->valid = 1;
434     odp->type = TYPE_RETURN;
435     odp->additional_data = rdp;
437     token = GetToken();
438     rdp->arg_size = strtol(token, &endptr, 0);
439     if (endptr == NULL || *endptr != '\0')
440     {
441         fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
442                 token);
443         exit(1);
444     }
446     token = GetToken();
447     rdp->ret_value = strtol(token, &endptr, 0);
448     if (endptr == NULL || *endptr != '\0')
449     {
450         fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
451                 token);
452         exit(1);
453     }
455     return 0;
459 ParseOrdinal(int ordinal)
461     char *token;
462     
463     token = GetToken();
464     if (token == NULL)
465     {
466         fprintf(stderr, "%d: Expected type after ordinal\n", Line);
467         exit(1);
468     }
470     if (stricmp(token, "byte") == 0)
471         return ParseVariable(ordinal, VARTYPE_BYTE);
472     else if (stricmp(token, "word") == 0)
473         return ParseVariable(ordinal, VARTYPE_WORD);
474     else if (stricmp(token, "long") == 0)
475         return ParseVariable(ordinal, VARTYPE_LONG);
476     else if (stricmp(token, "c") == 0)
477         return ParseExportFunction(ordinal, FUNCTYPE_C);
478     else if (stricmp(token, "p") == 0)
479         return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
480     else if (stricmp(token, "pascal") == 0)
481         return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
482     else if (stricmp(token, "register") == 0)
483         return ParseExportFunction(ordinal, FUNCTYPE_REG);
484     else if (stricmp(token, "equate") == 0)
485         return ParseEquate(ordinal);
486     else if (stricmp(token, "return") == 0)
487         return ParseReturn(ordinal);
488     else
489     {
490         fprintf(stderr, 
491                 "%d: Expected type after ordinal, found '%s' instead\n",
492                 Line, token);
493         exit(1);
494     }
498 ParseTopLevel(void)
500     char *token;
501     
502     while ((token = GetToken()) != NULL)
503     {
504         if (stricmp(token, "name") == 0)
505         {
506             strcpy(LowerDLLName, GetToken());
507             strlower(LowerDLLName);
509             strcpy(UpperDLLName, LowerDLLName);
510             strupper(UpperDLLName);
511         }
512         else if (stricmp(token, "id") == 0)
513         {
514             token = GetToken();
515             if (!IsNumberString(token))
516             {
517                 fprintf(stderr, "%d: Expected number after id\n", Line);
518                 exit(1);
519             }
520             
521             DLLId = atoi(token);
522         }
523         else if (stricmp(token, "length") == 0)
524         {
525             token = GetToken();
526             if (!IsNumberString(token))
527             {
528                 fprintf(stderr, "%d: Expected number after length\n", Line);
529                 exit(1);
530             }
532             Limit = atoi(token);
533         }
534         else if (IsNumberString(token))
535         {
536             int ordinal;
537             int rv;
538             
539             ordinal = atoi(token);
540             if ((rv = ParseOrdinal(ordinal)) < 0)
541                 return rv;
542         }
543         else
544         {
545             fprintf(stderr, 
546                     "%d: Expected name, id, length or ordinal\n", Line);
547             exit(1);
548         }
549     }
551     return 0;
554 void
555 OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
557     ORDVARDEF *vdp;
558     int i;
560     fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
562     vdp = odp->additional_data;
563     for (i = 0; i < vdp->n_values; i++)
564     {
565         if ((i & 7) == 0)
566             fprintf(fp, "\t%s\t", storage);
567             
568         fprintf(fp, "%d", vdp->values[i]);
569         
570         if ((i & 7) == 7 || i == vdp->n_values - 1)
571             fprintf(fp, "\n");
572         else
573             fprintf(fp, ", ");
574     }
575     fprintf(fp, "\n");
578 main(int argc, char **argv)
580     ORDDEF *odp;
581     ORDFUNCDEF *fdp;
582     ORDRETDEF *rdp;
583     FILE *fp;
584     char filename[80];
585     char buffer[80];
586     char *p;
587     int i;
588     
589     if (argc < 2)
590     {
591         fprintf(stderr, "usage: build SPECNAME\n");
592         exit(1);
593     }
595     SpecFp = fopen(argv[1], "r");
596     if (SpecFp == NULL)
597     {
598         fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
599         exit(1);
600     }
602     ParseTopLevel();
604     sprintf(filename, "dll_%s.S", LowerDLLName);
605     fp = fopen(filename, "w");
607     fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
608     fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
609     fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
610     fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
611     fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
612     fprintf(fp, "\tjmp\t_CallTo32\n\n");
614     odp = OrdinalDefinitions;
615     for (i = 0; i <= Limit; i++, odp++)
616     {
617         fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
619         if (!odp->valid)
620         {
621             fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
622 #ifdef BOB_SAYS_NO
623             fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
624             fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
625 #endif
626             fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
627             fprintf(fp, "\tpushw\t$0\n");
628             fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
629         }
630         else
631         {
632             fdp = odp->additional_data;
633             rdp = odp->additional_data;
634             
635             switch (odp->type)
636             {
637               case EQUATETYPE_ABS:
638                 fprintf(fp, "_%s_Ordinal_%d = %d\n\n", 
639                         UpperDLLName, i, (int) odp->additional_data);
640                 break;
642               case VARTYPE_BYTE:
643                 OutputVariableCode(fp, ".byte", odp);
644                 break;
646               case VARTYPE_WORD:
647                 OutputVariableCode(fp, ".word", odp);
648                 break;
650               case VARTYPE_LONG:
651                 OutputVariableCode(fp, ".long", odp);
652                 break;
654               case TYPE_RETURN:
655                 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
656                 fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
657                 fprintf(fp, "\tmovw\t$%d,%%dx\n", 
658                         (rdp->ret_value >> 16) & 0xffff);
659                 fprintf(fp, "\t.byte\t0x66\n");
660                 if (rdp->arg_size != 0)
661                     fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
662                 else
663                     fprintf(fp, "\tlret\n");
664                 break;
666               case FUNCTYPE_REG:
667                 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
668                 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
669                 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
670                 fprintf(fp, "\tpushl\t$0\n");                   /* cr2     */
671                 fprintf(fp, "\tpushl\t$0\n");                   /* oldmask */
672                 fprintf(fp, "\tpushl\t$0\n");                   /* i387    */
673                 fprintf(fp, "\tpushw\t$0\n");                   /* __ssh   */
674                 fprintf(fp, "\tpushw\t%%ss\n");                 /* ss      */
675                 fprintf(fp, "\tpushl\t%%esp\n");                /* esp     */
676                 fprintf(fp, "\tpushfl\n");                      /* eflags  */
677                 fprintf(fp, "\tpushw\t$0\n");                   /* __csh   */
678                 fprintf(fp, "\tpushw\t%%cs\n");                 /* cs      */
679                 fprintf(fp, "\tpushl\t$0\n");                   /* eip     */
680                 fprintf(fp, "\tpushl\t$0\n");                   /* err     */
681                 fprintf(fp, "\tpushl\t$0\n");                   /* trapno  */
682                 fprintf(fp, "\tpushal\n");                      /* AX, ... */
683                 fprintf(fp, "\tpushw\t$0\n");                   /* __dsh   */
684                 fprintf(fp, "\tpushw\t%%ds\n");                 /* ds      */
685                 fprintf(fp, "\tpushw\t$0\n");                   /* __esh   */
686                 fprintf(fp, "\tpushw\t%%es\n");                 /* es      */
687                 fprintf(fp, "\tpushw\t$0\n");                   /* __fsh   */
688                 fprintf(fp, "\tpushw\t%%fs\n");                 /* fs      */
689                 fprintf(fp, "\tpushw\t$0\n");                   /* __gsh   */
690                 fprintf(fp, "\tpushw\t%%gs\n");                 /* gs      */
691                 fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
692                 fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
693                 fprintf(fp, "\tpushl\t88(%%ebp)\n");
694                 fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
695                 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
696                 fprintf(fp, "\tpushw\t$92\n");
697                 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
698 #if 0
699                 fprintf(fp, "\tpushw\t%%ax\n");
700                 fprintf(fp, "\tpushw\t%%cx\n");
701                 fprintf(fp, "\tpushw\t%%dx\n");
702                 fprintf(fp, "\tpushw\t%%bx\n");
703                 fprintf(fp, "\tpushw\t%%sp\n");
704                 fprintf(fp, "\tpushw\t%%bp\n");
705                 fprintf(fp, "\tpushw\t%%si\n");
706                 fprintf(fp, "\tpushw\t%%di\n");
707                 fprintf(fp, "\tpushw\t%%ds\n");
708                 fprintf(fp, "\tpushw\t%%es\n");
709                 fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
710                 fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
711                 fprintf(fp, "\tpushl\t20(%%ebp)\n");
712                 fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
713                 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
714                 fprintf(fp, "\tpushw\t$24\n");
715                 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
716 #endif
717                 break;
719               case FUNCTYPE_PASCAL:
720                 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
721 #ifdef BOB_SAYS_NO
722                 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
723                 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
724 #endif
725                 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
726                 fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
727                 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
728                 break;
729                 
730               case FUNCTYPE_C:
731               default:
732                 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
733 #ifdef BOB_SAYS_NO
734                 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
735                 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
736 #endif
737                 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
738                 fprintf(fp, "\tpushw\t$0\n");
739                 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
740                 break;
741             }
742         }
743     }
745     fclose(fp);
747 #ifndef SHORTNAMES
748     sprintf(filename, "dll_%s_tab.c", LowerDLLName);
749 #else
750     sprintf(filename, "dtb_%s.c", LowerDLLName);
751 #endif
752     fp = fopen(filename, "w");
754     fprintf(fp, "#include <stdio.h>\n");
755     fprintf(fp, "#include <stdlib.h>\n");
756     fprintf(fp, "#include \042dlls.h\042\n\n");
758     for (i = 0; i <= Limit; i++)
759     {
760         fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
761     }
762     
763     odp = OrdinalDefinitions;
764     for (i = 0; i <= Limit; i++, odp++)
765     {
766         if (odp->valid && 
767             (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
768              odp->type == FUNCTYPE_REG))
769         {
770             fdp = odp->additional_data;
771             fprintf(fp, "extern int %s();\n", fdp->internal_name);
772         }
773     }
774     
775     fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n", 
776             UpperDLLName, Limit + 1);
777     fprintf(fp, "{\n");
778     odp = OrdinalDefinitions;
779     for (i = 0; i <= Limit; i++, odp++)
780     {
781         fdp = odp->additional_data;
783         if (!odp->valid)
784             odp->type = -1;
785         
786         switch (odp->type)
787         {
788           case FUNCTYPE_PASCAL:
789           case FUNCTYPE_REG:
790             fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
791             fprintf(fp, "\042%s\042, ", odp->export_name);
792             fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
793 #ifdef WINESTAT
794             fprintf(fp, "0, ");
795 #endif      
796             fprintf(fp, "%d, ", fdp->n_args_32);
797             if (fdp->n_args_32 > 0)
798             {
799                 int argnum;
800                 
801                 fprintf(fp, "\n      {\n");
802                 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
803                 {
804                     fprintf(fp, "        { %d, %d },\n",
805                             fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
806                             fdp->arg_types_16[argnum]);
807                 }
808                 fprintf(fp, "      }\n    ");
809             }
810             fprintf(fp, "}, \n");
811             break;
812                 
813           case FUNCTYPE_C:
814             fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
815             fprintf(fp, "\042%s\042, ", odp->export_name);
816             fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
817 #ifdef WINESTAT
818             fprintf(fp, "0, ");
819 #endif      
820             fprintf(fp, "%d, ", fdp->n_args_32);
821             if (fdp->n_args_32 > 0)
822             {
823                 int argnum;
824                 
825                 fprintf(fp, "\n      {\n");
826                 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
827                 {
828                     fprintf(fp, "        { %d, %d },\n",
829                             fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
830                             fdp->arg_types_16[argnum]);
831                 }
832                 fprintf(fp, "      }\n    ");
833             }
834             fprintf(fp, "}, \n");
835             break;
836             
837           default:
838             fprintf(fp, "    { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", 
839                     UTEXTSEL, UpperDLLName, i);
840             break;
841         }
842     }
843     fprintf(fp, "};\n");
845     fclose(fp);