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