Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / support / scripts / mh2h.c
blob892e06f74ee57570db306b9a3f4be47a97b35f51
1 /*-------------------------------------------------------------------------
2 mh2h.c - megaheader to header conversion utility. This utility converts
3 the mega-header MCS51 mcs51reg.h file to multiple simple header files.
5 We want the simple headers for compatibility with other compilers
6 and also for documentation(quick reference of registers names and
7 bit defines while programming).
8 At the same time we don't want to maintain all these redundant files.
10 So this offers a solution of converting 1 master .h file into many
11 simple header files.
13 We use the preprocessor(sdcpp) to do most of the work. Then we
14 use some c code to clean it up and make it look pretty.
16 Usage# mh2h {include_dir {bin_dir}} ; no options used.
17 default include_dir is "/usr/local/share/sdcc/include"
18 default bin_dir(run sdcpp from is ""
20 Written by Karl Bongers(kbongers@turbobit.com)
21 |-------------------------------------------------------------------------*/
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
27 void get_micro_h_name(char *name, char *ret_str);
28 void get_micro_list(void);
29 void strip_eol(char *str);
30 void strip_trailing_sp(char *str);
32 #define MAX_LISTSIZE 100
33 char *micro_list[MAX_LISTSIZE];
34 char bin_dir[256];
35 char inc_dir[256];
37 /*-------------------------------------------------------------------------
38 |-------------------------------------------------------------------------*/
39 int main(int argc, char *argv[])
41 int stat;
42 FILE *fpi, *fpo;
43 char str[256];
44 char fname[256];
45 int mi;
46 int last_line_was_sfr = 1; // used to print pretty, add a blank line
48 // 1st arg optional inc dir to pull mcs51reg.h from
49 if (argc > 1) {
50 strcpy(inc_dir, argv[1]);
51 printf("using %s bin dir\n", inc_dir);
53 else {
54 strcpy(inc_dir, "/usr/local/share/sdcc/include/");
57 // 2nd arg optional bin dir to run sdcpp from
58 if (argc > 2) {
59 strcpy(bin_dir, argv[2]);
60 printf("using %s bin dir\n", bin_dir);
62 else {
63 bin_dir[0] = 0;
67 get_micro_list();
68 mi = 0;
69 while (micro_list[mi] != NULL)
71 printf("LIST:%s\n", micro_list[mi++]);
74 mi = 0;
75 while (micro_list[mi] != NULL)
77 printf("converting %s\n", micro_list[mi]);
78 fflush(0);
80 sprintf(str, "%ssdcpp -D%s %smcs51reg.h tmp1",
81 bin_dir,
82 micro_list[mi],
83 inc_dir);
85 stat = system(str);
86 /* stat = -1, or 127 error */
88 fpi = fopen("tmp1", "r");
89 if (fpi == NULL) {
90 printf("error opening file to read\n");
91 exit(1);
94 get_micro_h_name(micro_list[mi], fname);
95 //sprintf(fname, "tmp%d.h", mi+1);
97 fpo = fopen(fname, "w");
98 if (fpo == NULL) {
99 printf("error opening %s file to write\n", fname);
100 exit(1);
103 fputs("/*-------------------------------------------------------------------------\n",
104 fpo);
105 fprintf(fpo, " %s - %s header file.\n", fname, micro_list[mi]);
106 fputs(" This file was automatically generated using mh2h utility\n", fpo);
107 fputs(" to convert from mcs51reg.h.\n", fpo);
108 fputs("|-------------------------------------------------------------------------*/\n",
109 fpo);
110 fprintf(fpo, "#define %s\n", micro_list[mi]);
111 fputs("#include <mcs51reg.h>\n\n", fpo);
113 fprintf(fpo, "#if 0\n");
114 fputs("The following is for your reference only\n", fpo);
115 fputs("and is an accurate translation of what the\n", fpo);
116 fputs("above included mcs51reg.h file generates.\n\n", fpo);
118 while (fgets(str, 256, fpi) != NULL) {
119 strip_eol(str);
120 strip_trailing_sp(str);
122 if (strlen(str) <= 0)
123 continue;
124 if (strncmp(str, "#line ", 6) == 0)
125 continue;
126 if (strncmp(str, "//", 2) == 0)
127 continue;
129 if (strncmp(str, "sfr ", 4) == 0)
131 if (!last_line_was_sfr)
132 fputs("\n", fpo); /* for readability, add a blank line) */
133 last_line_was_sfr = 1;
135 else
137 if (strncmp(str, "sbit ", 5) == 0)
138 fputs(" ", fpo); /* for readability, indent */
140 last_line_was_sfr = 0;
143 //printf("[%d,%s]\n", strlen(str), str);
144 fputs(str, fpo);
145 fputs("\n", fpo);
147 fprintf(fpo, "#endif\n");
149 fclose(fpi);
150 fclose(fpo);
151 ++mi;
152 } // while micro_list[mi]
154 return 0;
157 /*-------------------------------------------------------------------------
158 get_micro_h_name - get a .h filename to output to. Preferably, we will
159 have this info in mcs51reg.h file(alias:8051.h) and not do it like this.
160 |-------------------------------------------------------------------------*/
161 void get_micro_h_name(char *name, char *ret_str)
163 int mi;
164 static int name_i = 1;
165 // note: pulling these from mcs51reg.h would be better...
166 static char *micro_strings[] = {
167 "MICROCONTROLLER_8051", "8051.h",
168 "MICROCONTROLLER_8052", "8052.h",
169 "MICROCONTROLLER_AT89CX051", "at89x051.h",
170 "MICROCONTROLLER_AT89S53", "at89s53.h",
171 "MICROCONTROLLER_AT89X52", "at89x52.h",
172 "MICROCONTROLLER_AT89X55", "at89x55.h",
173 "MICROCONTROLLER_DS5000", "ds5000.h",
174 "MICROCONTROLLER_DS5001", "ds5001.h",
175 "MICROCONTROLLER_DS80C32X", "ds80c32x.h",
176 "MICROCONTROLLER_DS80C390", "ds80c390.h",
177 "MICROCONTROLLER_DS89C420", "ds89c420.h",
178 "MICROCONTROLLER_DS8XC520", "ds8xc520.h",
179 "MICROCONTROLLER_SAB80515", "sab80515.h",
180 "MICROCONTROLLER_SAB80515A", "sab80515a.h",
181 "MICROCONTROLLER_SAB80517", "sab80517.h",
182 "MICROCONTROLLER_P80C552", "p80c552.h",
183 NULL};
185 *ret_str = 0;
186 mi = 0;
187 while (micro_strings[mi] != NULL)
189 if (strcmp(micro_strings[mi], name) == 0)
191 strcpy(ret_str, micro_strings[mi+1]);
193 mi += 2;
196 if (*ret_str == 0)
198 sprintf(ret_str, "noname%d.h", name_i++);
199 printf("warning, could not find .h filename for %s using %s\n",
200 name, ret_str);
204 /*-------------------------------------------------------------------------
205 get_micro_list - get the list of micros supported by mcs51reg.h, grab
206 this list out of the mcs51reg.h file.
207 |-------------------------------------------------------------------------*/
208 void get_micro_list(void)
210 FILE *fp;
211 char str[256];
212 int li = 0;
213 char *s;
214 char *s_start;
216 strcpy(str, inc_dir);
217 strcat(str, "mcs51reg.h");
218 fp = fopen(str, "r");
219 if (fp == NULL) {
220 printf("error opening %s file to read\n", str);
221 exit(1);
223 while (fgets(str, 256, fp) != NULL)
225 strip_eol(str);
226 strip_trailing_sp(str);
227 s = str;
228 while (*s == ' ')
229 ++s;
230 if (strlen(s) <= 0)
231 continue;
233 if (strncmp(s, "MICROCONTROLLER_", 16) == 0)
235 s_start = s;
236 while ((*s != 0) && (*s != ' '))
237 ++s;
238 *s = 0;
239 micro_list[li++] = strdup(s_start); // add to our list MICROCONTROLLER_X
240 if (li >= MAX_LISTSIZE)
241 exit(1);
243 } // while
245 micro_list[li] = NULL;
247 if (li == 0)
249 printf("Error, no MICROCONTROLLER_ defines found\n");
250 exit(1);
252 printf("%d MICRO defines found\n", li);
253 fclose(fp);
256 /*-------------------------------------------------------------------------
257 |-------------------------------------------------------------------------*/
258 void strip_trailing_sp(char *str)
260 int sz;
261 sz = strlen(str);
262 if (sz == 0)
263 return;
264 while(str[sz-1] == ' ')
266 str[sz-1] = 0;
267 --sz;
268 if (sz == 0)
269 return;
273 /*-------------------------------------------------------------------------
274 |-------------------------------------------------------------------------*/
275 void strip_eol(char *str)
277 int sz;
278 #define is_eol_char(c) ((c == 0x0d) || (c == 0x0a))
279 sz = strlen(str);
280 if (sz == 0)
281 return;
282 if (is_eol_char(str[sz-1]))
283 str[sz-1] = 0;
285 sz = strlen(str);
286 if (sz == 0)
287 return;
288 if (is_eol_char(str[sz-1]))
289 str[sz-1] = 0;