1218822Sdim/* Copyright 2001, 2003, 2005 Free Software Foundation, Inc.
278828Sobrien   Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
378828Sobrien
478828SobrienThis file is part of GNU binutils.
578828Sobrien
678828SobrienThis program is free software; you can redistribute it and/or modify
778828Sobrienit under the terms of the GNU General Public License as published by
878828Sobrienthe Free Software Foundation; either version 2 of the License, or
978828Sobrien(at your option) any later version.
1078828Sobrien
1178828SobrienThis program is distributed in the hope that it will be useful,
1278828Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1378828SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1478828SobrienGNU General Public License for more details.
1578828Sobrien
1678828SobrienYou should have received a copy of the GNU General Public License
1778828Sobrienalong with this program; if not, write to the Free Software
18218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
1978828Sobrien
2033965Sjdp%{
2133965Sjdp#include <stdio.h>
2233965Sjdp#include <stdlib.h>
2333965Sjdp
24218822Sdimstatic char writecode;
25218822Sdimstatic char *it;
26218822Sdimstatic int code;
27218822Sdimstatic char * repeat;
28218822Sdimstatic char *oldrepeat;
29218822Sdimstatic char *name;
30218822Sdimstatic int rdepth;
31218822Sdimstatic char *names[] = {" ","[n]","[n][m]"};
32218822Sdimstatic char *pnames[]= {"","*","**"};
33218822Sdim
34218822Sdimstatic int yyerror (char *s);
35218822Sdimextern int yylex (void);
3633965Sjdp%}
3733965Sjdp
3833965Sjdp
3933965Sjdp%union {
4033965Sjdp int i;
4133965Sjdp char *s;
4233965Sjdp}
4333965Sjdp%token COND
4433965Sjdp%token REPEAT
4533965Sjdp%token '(' ')'
4633965Sjdp%token <s> TYPE
4733965Sjdp%token <s> NAME
4833965Sjdp%token <i> NUMBER UNIT
4933965Sjdp%type <i> attr_size
5033965Sjdp%type <s> attr_desc attr_id attr_type
5133965Sjdp%%
5233965Sjdp
5333965Sjdptop:  {
5433965Sjdp  switch (writecode)
5533965Sjdp    {
5633965Sjdp    case 'i':
5733965Sjdp      printf("#ifdef SYSROFF_SWAP_IN\n");
5833965Sjdp      break;
5933965Sjdp    case 'p':
6033965Sjdp      printf("#ifdef SYSROFF_p\n");
6133965Sjdp      break;
6233965Sjdp    case 'd':
6333965Sjdp      break;
6433965Sjdp    case 'g':
6533965Sjdp      printf("#ifdef SYSROFF_SWAP_OUT\n");
6633965Sjdp      break;
6733965Sjdp    case 'c':
6833965Sjdp      printf("#ifdef SYSROFF_PRINT\n");
6933965Sjdp      printf("#include <stdio.h>\n");
7033965Sjdp      printf("#include <stdlib.h>\n");
7189857Sobrien      printf("#include <ansidecl.h>\n");
7233965Sjdp      break;
7333965Sjdp    }
7433965Sjdp }
7533965Sjdpit_list {
7633965Sjdp  switch (writecode) {
7733965Sjdp  case 'i':
7833965Sjdp  case 'p':
7933965Sjdp  case 'g':
8033965Sjdp  case 'c':
8133965Sjdp    printf("#endif\n");
8233965Sjdp    break;
8333965Sjdp  case 'd':
8433965Sjdp    break;
8533965Sjdp  }
8633965Sjdp}
8733965Sjdp
8833965Sjdp  ;
8933965Sjdp
9033965Sjdp
9133965Sjdpit_list: it it_list
9233965Sjdp  |
9333965Sjdp  ;
9433965Sjdp
9533965Sjdpit:
9633965Sjdp	'(' NAME NUMBER
9733965Sjdp      {
9833965Sjdp	it = $2; code = $3;
9933965Sjdp	switch (writecode)
10033965Sjdp	  {
10133965Sjdp	  case 'd':
10233965Sjdp	    printf("\n\n\n#define IT_%s_CODE 0x%x\n", it,code);
10389857Sobrien	    printf("struct IT_%s;\n", it);
10489857Sobrien	    printf("extern void sysroff_swap_%s_in PARAMS ((struct IT_%s *));\n",
10589857Sobrien		   $2, it);
10689857Sobrien	    printf("extern void sysroff_swap_%s_out PARAMS ((FILE *, struct IT_%s *));\n",
10789857Sobrien		   $2, it);
10889857Sobrien	    printf("extern void sysroff_print_%s_out PARAMS ((struct IT_%s *));\n",
10989857Sobrien		   $2, it);
11033965Sjdp	    printf("struct IT_%s { \n", it);
11133965Sjdp	    break;
11233965Sjdp	  case 'i':
11333965Sjdp	    printf("void sysroff_swap_%s_in(ptr)\n",$2);
11433965Sjdp	    printf("struct IT_%s *ptr;\n", it);
11533965Sjdp	    printf("{\n");
116218822Sdim	    printf("unsigned char raw[255];\n");
11733965Sjdp	    printf("\tint idx = 0 ;\n");
11833965Sjdp	    printf("\tint size;\n");
11933965Sjdp	    printf("memset(raw,0,255);\n");
12033965Sjdp	    printf("memset(ptr,0,sizeof(*ptr));\n");
12133965Sjdp	    printf("size = fillup(raw);\n");
12233965Sjdp	    break;
12333965Sjdp	  case 'g':
12433965Sjdp	    printf("void sysroff_swap_%s_out(file,ptr)\n",$2);
12533965Sjdp	    printf("FILE * file;\n");
12633965Sjdp	    printf("struct IT_%s *ptr;\n", it);
12733965Sjdp	    printf("{\n");
128218822Sdim	    printf("\tunsigned char raw[255];\n");
12933965Sjdp	    printf("\tint idx = 16 ;\n");
13033965Sjdp	    printf("\tmemset (raw, 0, 255);\n");
13133965Sjdp	    printf("\tcode = IT_%s_CODE;\n", it);
13233965Sjdp	    break;
13333965Sjdp	  case 'o':
13433965Sjdp	    printf("void sysroff_swap_%s_out(abfd,ptr)\n",$2);
13533965Sjdp	    printf("bfd * abfd;\n");
13633965Sjdp	    printf("struct IT_%s *ptr;\n",it);
13733965Sjdp	    printf("{\n");
13833965Sjdp	    printf("int idx = 0 ;\n");
13933965Sjdp	    break;
14033965Sjdp	  case 'c':
14133965Sjdp	    printf("void sysroff_print_%s_out(ptr)\n",$2);
14233965Sjdp	    printf("struct IT_%s *ptr;\n", it);
14333965Sjdp	    printf("{\n");
14433965Sjdp	    printf("itheader(\"%s\", IT_%s_CODE);\n",$2,$2);
14533965Sjdp	    break;
14633965Sjdp
14733965Sjdp	  case 't':
14833965Sjdp	    break;
14933965Sjdp	  }
15033965Sjdp
15133965Sjdp      }
15233965Sjdp	it_field_list
15333965Sjdp')'
15433965Sjdp{
15533965Sjdp  switch (writecode) {
15633965Sjdp  case 'd':
15733965Sjdp    printf("};\n");
15833965Sjdp    break;
15933965Sjdp  case 'g':
16033965Sjdp    printf("\tchecksum(file,raw, idx, IT_%s_CODE);\n", it);
16133965Sjdp
16233965Sjdp  case 'i':
16333965Sjdp
16433965Sjdp  case 'o':
16533965Sjdp  case 'c':
16633965Sjdp    printf("}\n");
16733965Sjdp  }
16833965Sjdp}
16933965Sjdp;
17033965Sjdp
17133965Sjdp
17233965Sjdp
17333965Sjdpit_field_list:
17433965Sjdp		it_field it_field_list
17533965Sjdp	|	cond_it_field it_field_list
17633965Sjdp	|	repeat_it_field it_field_list
17733965Sjdp	|
17833965Sjdp	;
17933965Sjdp
18033965Sjdprepeat_it_field: '(' REPEAT NAME
18133965Sjdp	{
18233965Sjdp	  rdepth++;
18333965Sjdp	  switch (writecode)
18433965Sjdp	    {
18533965Sjdp	    case 'c':
18633965Sjdp	      if (rdepth==1)
18733965Sjdp	      printf("\tprintf(\"repeat %%d\\n\", %s);\n",$3);
18833965Sjdp	      if (rdepth==2)
18933965Sjdp	      printf("\tprintf(\"repeat %%d\\n\", %s[n]);\n",$3);
19033965Sjdp	    case 'i':
19133965Sjdp	    case 'g':
19233965Sjdp	    case 'o':
19333965Sjdp
19433965Sjdp	      if (rdepth==1)
19533965Sjdp		{
19633965Sjdp	      printf("\t{ int n; for (n = 0; n < %s; n++) {\n",    $3);
19733965Sjdp	    }
19833965Sjdp	      if (rdepth == 2) {
19933965Sjdp	      printf("\t{ int m; for (m = 0; m < %s[n]; m++) {\n",    $3);
20033965Sjdp	    }
20133965Sjdp
20233965Sjdp	      break;
20333965Sjdp	    }
20433965Sjdp
20533965Sjdp	  oldrepeat = repeat;
20633965Sjdp         repeat = $3;
20733965Sjdp	}
20833965Sjdp
20933965Sjdp	 it_field_list ')'
21033965Sjdp
21133965Sjdp	{
21233965Sjdp	  repeat = oldrepeat;
21333965Sjdp	  oldrepeat =0;
21433965Sjdp	  rdepth--;
21533965Sjdp	  switch (writecode)
21633965Sjdp	    {
21733965Sjdp	    case 'i':
21833965Sjdp	    case 'g':
21933965Sjdp	    case 'o':
22033965Sjdp	    case 'c':
22133965Sjdp	  printf("\t}}\n");
22233965Sjdp	}
22333965Sjdp	}
22433965Sjdp       ;
22533965Sjdp
22633965Sjdp
22733965Sjdpcond_it_field: '(' COND NAME
22833965Sjdp	{
22933965Sjdp	  switch (writecode)
23033965Sjdp	    {
23133965Sjdp	    case 'i':
23233965Sjdp	    case 'g':
23333965Sjdp	    case 'o':
23433965Sjdp	    case 'c':
23533965Sjdp	      printf("\tif (%s) {\n", $3);
23633965Sjdp	      break;
23733965Sjdp	    }
23833965Sjdp	}
23933965Sjdp
24033965Sjdp	 it_field_list ')'
24133965Sjdp	{
24233965Sjdp	  switch (writecode)
24333965Sjdp	    {
24433965Sjdp	    case 'i':
24533965Sjdp	    case 'g':
24633965Sjdp	    case 'o':
24733965Sjdp	    case 'c':
24833965Sjdp	  printf("\t}\n");
24933965Sjdp	}
25033965Sjdp	}
25133965Sjdp       ;
25233965Sjdp
25333965Sjdpit_field:
25433965Sjdp	'(' attr_desc '(' attr_type attr_size ')' attr_id
25533965Sjdp	{name = $7; }
25633965Sjdp	enums ')'
25733965Sjdp	{
25833965Sjdp	  char *desc = $2;
25933965Sjdp	  char *type = $4;
26033965Sjdp	  int size = $5;
26133965Sjdp	  char *id = $7;
26233965Sjdpchar *p = names[rdepth];
26333965Sjdpchar *ptr = pnames[rdepth];
26433965Sjdp	  switch (writecode)
26533965Sjdp	    {
26633965Sjdp	    case 'g':
26733965Sjdp	      if (size % 8)
26833965Sjdp		{
26933965Sjdp
27033965Sjdp		  printf("\twriteBITS(ptr->%s%s,raw,&idx,%d);\n",
27133965Sjdp			 id,
27233965Sjdp			 names[rdepth], size);
27333965Sjdp
27433965Sjdp		}
27533965Sjdp	      else {
27633965Sjdp		printf("\twrite%s(ptr->%s%s,raw,&idx,%d,file);\n",
27733965Sjdp		       type,
27833965Sjdp		       id,
27933965Sjdp		       names[rdepth],size/8);
28033965Sjdp		}
28133965Sjdp	      break;
28233965Sjdp	    case 'i':
28333965Sjdp	      {
28433965Sjdp
28533965Sjdp		if (rdepth >= 1)
28633965Sjdp
28733965Sjdp		  {
28833965Sjdp		    printf("if (!ptr->%s) ptr->%s = (%s*)xcalloc(%s, sizeof(ptr->%s[0]));\n",
28933965Sjdp			   id,
29033965Sjdp			   id,
29133965Sjdp			   type,
29233965Sjdp			   repeat,
29333965Sjdp			   id);
29433965Sjdp		  }
29533965Sjdp
29633965Sjdp		if (rdepth == 2)
29733965Sjdp		  {
29833965Sjdp		    printf("if (!ptr->%s[n]) ptr->%s[n] = (%s**)xcalloc(%s[n], sizeof(ptr->%s[n][0]));\n",
29933965Sjdp			   id,
30033965Sjdp			   id,
30133965Sjdp			   type,
30233965Sjdp			   repeat,
30333965Sjdp			   id);
30433965Sjdp		  }
30533965Sjdp
30633965Sjdp	      }
30733965Sjdp
30833965Sjdp	      if (size % 8)
30933965Sjdp		{
31033965Sjdp		  printf("\tptr->%s%s = getBITS(raw,&idx, %d,size);\n",
31133965Sjdp			 id,
31233965Sjdp			 names[rdepth],
31333965Sjdp			 size);
31433965Sjdp		}
31533965Sjdp	      else {
31633965Sjdp		printf("\tptr->%s%s = get%s(raw,&idx, %d,size);\n",
31733965Sjdp		       id,
31833965Sjdp		       names[rdepth],
31933965Sjdp		       type,
32033965Sjdp		       size/8);
32133965Sjdp		}
32233965Sjdp	      break;
32333965Sjdp	    case 'o':
32433965Sjdp	      printf("\tput%s(raw,%d,%d,&idx,ptr->%s%s);\n", type,size/8,size%8,id,names[rdepth]);
32533965Sjdp	      break;
32633965Sjdp	    case 'd':
32733965Sjdp	      if (repeat)
32833965Sjdp		printf("\t/* repeat %s */\n", repeat);
32933965Sjdp
33033965Sjdp		  if (type[0] == 'I') {
33133965Sjdp		  printf("\tint %s%s; \t/* %s */\n",ptr,id, desc);
33233965Sjdp		}
33333965Sjdp		  else if (type[0] =='C') {
33433965Sjdp		  printf("\tchar %s*%s;\t /* %s */\n",ptr,id, desc);
33533965Sjdp		}
33633965Sjdp	      else {
33733965Sjdp		printf("\tbarray %s%s;\t /* %s */\n",ptr,id, desc);
33833965Sjdp	      }
33933965Sjdp		  break;
34033965Sjdp		case 'c':
34133965Sjdp	      printf("tabout();\n");
34233965Sjdp		  printf("\tprintf(\"/*%-30s*/ ptr->%s = \");\n", desc, id);
34333965Sjdp
34433965Sjdp		  if (type[0] == 'I')
34533965Sjdp		  printf("\tprintf(\"%%d\\n\",ptr->%s%s);\n", id,p);
34633965Sjdp		  else   if (type[0] == 'C')
34733965Sjdp		  printf("\tprintf(\"%%s\\n\",ptr->%s%s);\n", id,p);
34833965Sjdp
34933965Sjdp		  else   if (type[0] == 'B')
35033965Sjdp		    {
35133965Sjdp		  printf("\tpbarray(&ptr->%s%s);\n", id,p);
35233965Sjdp		}
35333965Sjdp	      else abort();
35433965Sjdp		  break;
35533965Sjdp		}
35633965Sjdp	}
35733965Sjdp
35833965Sjdp	;
35933965Sjdp
36033965Sjdp
36133965Sjdpattr_type:
36233965Sjdp	 TYPE { $$ = $1; }
36333965Sjdp 	|  { $$ = "INT";}
36433965Sjdp	;
36533965Sjdp
36633965Sjdpattr_desc:
36733965Sjdp	'(' NAME ')'
36833965Sjdp	{ $$ = $2; }
36933965Sjdp	;
37033965Sjdp
37133965Sjdpattr_size:
37233965Sjdp	 NUMBER UNIT
37333965Sjdp	{ $$ = $1 * $2; }
37433965Sjdp	;
37533965Sjdp
37633965Sjdp
37733965Sjdpattr_id:
37833965Sjdp		'(' NAME ')'	{ $$ = $2; }
37933965Sjdp	|	{ $$ = "dummy";}
38033965Sjdp	;
38133965Sjdp
38233965Sjdpenums:
38333965Sjdp	| '(' enum_list ')' ;
38433965Sjdp
38533965Sjdpenum_list:
38633965Sjdp	|
38733965Sjdp	enum_list '(' NAME NAME ')' {
38833965Sjdp	  switch (writecode)
38933965Sjdp	    {
39033965Sjdp	    case 'd':
39133965Sjdp	      printf("#define %s %s\n", $3,$4);
39233965Sjdp	      break;
39333965Sjdp	    case 'c':
39433965Sjdp		printf("if (ptr->%s%s == %s) { tabout(); printf(\"%s\\n\");}\n", name, names[rdepth],$4,$3);
39533965Sjdp	    }
39633965Sjdp	}
39733965Sjdp
39833965Sjdp	;
39933965Sjdp
40033965Sjdp
40133965Sjdp
40233965Sjdp%%
40333965Sjdp/* four modes
40433965Sjdp
405218822Sdim   -d write structure definitions for sysroff in host format
40633965Sjdp   -i write functions to swap into sysroff format in
40733965Sjdp   -o write functions to swap into sysroff format out
40833965Sjdp   -c write code to print info in human form */
40933965Sjdp
41033965Sjdpint yydebug;
41133965Sjdp
41233965Sjdpint
413218822Sdimmain (int ac, char **av)
41433965Sjdp{
41533965Sjdp  yydebug=0;
41633965Sjdp  if (ac > 1)
41733965Sjdp    writecode = av[1][1];
41833965Sjdpif (writecode == 'd')
41933965Sjdp  {
42033965Sjdp    printf("typedef struct { unsigned char *data; int len; } barray; \n");
42133965Sjdp    printf("typedef  int INT;\n");
42233965Sjdp    printf("typedef  char * CHARS;\n");
42333965Sjdp
42433965Sjdp  }
42533965Sjdp  yyparse();
42633965Sjdpreturn 0;
42733965Sjdp}
42833965Sjdp
429218822Sdimstatic int
430218822Sdimyyerror (char *s)
43133965Sjdp{
43233965Sjdp  fprintf(stderr, "%s\n" , s);
43338889Sjdp  return 0;
43433965Sjdp}
435