1/* Copyright (C) 2001-2022 Free Software Foundation, Inc.
2   Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
3
4   This file is part of GNU binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21%{
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26static char writecode;
27static char *it;
28static int code;
29static char * repeat;
30static char *oldrepeat;
31static char *name;
32static int rdepth;
33static char *names[] = {" ","[n]","[n][m]"};
34static char *pnames[]= {"","*","**"};
35
36static void yyerror (const char *s);
37extern int yylex (void);
38%}
39
40
41%union {
42 int i;
43 char *s;
44}
45%token COND
46%token REPEAT
47%token '(' ')'
48%token <s> TYPE
49%token <s> NAME
50%token <i> NUMBER UNIT
51%type <i> attr_size
52%type <s> attr_desc attr_id attr_type
53%%
54
55top:  {
56  switch (writecode)
57    {
58    case 'i':
59      printf("#ifdef SYSROFF_SWAP_IN\n");
60      break;
61    case 'p':
62      printf("#ifdef SYSROFF_p\n");
63      break;
64    case 'd':
65      break;
66    case 'g':
67      printf("#ifdef SYSROFF_SWAP_OUT\n");
68      break;
69    case 'c':
70      printf("#ifdef SYSROFF_PRINT\n");
71      printf("#include <stdio.h>\n");
72      printf("#include <stdlib.h>\n");
73      printf("#include <ansidecl.h>\n");
74      break;
75    }
76 }
77it_list {
78  switch (writecode) {
79  case 'i':
80  case 'p':
81  case 'g':
82  case 'c':
83    printf("#endif\n");
84    break;
85  case 'd':
86    break;
87  }
88}
89
90  ;
91
92
93it_list: it it_list
94  |
95  ;
96
97it:
98	'(' NAME NUMBER
99      {
100	it = $2; code = $3;
101	switch (writecode)
102	  {
103	  case 'd':
104	    printf("\n\n\n#define IT_%s_CODE 0x%x\n", it,code);
105	    printf("struct IT_%s;\n", it);
106	    printf("extern void sysroff_swap_%s_in (struct IT_%s *);\n",
107		   $2, it);
108	    printf("extern void sysroff_swap_%s_out (FILE *, struct IT_%s *);\n",
109		   $2, it);
110	    printf("extern void sysroff_print_%s_out (struct IT_%s *);\n",
111		   $2, it);
112	    printf("struct IT_%s { \n", it);
113	    break;
114	  case 'i':
115	    printf("void sysroff_swap_%s_in (struct IT_%s * ptr)\n",$2,it);
116	    printf("{\n");
117	    printf("\tunsigned char raw[255];\n");
118	    printf("\tint idx = 0;\n");
119	    printf("\tint size;\n");
120	    printf("\tmemset(raw,0,255);\n");
121	    printf("\tmemset(ptr,0,sizeof(*ptr));\n");
122	    printf("\tsize = fillup(raw);\n");
123	    break;
124	  case 'g':
125	    printf("void sysroff_swap_%s_out (FILE * ffile, struct IT_%s * ptr)\n",$2,it);
126	    printf("{\n");
127	    printf("\tunsigned char raw[255];\n");
128	    printf("\tint idx = 16;\n");
129	    printf("\tmemset (raw, 0, 255);\n");
130	    printf("\tcode = IT_%s_CODE;\n", it);
131	    break;
132	  case 'o':
133	    printf("void sysroff_swap_%s_out (bfd * abfd, struct IT_%s * ptr)\n",$2, it);
134	    printf("{\n");
135	    printf("\tint idx = 0;\n");
136	    break;
137	  case 'c':
138	    printf("void sysroff_print_%s_out (struct IT_%s *ptr)\n",$2,it);
139	    printf("{\n");
140	    printf("itheader(\"%s\", IT_%s_CODE);\n",$2,$2);
141	    break;
142
143	  case 't':
144	    break;
145	  }
146
147      }
148	it_field_list
149')'
150{
151  switch (writecode) {
152  case 'd':
153    printf("};\n");
154    break;
155  case 'g':
156    printf("\tchecksum(ffile,raw, idx, IT_%s_CODE);\n", it);
157    /* Fall through.  */
158  case 'i':
159  case 'o':
160  case 'c':
161    printf("}\n");
162  }
163
164  free (it);
165}
166;
167
168
169
170it_field_list:
171		it_field it_field_list
172	|	cond_it_field it_field_list
173	|	repeat_it_field it_field_list
174	|
175	;
176
177repeat_it_field: '(' REPEAT NAME
178	{
179	  rdepth++;
180	  switch (writecode)
181	    {
182	    case 'c':
183	      if (rdepth==1)
184	      printf("\tprintf(\"repeat %%d\\n\", %s);\n",$3);
185	      if (rdepth==2)
186	      printf("\tprintf(\"repeat %%d\\n\", %s[n]);\n",$3);
187	      /* Fall through.  */
188	    case 'i':
189	    case 'g':
190	    case 'o':
191
192	      if (rdepth==1)
193		{
194	      printf("\t{ int n; for (n = 0; n < %s; n++) {\n",    $3);
195	    }
196	      if (rdepth == 2) {
197	      printf("\t{ int m; for (m = 0; m < %s[n]; m++) {\n",    $3);
198	    }
199
200	      break;
201	    }
202
203	  oldrepeat = repeat;
204         repeat = $3;
205	}
206
207	 it_field_list ')'
208
209	{
210	  free (repeat);
211
212	  repeat = oldrepeat;
213	  oldrepeat =0;
214	  rdepth--;
215	  switch (writecode)
216	    {
217	    case 'i':
218	    case 'g':
219	    case 'o':
220	    case 'c':
221	  printf("\t}}\n");
222	}
223	}
224       ;
225
226
227cond_it_field: '(' COND NAME
228	{
229	  switch (writecode)
230	    {
231	    case 'i':
232	    case 'g':
233	    case 'o':
234	    case 'c':
235	      printf("\tif (%s) {\n", $3);
236	      break;
237	    }
238
239	  free ($3);
240	}
241
242	 it_field_list ')'
243	{
244	  switch (writecode)
245	    {
246	    case 'i':
247	    case 'g':
248	    case 'o':
249	    case 'c':
250	  printf("\t}\n");
251	}
252	}
253       ;
254
255it_field:
256	'(' attr_desc '(' attr_type attr_size ')' attr_id
257	{name = $7; }
258	enums ')'
259	{
260	  char *desc = $2;
261	  char *type = $4;
262	  int size = $5;
263	  char *id = $7;
264char *p = names[rdepth];
265char *ptr = pnames[rdepth];
266	  switch (writecode)
267	    {
268	    case 'g':
269	      if (size % 8)
270		{
271
272		  printf("\twriteBITS(ptr->%s%s,raw,&idx,%d);\n",
273			 id,
274			 names[rdepth], size);
275
276		}
277	      else {
278		printf("\twrite%s(ptr->%s%s,raw,&idx,%d,ffile);\n",
279		       type,
280		       id,
281		       names[rdepth],size/8);
282		}
283	      break;
284	    case 'i':
285	      {
286
287		if (rdepth >= 1)
288
289		  {
290		    printf("if (!ptr->%s) ptr->%s = (%s*)xcalloc(%s, sizeof(ptr->%s[0]));\n",
291			   id,
292			   id,
293			   type,
294			   repeat,
295			   id);
296		  }
297
298		if (rdepth == 2)
299		  {
300		    printf("if (!ptr->%s[n]) ptr->%s[n] = (%s**)xcalloc(%s[n], sizeof(ptr->%s[n][0]));\n",
301			   id,
302			   id,
303			   type,
304			   repeat,
305			   id);
306		  }
307
308	      }
309
310	      if (size % 8)
311		{
312		  printf("\tptr->%s%s = getBITS(raw,&idx, %d,size);\n",
313			 id,
314			 names[rdepth],
315			 size);
316		}
317	      else {
318		printf("\tptr->%s%s = get%s(raw,&idx, %d,size);\n",
319		       id,
320		       names[rdepth],
321		       type,
322		       size/8);
323		}
324	      break;
325	    case 'o':
326	      printf("\tput%s(raw,%d,%d,&idx,ptr->%s%s);\n", type,size/8,size%8,id,names[rdepth]);
327	      break;
328	    case 'd':
329	      if (repeat)
330		printf("\t/* repeat %s */\n", repeat);
331
332		  if (type[0] == 'I') {
333		  printf("\tint %s%s; \t/* %s */\n",ptr,id, desc);
334		}
335		  else if (type[0] =='C') {
336		  printf("\tchar %s*%s;\t /* %s */\n",ptr,id, desc);
337		}
338	      else {
339		printf("\tbarray %s%s;\t /* %s */\n",ptr,id, desc);
340	      }
341		  break;
342		case 'c':
343	      printf("tabout();\n");
344		  printf("\tprintf(\"/*%-30s*/ ptr->%s = \");\n", desc, id);
345
346		  if (type[0] == 'I')
347		  printf("\tprintf(\"%%d\\n\",ptr->%s%s);\n", id,p);
348		  else   if (type[0] == 'C')
349		  printf("\tprintf(\"%%s\\n\",ptr->%s%s);\n", id,p);
350
351		  else   if (type[0] == 'B')
352		    {
353		  printf("\tpbarray(&ptr->%s%s);\n", id,p);
354		}
355	      else abort();
356		  break;
357		}
358
359	  free (desc);
360	  free (id);
361	}
362
363	;
364
365
366attr_type:
367	 TYPE { $$ = $1; }
368 	|  { $$ = "INT";}
369	;
370
371attr_desc:
372	'(' NAME ')'
373	{ $$ = $2; }
374	;
375
376attr_size:
377	 NUMBER UNIT
378	{ $$ = $1 * $2; }
379	;
380
381
382attr_id:
383		'(' NAME ')'	{ $$ = $2; }
384	|	{ $$ = strdup ("dummy");}
385	;
386
387enums:
388	| '(' enum_list ')' ;
389
390enum_list:
391	|
392	enum_list '(' NAME NAME ')' {
393	  switch (writecode)
394	    {
395	    case 'd':
396	      printf("#define %s %s\n", $3,$4);
397	      break;
398	    case 'c':
399		printf("if (ptr->%s%s == %s) { tabout(); printf(\"%s\\n\");}\n", name, names[rdepth],$4,$3);
400	    }
401
402	  free ($3);
403	  free ($4);
404	}
405
406	;
407
408
409
410%%
411/* four modes
412
413   -d write structure definitions for sysroff in host format
414   -i write functions to swap into sysroff format in
415   -o write functions to swap into sysroff format out
416   -c write code to print info in human form */
417
418int yydebug;
419
420int
421main (int ac, char **av)
422{
423  yydebug=0;
424  if (ac > 1)
425    writecode = av[1][1];
426if (writecode == 'd')
427  {
428    printf("typedef struct { unsigned char *data; int len; } barray; \n");
429    printf("typedef  int INT;\n");
430    printf("typedef  char * CHARS;\n");
431
432  }
433  yyparse();
434return 0;
435}
436
437static void
438yyerror (const char *s)
439{
440  fprintf(stderr, "%s\n" , s);
441}
442