/* Copyright (c), Digital Equipment Corporation, 1994. Redistribution and use source and binary forms are permitted provided that the copyright notice as indicated box below and this paragraph are duplicated all such forms and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed by Digital Equipment Corporation. The name of Digital Equipment Corporation may not be used to endorse or promote products derived from this software without the specific prior written permission. All other rights reserved. THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Digital assumes no responsibility AT ALL for the use or reliability of this software. +------------------------------------------------------------------------+ | USE, DUPLICATION OR DISCLOSURE BY THE U.S. GOVERNMENT IS SUBJECT TO | | RESTRICTIONS AS SET FORTH IN SUBPARAGRAPH (c) (1) (ii) OF | | DFARS 252.227-7013, OR IN FAR 52.227-14 ALT. II, AS APPLICABLE. | | | +------------------------------------------------------------------------+ C to Ada Translator 03Jun93 dbh Move program start to user's domain 24May93 dbh Added padding tokens [#pads size [#pado offset 20May93 dbh Added [#psb based size - size of struct starting from component 17May93 dbh Added [#pob - based offset - offset from component 05May93 dbh Left justify macro #define 22Apr93 dbh Added [#psc - output sizeof component 08Apr93 dbh Retokenization: [#inc, [#pd, [#ps, [#po, [#rec, [#. 06Apr93 dbh Added [#rec token. */ #define MAXLINE 1024 /* line length for files */ #define NAMESIZE 80 /* size of names - records, components, types */ #include #include #include #include #include #ifdef VMS #define ok 1 #define errval 0 #include #else #define ok 0 #define errval 1 #endif typedef char LINE [MAXLINE]; typedef char NAME [NAMESIZE]; typedef char *(*trtn_p)(char *); typedef struct {trtn_p trtn; char *str;} trec; /* Token Output Routines */ char *_text (char *s); char *_include (char *s); char *_define (char *s); char *_record (char *s); char *_sizeof (char *s); char *_sizeofc (char *s); char *_sizeofb (char *s); char *_offsetof (char *s); char *_offsetofb (char *s); char *_C_code (char *s); char *_pads (char *s); char *_pado (char *s); /* Auxillary Routines */ void init (int argc, char *argv[]); char *readin (char *line); void valtok (char *s, char *v); trtn_p gettoken (char *s); char *prtf (char *s, FILE *fp); FILE *opfile (char *fn, char *m,FILE *fp); void apfile (char *fn, FILE *s,FILE *d); /* Error Routines */ void token_error(); void errxit(char *s); void errnox(char *s); #define ontoken(s) ((*s=='[')&&(*(s+1)=='#')) /* The order of the array following must be maintained to prevent general tokens from obscuring more specific ones of a certain variety. For example the size of a component - [#ps, must precede the general token size - [#psc. Legand for semantics documentation below: SZ-sizeof, OFF-offsetof, OB-object of type, -expression, t-type, st-structure type, c-component name. All values for below are printed using printf ("%d", ...). */ static trec tt[] = { /* routine string semantics */ _include, "[#inc", /* create an include file line */ _define, "[#pd", /* print expression */ _sizeofb, "[#psb", /* print based size (SZ(st) - OFF(st,c)) */ _sizeofc, "[#psc", /* print component size SZ(OB(st,c)) */ _sizeof, "[#ps", /* print size SZ(t or st) */ _offsetofb, "[#pob", /* print based offset (OF(st,c2)-OF(st,c1)) */ _offsetof, "[#po", /* print offset OF(st,c) */ _pads, "[#pads", /* print pad size (SZ(st) - (OF(st,c)+SZ(st,c))) */ _pado, "[#pado", /* print pad offset (OF(st,c) + SZ(st,c)) */ _record, "[#rec", /* build a record rep clause */ _C_code, "[#c" /* [#...arbitrary C code...#] must be last */ }; #define ttn sizeof(tt)/sizeof(trec) /* Static */ static LINE line; /* io file processing parms */ static char *eolp; /* eol ptr, s & p pt into line[] */ static int lnum; /* line number count */ static FILE *ifp; /* input file */ static FILE *ofp; /* output file */ static FILE *repfp; /* rep specs temp file */ static int once = 1; /* for begin processing */ static int done = 0; /* for end processing */ main (int argc, char *argv[]) { int i; char *s; trtn_p trout; /* token routine */ init (argc, argv); /* read input, process tokens */ while (s = readin(line)) while (trout = gettoken(s)) { /* Program Heading */ if (once && ((trout!=_include)&&(trout!=_C_code))) { fputs("#include \n",ofp); fputs("#include \n\n",ofp); fputs("#define objof(t,id) (((t *)0)->id)\n\n",ofp); fputs("main () {\n",ofp); once=0; } s = (*trout)(s); } if (!done) fputs("}\n",ofp); fclose(ifp); fclose(ofp); exit(ok); } /*=-=-=-=-=-=-=-=-=-=-=-= Token Output Processing =-=-=-=-=-=-=-=-=-=*/ /* Text Token */ char *_text (char *s) { fputs("printf(\"",ofp); while (*s!='\0' && !ontoken(s)) { if (*s=='\n') fputs("\\n",ofp); else if (*s=='"') fputs("\\\"",ofp); else putc(*s,ofp); s++; } fputs("\");\n", ofp); return s; } /* Include File [#inc ] => #include */ char *_include(char *s) { LINE l; /* avoid default includes */ if ((strstr(s,"stddef.h")) || (strstr(s,"stdio.h"))) return eolp; strtok(s," "); sprintf(l,"#include %s\n", strtok(0,"]")); fputs(l,ofp); return eolp; } /* Print Data [#pd ] => printf("%d",); */ char *_define (char *s) { LINE l; strtok(s," "); sprintf(l,"\"%%d\",%s", s=strtok(0,"]")); prtf(l,ofp); return s+strlen(s)+1; } /* Based Size [#psb (st,c)] => printf("%d",(sizeof(st)-offsetof(st,c))); */ char *_sizeofb(char *s) { LINE l; char *t1,*t2,*t3,*t4; valtok(s+5,"(,)]"); /* validate token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> st */ while (*s!=',') s++; *s++='\0'; t3=s; /* t3 -> c */ while (*s!=')') s++; *s++='\0'; t4=s; /* t4 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%s(sizeof(%s)-offsetof(%s,%s))%s", t1, t2, t2,t3, t4); prtf(l,ofp); return s; } /* Sizeof Component [#psc (st,c)] => printf("%d",sizeof(objof(st,c))); */ char *_sizeofc(char *s) { LINE l; char *t1,*t2,*t3; valtok(s+5,"(,)]"); /* validate sizeof token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> st,c */ while (*s!=')') s++; *s++='\0'; t3=s; /* t3 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%ssizeof(objof(%s))%s", t1, t2, t3); prtf(l,ofp); return s; } /* Sizeof Type [#ps (t)] => printf("%d",sizeof(t)); */ char *_sizeof(char *s) { LINE l; char *t1,*t2,*t3; valtok(s+4,"()]"); /* validate sizeof token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> t */ while (*s!=')') s++; *s++='\0'; t3=s; /* t3 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%ssizeof(%s)%s", t1, t2,t3); prtf(l,ofp); return s; } /* Component Offset [#po (st,c)] => printf("%d",offsetof(st,c)); */ char *_offsetof(char *s) { LINE l; char *t1,*t2,*t3; valtok(s+4,"(,)]"); /* validate token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> st,c */ while (*s!=')') s++; *s++='\0'; t3=s; /* t3 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%soffsetof(%s)%s", t1, t2,t3); prtf(l,ofp); return s; } /* Based Offset - offset a - offset b [#pob (st,a,b)] => printf("%d",(offsetof(st,a)-offsetof(st,b))); */ char *_offsetofb(char *s) { LINE l; char *t1,*t2,*t3,*t4,*t5; valtok(s+5,"(,,)]"); /* validate offsetof token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> st */ while (*s!=',') s++; *s++='\0'; t3=s; /* t3 -> a */ while (*s!=',') s++; *s++='\0'; t4=s; /* t4 -> b */ while (*s!=')') s++; *s++='\0'; t5=s; /* t3 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%s(offsetof(%s,%s)-offsetof(%s,%s))%s", t1, t2,t3, t2,t4, t5); prtf(l,ofp); return s; } /* Pad Size [#pads (st,c)] => printf ("%d",(sizeof(st)-(offsetof(st,c) + sizeof(objof(st,c))))); */ char *_pads (char *s) { LINE l; char *t1,*t2,*t3,*t4; valtok(s+6,"(,)]"); /* validate token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> st */ while (*s!=',') s++; *s++='\0'; t3=s; /* t3 -> c */ while (*s!=')') s++; *s++='\0'; t4=s; /* t4 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%s(sizeof(%s)-(offsetof(%s,%s)+sizeof(objof(%s,%s))))%s", t1, t2, t2,t3, t2,t3, t4); prtf(l,ofp); return s; } /* Pad Offset [#pado (st,c)] => printf ("%d",(offsetof(st,c) + sizeof(objof(st,c)))); */ char *_pado (char *s) { LINE l; char *t1,*t2,*t3,*t4; valtok(s+6,"(,)]"); /* validate token */ while (*s!=' ') s++; t1=s+1; /* t1 -> */ while (*s!='(') s++; *s++='\0'; t2=s; /* t2 -> st */ while (*s!=',') s++; *s++='\0'; t3=s; /* t3 -> c */ while (*s!=')') s++; *s++='\0'; t4=s; /* t4 -> */ while (*s!=']') s++; *s++='\0'; sprintf(l,"\"%%d\",%s(offsetof(%s,%s)+sizeof(objof(%s,%s)))%s", t1, t2,t3, t2,t3, t4); prtf(l,ofp); return s; } /* [#c...C Code...#] */ char *_C_code(char *s) { char *p,*c; s=s+3; for(;;) { /* check that other "[#" tokens don't intervene */ if (c=strstr(s,"[#")) token_error(); /* turn once off if we encounter "main" */ if (c=strstr(s,"main")) once = 0; /* turn done on if we encounter "}" */ if (c=strstr(s,"}")) done = 1; /* end token on this line? */ if (p=strstr(s,"#]")) { while (s < p) { putc(*s,ofp); s++; } s=s+2; if (*s=='\n') putc(*s++,ofp); return s; } /* write line, read next */ fputs(s,ofp); if (s=readin(line)) continue; else token_error(); } } /* [#record] */ char *_record(char *s) { char *p, *cnm, *cty; NAME rnm; LINE t; /* rep spec temp file */ if (!repfp) repfp=opfile("c2a.rep", "w+", repfp); else fseek(repfp,0,0); /* Read Record Loop */ for (;;) { readin(line); /* Record Name: type is */ if ((p=strstr(line,"type")) && (strstr(line,"is"))) { strcpy(rnm, strtok(p+5," ")); /* copy */ /* type ... is record */ sprintf(t,"\"type %s is record\n\"",rnm); prtf(t,ofp); /* for ... use record */ prtf("\"\n\"",repfp); sprintf(t,"\"for %s use record\n\"",rnm); prtf(t,repfp); /* gobble record stmts, else parse the line */ readin(line); if (strstr(line," record")) continue; } /* end record; */ if (strstr(line,"end record;")) { sprintf(t,"\"%s\"",line); prtf(t, ofp); prtf(t, repfp); /* Copy Rep Spec */ fseek(repfp,0,0); while (fgets(t,MAXLINE,repfp)) fputs(t,ofp); fclose(repfp); return &line[strlen(line)]; } /* Components */ /* Name and Type */ cnm=strtok(line," "); while (*cnm==' ') cnm++; cty=strtok( 0," "); while (*cty==' ') cty++; /* Component_Name: Component_Type; */ sprintf(t," printf(\" %-20s%-20s\\n\");\n",cnm, cty); fputs(t,ofp); /* Component_Name at range 0 .. */ for (p=cnm;(*p!=':')&&(*p!='\0');p++) ; *p='\0'; /* trim punct */ for (p=cty;(*p!=';')&&(*p!='\0');p++) ; *p='\0'; sprintf(t," printf(\" %-20s at\");\n",cnm); fputs(t,repfp); sprintf(t," printf(\"%%4d range \", offsetof(struct %s,%s));\n",rnm,cnm); fputs(t,repfp); sprintf(t," printf(\"0 .. %%4d;\\n\", 8*sizeof(%s)-1);\n",cty); fputs (t,repfp); } } /*=-=-=-=-=-=-=-=-=-=-=-= Auxillary Routines =-=-=-=-=-=-=-=-=-=*/ /* prtf - printf surround output until '\0' */ char *prtf(char *s, FILE *fp) { fputs("printf(",fp); for (; *s!='\0'; s++) { (*s=='\n') ? fputs("\\n",fp) : putc(*s,fp); } fputs(");\n", fp); return s; } /* readin - read ifp, count lines, set eolp */ char *readin (char *line) { char *s; s=fgets(line, MAXLINE, ifp); lnum++; eolp = &line[strlen(line)]; return s; } /* Open tmp, in, and out files */ void init(int argc, char *argv[]) { int i; if (argc < 1) { ifp=stdin; ofp=stdout; return; } for (i=1; i0 && errno0) { printf (", line %d.\n", lnum); printf ("%s", line); } exit (errval); }