1
0
mirror of https://github.com/deadw00d/AROS.git synced 2025-12-07 22:14:08 +00:00
Files
AROS-v0/tools/parseoffsets/header.c
Matthias Rustler 82d8fd11a1 tools: detabbed
2021-05-02 14:02:02 +02:00

308 lines
12 KiB
C

/*
Copyright (C) 2019, The AROS Development Team. All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdbool.h>
#include "parsendkoffsets.h"
#include "header.h"
typedef struct hnode {
struct hnode * next;
struct hnode * prev;
char *id;
} hnode_t;
struct headerSet
{
hnode_t hs_Node;
hnode_t *headerStructs;
};
struct headerMatch
{
char *headerStruct;
bool headerSkip;
char *headerfile;
};
hnode_t *headerSets = NULL;
struct headerMatch knownStructs[] =
{
{ "ExecBase", false, "exec/execbase.h" },
{ "DateStamp", false, "dos/dos.h" },
{ "FileInfoBlock", false, "dos/dos.h" },
{ "InfoData", false, "dos/dos.h" },
{ "DosLibrary", false, "dos/dosextens.h" },
{ "RootNode", false, "dos/dosextens.h" },
{ "CLIInfo", false, "dos/dosextens.h" },
{ "DosInfo", false, "dos/dosextens.h" },
{ "Process", false, "dos/dosextens.h" },
{ "CommandLineInterface", false, "dos/dosextens.h" },
{ "DevProcs", false, "dos/dosextens.h" },
{ "FileHandle", true, "dos/dosextens.h" },
{ "FileLock", false, "dos/dosextens.h" },
{ "DosList", false, "dos/dosextens.h" },
{ "DeviceList", false, "dos/dosextens.h" },
{ "DevInfo", false, "dos/dosextens.h" },
{ "AssignList", false, "dos/dosextens.h" },
{ "DosPacket", false, "dos/dosextens.h" },
{ "StandardPacket", false, "dos/dosextens.h" },
{ "Segment", false, "dos/dosextens.h" },
{ "ErrorString", false, "dos/dosextens.h" },
{ "AChain", false, "dos/dosasl.h" },
{ "AnchorPath", false, "dos/dosasl.h" },
{ "AmigaGuideHost", false, "libraries/amigaguide.h" },
{ "AmigaGuideMsg", false, "libraries/amigaguide.h" },
{ "NewAmigaGuide", false, "libraries/amigaguide.h" },
{ "XRef", false, "libraries/amigaguide.h" },
{ "opFindHost", false, "libraries/amigaguide.h" },
{ "opNodeIO", false, "libraries/amigaguide.h" },
{ "opExpungeNode", false, "libraries/amigaguide.h" },
{ "DateTime", false, "dos/datetime.h" },
{NULL, true, NULL }
};
void nodeaddtail(hnode_t *nodefirst, hnode_t *node)
{
hnode_t * current = nodefirst;
while (current->next != NULL) {
current = current->next;
}
if (verbose)
{
printf ("Adding node @ %p after %p\n", node, current);
}
current->next = node;
node->prev = current;
node->next = NULL;
}
void noderem(hnode_t *node)
{
hnode_t * prev, *next;
prev = node->prev;
next = node->next;
next->prev = prev;
prev->next = next;
node->prev = NULL;
node->next = NULL;
}
hnode_t *nodefind(hnode_t *nodefirst, char *id)
{
hnode_t * current = nodefirst;
while (current) {
if (0 == strncmp(id, current->id, strlen(id)))
return current;
current = current->next;
}
return NULL;
}
void addSDKHeaderStruct(char *sdkheaderset, char *structname)
{
struct headerSet *header_node = NULL;
hnode_t *structnode = NULL;
if (headerSets)
header_node = (struct headerSet *)nodefind(headerSets, sdkheaderset);
if (!header_node)
{
if (verbose)
{
printf ("registering new header-set %s\n", sdkheaderset);
}
header_node = malloc(sizeof(struct headerSet));
header_node->hs_Node.id = malloc(strlen(sdkheaderset) + 1);
memcpy(header_node->hs_Node.id, sdkheaderset, strlen(sdkheaderset));
header_node->hs_Node.id[strlen(sdkheaderset)] = '\0';
header_node->hs_Node.next = NULL;
header_node->hs_Node.prev = NULL;
header_node->headerStructs = NULL;
if (!headerSets)
{
headerSets = &header_node->hs_Node;
if (verbose)
{
printf ("first header-set registered (= %p)\n", headerSets);
}
}
else
nodeaddtail(headerSets, &header_node->hs_Node);
}
if (header_node->headerStructs)
structnode = nodefind(header_node->headerStructs, structname);
if (!structnode)
{
if (verbose)
{
printf ("registering new %s header-set struct %s\n", header_node->hs_Node.id, structname);
}
structnode = malloc(sizeof(hnode_t));
structnode->id = malloc(strlen(structname) + 1);
memcpy(structnode->id, structname, strlen(structname));
structnode->id[strlen(structname)] = '\0';
structnode->next = NULL;
structnode->prev = NULL;
if (!header_node->headerStructs)
{
header_node->headerStructs = structnode;
if (verbose)
{
printf ("first struct registered (= %p)\n", structnode);
}
}
else
nodeaddtail(header_node->headerStructs, structnode);
}
}
char *findStructHeader (char *sdkdir, char *structname)
{
char *headerFilename = NULL;
int i;
if (sdkdir)
{
if (verbose)
{
printf ("Searching in '%s' for definition of '%s'\n", sdkdir, structname);
}
}
for (i = 0; knownStructs[i].headerStruct != NULL; i++)
{
if (!strcmp(knownStructs[i].headerStruct, structname) && (!knownStructs[i].headerSkip))
return knownStructs[i].headerfile;
}
return headerFilename;
}
void writeHeaderMakefile(char *gendir, char *bindir)
{
char *Makefilename = NULL;
FILE *Makefilefile = NULL;
FILE *Settestfile = NULL;
char *Settestfilename = NULL;
makefullpath(gendir);
if (strcmp(gendir, bindir))
makefullpath(bindir);
Makefilename = malloc(strlen(gendir) + strlen("Makefile") + 2);
if (Makefilename)
{
sprintf(Makefilename, "%s/Makefile", gendir);
Makefilefile = fopen(Makefilename, "w");
if (!Makefilefile)
{
printf ("Failed to open '%s'\n", Makefilename);
return;
}
printBanner(Makefilefile, "#");
fprintf(Makefilefile, "include $(SRCDIR)/config/aros.cfg\n");
if (headerSets)
{
struct headerSet *header_node = (struct headerSet *)headerSets;
char *structFileName = malloc(LINELENGTH);
/* Pass 1: generate recipes for the individual structure test targets */
while (header_node) {
if (header_node->headerStructs)
{
hnode_t * current = header_node->headerStructs;
while (current) {
// Write rules for this struct's tests
sprintf(structFileName, "test-struct_%s", current->id);
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);
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);
current = current->next;
}
}
header_node = (struct headerSet *)header_node->hs_Node.next;
}
/* Pass 2: generate header-set targets & scripts */
header_node = (struct headerSet *)headerSets;
while (header_node) {
if (header_node->headerStructs)
{
hnode_t * current = header_node->headerStructs;
Settestfilename = malloc(strlen(bindir) + strlen(header_node->hs_Node.id) + 12);
fprintf(Makefilefile, "\ntest-sdk-%s-genfiles :", header_node->hs_Node.id);
if (Settestfilename)
{
sprintf(Settestfilename, "%s/run-%s-tests", bindir, header_node->hs_Node.id);
Settestfile = fopen(Settestfilename, "w");
}
while (current) {
// Write rules for this struct's tests
sprintf(structFileName, "%s/test-struct_%s", bindir, current->id);
fprintf(Makefilefile, " %s", structFileName);
if (Settestfile)
fprintf(Settestfile, "test-struct_%s\n", current->id);
current = current->next;
}
fprintf(Makefilefile, "\n");
if (Settestfile)
fclose(Settestfile);
if (Settestfilename)
free(Settestfilename);
}
header_node = (struct headerSet *)header_node->hs_Node.next;
}
/* Pass 3: generate main targets & scripts */
Settestfilename = malloc(strlen(bindir) + 15);
fprintf(Makefilefile, "\ntest-sdk-headers-genfiles :");
header_node = (struct headerSet *)headerSets;
if (Settestfilename)
{
sprintf(Settestfilename, "%s/run-sdk-tests", bindir);
Settestfile = fopen(Settestfilename, "w");
}
while (header_node) {
if (header_node->headerStructs)
{
fprintf(Makefilefile, " test-sdk-%s-genfiles", header_node->hs_Node.id);
if (Settestfile)
fprintf(Settestfile, "c:execute run-%s-tests\n", header_node->hs_Node.id);
}
header_node = (struct headerSet *)header_node->hs_Node.next;
}
if (Settestfile)
fclose(Settestfile);
fprintf(Makefilefile, "\n");
if (Settestfilename)
free(Settestfilename);
if (structFileName)
free(structFileName);
}
fclose(Makefilefile);
free(Makefilename);
}
}