-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathdcapp_genheader.cc
More file actions
183 lines (156 loc) · 6.42 KB
/
dcapp_genheader.cc
File metadata and controls
183 lines (156 loc) · 6.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <list>
#include <libgen.h>
#include <fcntl.h>
#include <unistd.h>
#include "basicutils/msg.hh"
#include "basicutils/pathinfo.hh"
#include "basicutils/shellutils.hh"
#include "xml_utils.hh"
#include "xml_stringsub.hh"
typedef struct
{
std::string name;
std::string type;
} vitem;
static std::list<vitem> vlist;
static void process_elements(xmlNodePtr);
static void UsageError(xmlDocPtr);
int main(int argc, char **argv)
{
xmlDocPtr mydoc;
xmlNodePtr root_element;
FILE *p_file;
static std::list<vitem>::iterator myvitem;
Message::setLabel(basename(argv[0]));
if (argc < 2) UsageError(0x0);
if (XMLFileOpen(&mydoc, &root_element, argv[1])) UsageError(0x0);
if (!NodeCheck(root_element, "DCAPP"))
{
error_msg("Bad root element in XML file: \"" << root_element->name << "\" (should be \"DCAPP\")");
return (-1);
}
if (argc < 3) p_file = fopen("dcapp.h", "w");
else p_file = fopen(argv[2], "w");
if (!p_file) UsageError(mydoc);
// move to the folder containing the specfile and set $dcappDisplayHome
PathInfo mypath(argv[1]);
if (mypath.isValid())
{
setenv("dcappDisplayHome", mypath.getDirectory().c_str(), 1);
chdir(mypath.getDirectory().c_str());
}
process_elements(root_element->children);
std::string configscript = PathInfo(findExecutablePath(argv[0]) + "/../dcapp-config").getFullPath();
fprintf(p_file, "// ********************************************* //\n");
fprintf(p_file, "// THIS FILE IS AUTO-GENERATED -- DO NOT EDIT!!! //\n");
fprintf(p_file, "// ********************************************* //\n\n");
// the line below preceded the use of DCAPP_MAJOR_VERSION and DCAPP_MINOR_VERSION, so retain it for backward compatibility
fprintf(p_file, "#define DCAPP_VERSION_1_0\n\n");
fprintf(p_file, "#define DCAPP_MAJOR_VERSION %s\n", getScriptResult(configscript, "--version_major").c_str());
fprintf(p_file, "#define DCAPP_MINOR_VERSION %s\n", getScriptResult(configscript, "--version_minor").c_str());
fprintf(p_file, "\n#include <string>\n\n");
fprintf(p_file, "#ifndef _DCAPP_EXTERNALS_\n#define _DCAPP_EXTERNALS_\n\n");
fprintf(p_file, "void *(*get_pointer)(const char *);\n\n");
for (myvitem = vlist.begin(); myvitem != vlist.end(); myvitem++)
{
if (myvitem->type == "Decimal" || myvitem->type == "Float") fprintf(p_file, "double *");
else if (myvitem->type == "Integer") fprintf(p_file, "int *");
else fprintf(p_file, "std::string *");
fprintf(p_file, "%s;\n", myvitem->name.c_str());
}
fprintf(p_file, "\n#ifdef __cplusplus\n");
fprintf(p_file, "extern \"C\" void DisplayPreInit(void *(*get_pointer_arg)(const char *))\n");
fprintf(p_file, "#else\n");
fprintf(p_file, "void DisplayPreInit(void *(*get_pointer_arg)(const char *))\n");
fprintf(p_file, "#endif\n{\n");
fprintf(p_file, " get_pointer = get_pointer_arg;\n\n");
for (myvitem = vlist.begin(); myvitem != vlist.end(); myvitem++)
{
fprintf(p_file, " %s = ", myvitem->name.c_str());
if (myvitem->type == "Decimal" || myvitem->type == "Float") fprintf(p_file, "(double *)");
else if (myvitem->type == "Integer") fprintf(p_file, "(int *)");
else fprintf(p_file, "(std::string *)");
fprintf(p_file, "get_pointer(\"%s\");\n", myvitem->name.c_str());
}
fprintf(p_file, "}\n\n");
fprintf(p_file, "#else\n\n");
fprintf(p_file, "extern void *(*get_pointer)(const char *);\n\n");
for (myvitem = vlist.begin(); myvitem != vlist.end(); myvitem++)
{
if (myvitem->type == "Decimal" || myvitem->type == "Float") fprintf(p_file, "extern double *");
else if (myvitem->type == "Integer") fprintf(p_file, "extern int *");
else fprintf(p_file, "extern std::string *");
fprintf(p_file, "%s;\n", myvitem->name.c_str());
}
fprintf(p_file, "\n#endif\n");
fclose(p_file);
vlist.clear();
XMLFileClose(mydoc);
XMLEndParsing();
return 0;
}
static void process_elements(xmlNodePtr startnode)
{
for (xmlNodePtr node = startnode; node; node = node->next)
{
if (NodeCheck(node, "Dummy")) process_elements(node->children);
if (NodeCheck(node, "Constant")) processConstantNode(node);
if (NodeCheck(node, "Style")) processStyleNode(node);
if (NodeCheck(node, "Defaults")) processDefaultsNode(node);
if (NodeCheck(node, "Include"))
{
xmlDocPtr include_file;
xmlNodePtr include_element;
std::string include_filename = get_node_content(node);
if (!include_filename.empty())
{
PathInfo mypath(include_filename);
if (!mypath.isValid())
{
warning_msg("Couldn't open include file " << include_filename);
}
else
{
// Store cwd for future use
int mycwd = open(".", O_RDONLY);
// Move to directory containing the new file
chdir(mypath.getDirectory().c_str());
if (XMLFileOpen(&include_file, &include_element, mypath.getFile()))
{
warning_msg("Couldn't open include file " << include_filename);
}
else
{
process_elements(include_element);
XMLFileClose(include_file);
}
// Return to the original working directory
fchdir(mycwd);
close(mycwd);
}
}
else warning_msg("No include file specified");
}
if (NodeCheck(node, "Variable"))
{
vitem newitem;
std::string myname = get_node_content(node);
if (myname[0] == '@') myname.erase(0, 1);
newitem.name = myname;
newitem.type = get_element_data(node, "Type");
vlist.push_back(newitem);
}
}
}
static void UsageError(xmlDocPtr infile)
{
if (infile) XMLFileClose(infile);
printf("Usage: dcapp_genheader <infile> <outfile>, where:\n");
printf(" <infile> is a dcapp specfile or a dcapp global variable file\n");
printf(" <outfile> is a the name of the header file to be generated\n");
exit(-1);
}