chiark / gitweb /
Initial revision
[ssr] / StraySrc / SDLS / cdll / c / dllbinder
1 /*
2  * dllbinder.c
3  *
4  * Entry point and things for the DLL Binder
5  *
6  * © 1994-1998 Straylight
7  */
8
9 /*----- Licensing note ----------------------------------------------------*
10  *
11  * This file is part of Straylight's Dynamic Linking System (SDLS)
12  *
13  * SDLS is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * SDLS is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with SDLS.  If not, write to the Free Software Foundation,
25  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include "_time.h"
32
33 #include "error.h"
34 #include "hashtable.h"
35 #include "decode.h"
36 #include "readdef.h"
37 #include "binding.h"
38 #include "cstub.h"
39 #include "extentry.h"
40
41 extern char cright[];
42
43 static void cdll_readSymbols(char *p,void *handle)
44 {
45   decode(handle,p);
46 }
47
48 static void cdll_writeName(char *p,void *handle)
49 {
50   FILE *fp=handle;
51   fprintf(fp,"  %s\n",p);
52 }
53
54 static void cdll_notsubset(char *p)
55 {
56   error(LOSTSYM,p);
57 }
58
59 int main(int argc,char *argv[])
60 {
61
62   enum
63   {
64     NOWT=0,
65     DEF=1,
66     STUB=2,
67     BINDING=4,
68     OBJECT=8,
69     EXTERN=16,
70     PATH=32
71   };
72
73   char *deffile=0;                      /* Name of definition file      */
74   char *stubfile=0;                     /* Name of stublib file         */
75   char *bindfile=0;                     /* Name of binding file         */
76   char *extfile=0;                      /* Name of external veneer file */
77   char *dllfile=0;                      /* Name of DLL file to use      */
78   int helped=0;                         /* Have we given help?          */
79   hashtable objfiles;                   /* Names of objects specified   */
80   hashtable symbols;                    /* Symbols defined in deffile   */
81   hashtable objsym;                     /* Symbols defined in objects   */
82   hashtable veneered;                   /* Private symbols to veneer    */
83   int createdef=0;                      /* Do we create the def file?   */
84   int whatnext=DEF;                     /* What thing do we read next   */
85   int override=NOWT;                    /* What was the override tag?   */
86   int done=NOWT;                        /* What things we've done       */
87   int i;                                /* Loop counter                 */
88   int process=1;                        /* Do we process this time?     */
89   int apptbl=0;                         /* Is this for app extension?   */
90
91   error_setProgName(argv[0]);           /* Set up the program name      */
92
93   objfiles=hash_create();
94   symbols=hash_create();
95   veneered=hash_create();
96   objsym=hash_create();
97   if (!objfiles || !symbols || !objsym)
98     error(NOMEM);
99
100   for (i=1;i<argc;i++)
101   {
102     if (!cistrcmp(argv[i],"-help"))
103     {
104       printf(
105
106 "%s: (help)\n"
107 "\n"
108 "Straylight Dynamic Link Library building system\n"
109 "  version %s\n"
110 "  %s\n"
111 "\n"
112 "Usage:\n"
113 "\n"
114 "  For a reminder of command syntax:\n"
115 "    %s -help\n"
116 "\n"
117 "  To create a definition file from object files:\n"
118 "    %s [[-def] <deffile>] -obj <objfile> [<objfile>]...\n"
119 "\n"
120 "  To create stub libraries and DLL headers:\n"
121 "    %s [[-def] <deffile>] [[-stub] <stublib>] [[-hdr] <header>]\n"
122 "      [-file <dllpath>]\n"
123 "\n"
124 "  To create application entry tables and extension stubs:\n"
125 "    %s -app [[-def] <deffile>] [[-stub] <stublib>] [[-hdr] <header>]\n"
126 "\n"
127 "  To create external function entry points for module tasks:\n"
128 "    %s [[-def] <deffile>] [-ext <extstub>]\n"
129 "\n"
130 "  All option switches may be abbreviated to single characters except\n"
131 "  -help.\n"
132 "\n",
133
134              error_progname(),
135              _time,
136              cright,
137              error_progname(),
138              error_progname(),
139              error_progname(),
140              error_progname(),
141              error_progname());
142       helped=1;
143     }
144     else if (argv[i][0]=='-')           /* Is it an option tag?         */
145     {
146       switch (argv[i][1])               /* Find second character        */
147       {
148         case 'a':
149           apptbl=1;
150           break;
151         case 'd':
152           override=DEF;
153           break;
154         case 's':
155           override=STUB;
156           break;
157         case 'h':
158           override=BINDING;
159           break;
160         case 'e':
161           override=EXTERN;
162           break;
163         case 'o':
164           override=OBJECT;
165           break;
166         case 'f':
167           override=PATH;
168           break;
169         default:
170           error(BADTAG,argv[i]);
171           break;
172       }
173       if (override & done)
174       {
175         error(DUPOPT,argv[i]);
176         process=0;
177         override=NOWT;
178       }
179     }
180     else
181     {
182       switch (override==NOWT ? whatnext : override)
183       {
184         case NOWT:
185           error(SILLYOPT,argv[i]);
186           break;
187         case DEF:
188           deffile=argv[i];
189           done|=DEF;
190           break;
191         case STUB:
192           if (createdef)
193           {
194             error(SORBNOBJ);
195             process=0;
196           }
197           else
198           {
199             stubfile=argv[i];
200             done|=STUB;
201           }
202           break;
203         case BINDING:
204           if (createdef)
205           {
206             error(SORBNOBJ);
207             process=0;
208           }
209           else
210           {
211             bindfile=argv[i];
212             done|=BINDING;
213           }
214           break;
215         case EXTERN:
216           if (createdef)
217           {
218             error(SORBNOBJ);
219             process=0;
220           }
221           else
222           {
223             extfile=argv[i];
224             done|=EXTERN;
225           }
226           break;
227         case OBJECT:
228           if (bindfile || stubfile)
229           {
230             error(SORBNOBJ);
231             process=0;
232           }
233           else if (apptbl)
234           {
235             error(APPNOEXT);
236             process=0;
237           }
238           else
239           {
240             if (!hash_add(objfiles,argv[i]))
241               error(NOMEM);
242             createdef=1;
243           }
244           break;
245         case PATH:
246           dllfile=argv[i];
247           break;
248       }
249       override=0;
250     }
251     if (!(done & DEF))
252       whatnext=DEF;
253     else if (createdef)
254       whatnext=OBJECT;
255     else if (!(done & STUB))
256       whatnext=STUB;
257     else if (!(done & BINDING))
258       whatnext=BINDING;
259     else
260       whatnext=NOWT;
261   }
262   if (!deffile)
263   {
264     if (!helped)
265       error(NODEF);
266     process=0;
267   }
268   if (!createdef && !bindfile && !stubfile && !extfile && !helped)
269     error(EASY);
270   else if (!process)
271   {
272     if (!helped)
273       error(BADCMDLINE);
274   }
275   else if (createdef)
276   {
277     FILE *fp=fopen(deffile,"w");
278     if (!fp)
279       error(NOOPENOUT,deffile);
280     else
281     {
282       hash_enumerate(objfiles,cdll_readSymbols,objsym);
283       fprintf(fp,";\n"
284                  "; cdll definition file for <name>\n"
285                  ";\n"
286                  "\n"
287                  "name \"<name>\"\n"
288                  "  version 1.00\n"
289                  "  author \"<author>\"\n"
290                  "\n"
291                  "; --- Exported symbols ---\n"
292                  "\n"
293                  "exports\n"
294                  "{\n");
295       hash_enumerate(objsym,cdll_writeName,fp);
296       fprintf(fp,"}\n"
297                  "\n"
298                  "; --- Object files ---\n"
299                  "\n"
300                  "objects\n"
301                  "{\n");
302       hash_enumerate(objfiles,cdll_writeName,fp);
303       fprintf(fp,"}\n");
304       fclose(fp);
305     }
306   }
307   else
308   {
309     readdef_info i;
310     i.sym=symbols;
311     i.obj=objfiles;
312     i.vsym=veneered;
313     i.apptbl=apptbl;
314     i.dllpath=dllfile;
315     readdef(deffile,&i);
316     hash_enumerate(objfiles,cdll_readSymbols,objsym);
317     hash_subset(objsym,symbols,cdll_notsubset);
318     hash_subset(objsym,veneered,cdll_notsubset);
319     if (bindfile)
320       binding(bindfile,&i,objsym);
321     if (stubfile)
322       cstub(stubfile,&i,objsym);
323     if (extfile)
324       extentry(extfile,&i,objsym);
325   }
326   error_show();
327   return (error_returnCode());
328 }