re-order some parts of the code so that the msg and rect are only allocated once.
[AROS.git] / tools / parseoffsets / header.c
blobe73c6d2111135ca059ed4bac0671f892f7aef0a9
1 /*
2 Copyright © 2019, The AROS Development Team. All rights reserved.
3 */
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdarg.h>
8 #include <stdlib.h>
9 #include <stdbool.h>
11 #include "parsendkoffsets.h"
12 #include "header.h"
14 typedef struct hnode {
15 struct hnode * next;
16 struct hnode * prev;
17 char *id;
18 } hnode_t;
20 struct headerSet
22 hnode_t hs_Node;
23 hnode_t *headerStructs;
26 struct headerMatch
28 char *headerStruct;
29 bool headerSkip;
30 char *headerfile;
33 hnode_t *headerSets = NULL;
35 struct headerMatch knownStructs[] =
37 { "ExecBase", false, "exec/execbase.h" },
39 { "DateStamp", false, "dos/dos.h" },
40 { "FileInfoBlock", false, "dos/dos.h" },
41 { "InfoData", false, "dos/dos.h" },
43 { "DosLibrary", false, "dos/dosextens.h" },
44 { "RootNode", false, "dos/dosextens.h" },
45 { "CLIInfo", false, "dos/dosextens.h" },
46 { "DosInfo", false, "dos/dosextens.h" },
47 { "Process", false, "dos/dosextens.h" },
48 { "CommandLineInterface", false, "dos/dosextens.h" },
49 { "DevProcs", false, "dos/dosextens.h" },
50 { "FileHandle", true, "dos/dosextens.h" },
51 { "FileLock", false, "dos/dosextens.h" },
52 { "DosList", false, "dos/dosextens.h" },
53 { "DeviceList", false, "dos/dosextens.h" },
54 { "DevInfo", false, "dos/dosextens.h" },
55 { "AssignList", false, "dos/dosextens.h" },
56 { "DosPacket", false, "dos/dosextens.h" },
57 { "StandardPacket", false, "dos/dosextens.h" },
58 { "Segment", false, "dos/dosextens.h" },
59 { "ErrorString", false, "dos/dosextens.h" },
61 { "AChain", false, "dos/dosasl.h" },
62 { "AnchorPath", false, "dos/dosasl.h" },
64 { "AmigaGuideHost", false, "libraries/amigaguide.h" },
65 { "AmigaGuideMsg", false, "libraries/amigaguide.h" },
66 { "NewAmigaGuide", false, "libraries/amigaguide.h" },
67 { "XRef", false, "libraries/amigaguide.h" },
68 { "opFindHost", false, "libraries/amigaguide.h" },
69 { "opNodeIO", false, "libraries/amigaguide.h" },
70 { "opExpungeNode", false, "libraries/amigaguide.h" },
72 { "DateTime", false, "dos/datetime.h" },
74 {NULL, true, NULL }
77 void nodeaddtail(hnode_t *nodefirst, hnode_t *node)
79 hnode_t * current = nodefirst;
80 while (current->next != NULL) {
81 current = current->next;
83 if (verbose)
85 printf ("Adding node @ %p after %p\n", node, current);
87 current->next = node;
88 node->prev = current;
89 node->next = NULL;
92 void noderem(hnode_t *node)
94 hnode_t * prev, *next;
95 prev = node->prev;
96 next = node->next;
98 next->prev = prev;
99 prev->next = next;
101 node->prev = NULL;
102 node->next = NULL;
105 hnode_t *nodefind(hnode_t *nodefirst, char *id)
107 hnode_t * current = nodefirst;
108 while (current) {
109 if (0 == strncmp(id, current->id, strlen(id)))
110 return current;
111 current = current->next;
113 return NULL;
116 void addSDKHeaderStruct(char *sdkheaderset, char *structname)
118 struct headerSet *header_node = NULL;
119 hnode_t *structnode = NULL;
121 if (headerSets)
122 header_node = (struct headerSet *)nodefind(headerSets, sdkheaderset);
123 if (!header_node)
125 if (verbose)
127 printf ("registering new header-set %s\n", sdkheaderset);
129 header_node = malloc(sizeof(struct headerSet));
130 header_node->hs_Node.id = malloc(strlen(sdkheaderset) + 1);
131 memcpy(header_node->hs_Node.id, sdkheaderset, strlen(sdkheaderset));
132 header_node->hs_Node.id[strlen(sdkheaderset)] = '\0';
133 header_node->hs_Node.next = NULL;
134 header_node->hs_Node.prev = NULL;
135 header_node->headerStructs = NULL;
137 if (!headerSets)
139 headerSets = &header_node->hs_Node;
140 if (verbose)
142 printf ("first header-set registered (= %p)\n", headerSets);
145 else
146 nodeaddtail(headerSets, &header_node->hs_Node);
149 if (header_node->headerStructs)
150 structnode = nodefind(header_node->headerStructs, structname);
151 if (!structnode)
153 if (verbose)
155 printf ("registering new %s header-set struct %s\n", header_node->hs_Node.id, structname);
157 structnode = malloc(sizeof(hnode_t));
158 structnode->id = malloc(strlen(structname) + 1);
159 memcpy(structnode->id, structname, strlen(structname));
160 structnode->id[strlen(structname)] = '\0';
161 structnode->next = NULL;
162 structnode->prev = NULL;
164 if (!header_node->headerStructs)
166 header_node->headerStructs = structnode;
167 if (verbose)
169 printf ("first struct registered (= %p)\n", structnode);
172 else
173 nodeaddtail(header_node->headerStructs, structnode);
177 char *findStructHeader (char *sdkdir, char *structname)
179 char *headerFilename = NULL;
180 int i;
182 if (sdkdir)
184 if (verbose)
186 printf ("Searching in '%s' for definition of '%s'\n", sdkdir, structname);
189 for (i = 0; knownStructs[i].headerStruct != NULL; i++)
191 if (!strcmp(knownStructs[i].headerStruct, structname) && (!knownStructs[i].headerSkip))
192 return knownStructs[i].headerfile;
194 return headerFilename;
197 void writeHeaderMakefile(char *gendir, char *bindir)
199 char *Makefilename = NULL;
200 FILE *Makefilefile = NULL;
201 FILE *Settestfile = NULL;
202 char *Settestfilename = NULL;
204 makefullpath(gendir);
205 if (strcmp(gendir, bindir))
206 makefullpath(bindir);
208 Makefilename = malloc(strlen(gendir) + strlen("Makefile") + 2);
209 if (Makefilename)
211 sprintf(Makefilename, "%s/Makefile", gendir);
213 Makefilefile = fopen(Makefilename, "w");
214 if (!Makefilefile)
216 printf ("Failed to open '%s'\n", Makefilename);
217 return;
219 printBanner(Makefilefile, "#");
220 fprintf(Makefilefile, "include $(SRCDIR)/config/aros.cfg\n");
222 if (headerSets)
224 struct headerSet *header_node = (struct headerSet *)headerSets;
225 char *structFileName = malloc(LINELENGTH);
227 /* Pass 1: generate recipes for the individual structure test targets */
228 while (header_node) {
229 if (header_node->headerStructs)
231 hnode_t * current = header_node->headerStructs;
232 while (current) {
233 // Write rules for this struct's tests
234 sprintf(structFileName, "test-struct_%s", current->id);
235 fprintf(Makefilefile, " \n%s/%s.o : %s/%s.c\n\t@$(ECHO) \"Compiling $(notdir %s).c\"\n\t@$(strip $(TARGET_CC) $(TARGET_SYSROOT) $(CFLAGS) $(CPPFLAGS)) -c $< -o $@\n", gendir, structFileName, gendir, structFileName, structFileName);
237 fprintf(Makefilefile, " \n%s/%s : %s/%s.o\n\t@$(ECHO) \"Linking $(notdir %s)\"\n\t@$(strip $(TARGET_CC) $(TARGET_SYSROOT) $(TARGET_LDFLAGS)) $< -o $@\n", bindir, structFileName, gendir, structFileName, structFileName);
239 current = current->next;
242 header_node = (struct headerSet *)header_node->hs_Node.next;
245 /* Pass 2: generate header-set targets & scripts */
246 header_node = (struct headerSet *)headerSets;
247 while (header_node) {
248 if (header_node->headerStructs)
250 hnode_t * current = header_node->headerStructs;
252 Settestfilename = malloc(strlen(bindir) + strlen(header_node->hs_Node.id) + 12);
253 fprintf(Makefilefile, "\ntest-sdk-%s-genfiles :", header_node->hs_Node.id);
254 if (Settestfilename)
256 sprintf(Settestfilename, "%s/run-%s-tests", bindir, header_node->hs_Node.id);
257 Settestfile = fopen(Settestfilename, "w");
259 while (current) {
260 // Write rules for this struct's tests
261 sprintf(structFileName, "%s/test-struct_%s", bindir, current->id);
262 fprintf(Makefilefile, " %s", structFileName);
263 if (Settestfile)
264 fprintf(Settestfile, "test-struct_%s\n", current->id);
266 current = current->next;
268 fprintf(Makefilefile, "\n");
269 if (Settestfile)
270 fclose(Settestfile);
271 if (Settestfilename)
272 free(Settestfilename);
274 header_node = (struct headerSet *)header_node->hs_Node.next;
277 /* Pass 3: generate main targets & scripts */
278 Settestfilename = malloc(strlen(bindir) + 15);
279 fprintf(Makefilefile, "\ntest-sdk-headers-genfiles :");
280 header_node = (struct headerSet *)headerSets;
281 if (Settestfilename)
283 sprintf(Settestfilename, "%s/run-sdk-tests", bindir);
284 Settestfile = fopen(Settestfilename, "w");
286 while (header_node) {
287 if (header_node->headerStructs)
289 fprintf(Makefilefile, " test-sdk-%s-genfiles", header_node->hs_Node.id);
290 if (Settestfile)
291 fprintf(Settestfile, "c:execute run-%s-tests\n", header_node->hs_Node.id);
293 header_node = (struct headerSet *)header_node->hs_Node.next;
295 if (Settestfile)
296 fclose(Settestfile);
297 fprintf(Makefilefile, "\n");
298 if (Settestfilename)
299 free(Settestfilename);
300 if (structFileName)
301 free(structFileName);
303 fclose(Makefilefile);
304 free(Makefilename);