home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / e / amiga_e_v2.1b / sources / utilities / iconvert.e < prev    next >
Text File  |  1994-05-26  |  9KB  |  272 lines

  1. /* Iconvert.e
  2.  
  3.    This little utility converts a '.i' assembly include file
  4.    into an E binary module.
  5.    it understands '=' and 'EQU' for constant definitions, and builds
  6.    OBJECTs out of STRUCTURE definitions (from "exec/types.i").
  7.    it needs a macroassembler like A68k to run.
  8.    USAGE: iconvert <.ifile>       */
  9.  
  10. OBJECT def
  11.   type:INT,name
  12. ENDOBJECT
  13.  
  14. ENUM T_ARRAY,T_CHAR,T_INT,T_LONG=4,T_CONST=$10,T_STRUCT,T_END
  15. ENUM ER_NONE,ER_IN,ER_OUT,ER_MEM,ER_WORK,ER_BREAK,ER_FORM,ER_TEMPW,
  16.      ER_INVOKE,ER_TEMPR,ER_OFORM,ER_I
  17.  
  18. CONST MAX_DEF=2500,IDMAX=10
  19.  
  20. DEF defs[MAX_DEF]:ARRAY OF def,
  21.     infile[100]:STRING,outfile[100]:STRING,
  22.     handle=NIL,flen,buf,bbuf,defn=0,line=0,mode=0,a
  23.  
  24. PROC main()
  25.   WriteF('Iconvert v0.1 1992 $#%!\n\n')
  26.   readinfile()
  27.   collectidents()
  28.   makeasmfile()
  29.   invokea68k()
  30.   readbinary()
  31.   makemodule()
  32.   error(ER_NONE)
  33. ENDPROC
  34.  
  35. PROC readinfile()
  36.   DEF len
  37.   StrCopy(infile,arg,ALL)
  38.   len:=EstrLen(infile)-2
  39.   IF infile[len]<>"." THEN error(ER_I)
  40.   StrCopy(outfile,arg,ALL); outfile[len+1]:="m"
  41.   IF (flen:=FileLength(infile))<1 THEN error(ER_IN)
  42.   IF (buf:=New(flen+1))=NIL THEN error(ER_MEM)
  43.   buf[flen]:=10
  44.   IF (handle:=Open(infile,OLDFILE))=NIL THEN error(ER_IN)
  45.   IF Read(handle,buf,flen)<>flen THEN error(ER_IN)
  46.   Close(handle); handle:=NIL
  47. ENDPROC
  48.  
  49. PROC collectidents()
  50.   DEF p,a,id[IDMAX]:ARRAY OF LONG,num,f,c,end,zero=NIL,macro=FALSE
  51.   DEF struct=FALSE,d:PTR TO def,size,work[10]:STRING
  52.   WriteF('Now trying to convert "\s".\n',infile)
  53.   INC line; p:=buf; end:=p+flen; d:=defs
  54.   WHILE p<end
  55.     FOR a:=0 TO IDMAX-1 DO id[a]:=0
  56.     num:=0; f:=TRUE
  57.     WHILE f
  58.       c:=p[]++
  59.       IF zero; zero[]:=0; zero:=NIL; ENDIF
  60.       IF (c=10) OR (c=0)
  61.         f:=FALSE
  62.       ELSEIF (c<=" ") OR (c=",")
  63.       ELSEIF (c=";") OR (c="*")
  64.         f:=FALSE
  65.         WHILE p[]++<>10 DO NOP
  66.       ELSE
  67.         id[num]:=p-1
  68.         WHILE ((c:=p[]++)>" ") AND (c<>",") AND (c<>";") DO NOP
  69.         p--; zero:=p
  70.         IF num++=IDMAX THEN error(ER_WORK)
  71.       ENDIF
  72.     ENDWHILE
  73.     IF num
  74.       size:=-1
  75.       IF StrCmp(id[1],'MACRO',ALL)
  76.         macro:=TRUE
  77.       ELSEIF StrCmp(id[1],'EQU',ALL) OR StrCmp(id[1],'=',ALL) OR StrCmp(id[1],'equ',ALL)
  78.         IF macro=FALSE
  79.           d.type:=T_CONST
  80.           d.name++:=id[0]
  81.           defn++
  82.         ENDIF
  83.       ELSEIF StrCmp(id[0],'STRUCTURE',ALL)
  84.         struct:=TRUE
  85.         d.type:=T_STRUCT
  86.         d.name++:=id[1]
  87.         defn++
  88.         IF (InStr(id[2],'SIZEOF',0)<>-1) OR (InStr(id[2],'SIZE',0)<>-1)
  89.           IF defn>=MAX_DEF THEN error(ER_WORK)
  90.           d.type:=T_ARRAY
  91.           c:=InStr(id[2],'_',0)
  92.           IF c<>-1 THEN PutChar(id[2]+c,0)
  93.           d.name++:=id[2]
  94.           defn++
  95.     ELSEIF (Val(id[2],{c})<>0) OR (c=0)
  96.           WriteF('WARNING: object "\s" does not start at offset 0\n',id[1])
  97.         ENDIF
  98.       ELSEIF StrCmp(id[0],'LABEL',ALL)
  99.         IF struct=FALSE THEN error(ER_FORM)
  100.         IF (InStr(id[1],'SIZEOF',0)<>-1) OR (InStr(id[1],'SIZE',0)<>-1)
  101.           struct:=FALSE
  102.           d.type:=T_END
  103.           d.name++:=id[1]
  104.           defn++
  105.         ENDIF
  106.       ELSEIF StrCmp(id[0],'BYTE',ALL); size:=1
  107.       ELSEIF StrCmp(id[0],'UBYTE',ALL); size:=1
  108.       ELSEIF StrCmp(id[0],'WORD',ALL); size:=2
  109.       ELSEIF StrCmp(id[0],'UWORD',ALL); size:=2
  110.       ELSEIF StrCmp(id[0],'SHORT',ALL); size:=2
  111.       ELSEIF StrCmp(id[0],'USHORT',ALL); size:=2
  112.       ELSEIF StrCmp(id[0],'LONG',ALL); size:=4
  113.       ELSEIF StrCmp(id[0],'ULONG',ALL); size:=4
  114.       ELSEIF StrCmp(id[0],'APTR',ALL); size:=4
  115.       ELSEIF StrCmp(id[0],'BPTR',ALL); size:=4
  116.       ELSEIF StrCmp(id[0],'CPTR',ALL); size:=4
  117.       ELSEIF StrCmp(id[0],'BSTR',ALL); size:=4
  118.       ELSEIF StrCmp(id[0],'BOOL',ALL); size:=2
  119.       ELSEIF StrCmp(id[0],'FPTR',ALL); size:=4
  120.       ELSEIF StrCmp(id[0],'STRUCT',ALL); size:=0
  121.       ELSEIF StrCmp(id[1],'MACRO',ALL)
  122.         macro:=TRUE
  123.       ELSEIF StrCmp(id[0],'ENDM',ALL)
  124.         macro:=FALSE
  125.       ELSEIF StrCmp(id[0],'BITDEF',ALL)     /* depends on correctness */
  126.         c:=id[1]-1
  127.         FOR a:=1 TO id[2]-id[1]-1 DO c[]++:=c[1]
  128.         c[]++:="F"; c[]++:="_"
  129.         d.type:=T_CONST
  130.         d.name++:=id[1]-1
  131.         defn++
  132.       ELSEIF StrCmp(id[0],'EITEM',ALL)
  133.         d.type:=T_CONST
  134.         d.name++:=id[1]
  135.         defn++
  136.       ELSEIF StrCmp(id[0],'DEVCMD',ALL)
  137.         d.type:=T_CONST
  138.         d.name++:=id[1]
  139.         defn++
  140.       ELSEIF StrCmp(id[1],'SET',ALL) OR StrCmp(id[0],'IFND',ALL) OR StrCmp(id[0],'ENDC',ALL) OR StrCmp(id[0],'INCLUDE',ALL) OR StrCmp(id[0],'ENUM',ALL) OR StrCmp(id[0],'LIBENT',ALL) OR StrCmp(id[0],'LIBINIT',ALL) OR StrCmp(id[0],'LIBDEF',ALL) OR StrCmp(id[0],'DEVINIT',ALL) OR StrCmp(id[0],'FUNCDEF',ALL) OR StrCmp(id[0],'include',ALL) OR StrCmp(id[0],'IFD',ALL)
  141.       ELSE
  142.         IF macro=FALSE THEN error(ER_FORM)
  143.       ENDIF
  144.       IF size<>-1
  145.         IF (InStr(id[1],'Kludge',0)<>-1)       /* ask for deletion */
  146.           WriteF('Skip member "\s" (y/n)? >',id[1])
  147.           Read(stdout,work,2)
  148.           c:=work[0]
  149.         ELSE
  150.           c:=0
  151.         ENDIF
  152.         IF (c<>"y") AND (macro=FALSE)
  153.           IF struct=FALSE THEN error(ER_FORM)
  154.           IF size=1 THEN d.type:=T_CHAR ELSE IF size=2 THEN d.type:=T_INT ELSE IF size=4 THEN d.type:=T_LONG ELSE d.type:=T_ARRAY
  155.           d.name++:=id[1]
  156.           defn++
  157.         ENDIF
  158.       ENDIF
  159.       IF defn>=MAX_DEF THEN error(ER_WORK)
  160.     ENDIF
  161.     IF CtrlC() THEN error(ER_BREAK)
  162.     IF (line AND $F)=0 THEN WriteF('line=\d\b',line)
  163.     INC line
  164.   ENDWHILE
  165.   line:=0
  166. ENDPROC
  167.  
  168. PROC makeasmfile()
  169.   DEF a,oldout,d:PTR TO def
  170.   IF (handle:=Open('ram:iconvert.s',NEWFILE))=NIL THEN error(ER_TEMPW)
  171.   IF defn=0 THEN error(ER_FORM)
  172.   d:=defs
  173.   oldout:=SetStdOut(handle)
  174.   WriteF(' INCLUDE "\s"\n\n',infile)
  175.   FOR a:=1 TO defn
  176.     WriteF(' DC.L \s\n',d.name++)
  177.   ENDFOR
  178.   WriteF('\n END\n')
  179.   SetStdOut(oldout)
  180.   Close(handle); handle:=NIL
  181. ENDPROC
  182.  
  183. PROC invokea68k()
  184.   IF Execute('A68k -iINCLUDES: ram:iconvert.s',NIL,stdout)=FALSE THEN error(ER_INVOKE)
  185. ENDPROC
  186.  
  187. PROC readbinary()
  188.   DEF bsize
  189.   bsize:=defn*4+32
  190.   IF FileLength('ram:iconvert.o')<>bsize THEN error(ER_TEMPR)
  191.   bbuf:=New(bsize)
  192.   IF bbuf=NIL THEN error(ER_MEM)
  193.   IF (handle:=Open('ram:iconvert.o',OLDFILE))=NIL THEN error(ER_TEMPR)
  194.   IF Read(handle,bbuf,bsize)<>bsize THEN error(ER_TEMPR)
  195.   Close(handle); handle:=NIL
  196. ENDPROC
  197.  
  198. PROC makemodule()
  199.   DEF v:PTR TO LONG,work[3]:ARRAY OF INT,d:PTR TO def,l,x,obj=NIL
  200.   v:=bbuf+28; d:=defs
  201.   IF (handle:=Open(outfile,NEWFILE))=NIL THEN error(ER_OUT)
  202.   Write(handle,'EMOD',4)
  203.   FOR a:=1 TO defn
  204.     IF d.type=T_CONST
  205.       IF mode=2 THEN endobj(obj)
  206.       IF mode=0 THEN Write(handle,[1]:INT,2)
  207.       l:=StrLen(d.name)+1
  208.       work[0]:=IF Odd(l) THEN l+1 ELSE l
  209.       PutLong(work+2,v[]++)
  210.       Write(handle,work,6)
  211.       UpperStr(d.name)
  212.       Write(handle,d.name++,l)
  213.       IF Odd(l) THEN Write(handle,'',1)
  214.       mode:=1
  215.     ELSEIF d.type=T_END
  216.       IF mode<>2 THEN error(ER_OFORM)
  217.       mode:=0
  218.       Write(handle,[0,v[]++]:INT,4)
  219.       d++
  220.     ELSE
  221.       IF (mode=2) AND (d.type=T_STRUCT) THEN endobj(obj)
  222.       IF mode=1 THEN Write(handle,[0]:INT,2)
  223.       IF mode<>2
  224.         Write(handle,[2]:INT,2)
  225.         IF d.type<>T_STRUCT THEN error(ER_OFORM)
  226.         obj:=d.name
  227.       ENDIF
  228.       work[1]:=IF d.type=T_STRUCT THEN -1 ELSE d.type
  229.       work[2]:=v[]++
  230.       x:=InStr(d.name,'_',0)
  231.       IF x<>-1 THEN d.name:=d.name+x+1
  232.       LowerStr(d.name)
  233.       l:=StrLen(d.name)+1
  234.       work[0]:=IF Odd(l) THEN l+1 ELSE l
  235.       Write(handle,work,6)
  236.       Write(handle,d.name++,l)
  237.       IF Odd(l) THEN Write(handle,'',1)
  238.       mode:=2
  239.     ENDIF
  240.   ENDFOR
  241.   IF mode=2 THEN endobj(obj)
  242.   IF mode=1 THEN Write(handle,[0]:INT,2)
  243.   Close(handle); handle:=NIL
  244. ENDPROC
  245.  
  246. PROC endobj(obj)
  247.   Write(handle,[0,-1]:INT,4)
  248.   WriteF('WARNING: object "\s" has no SIZE\n',obj)
  249.   mode:=0
  250. ENDPROC
  251.  
  252. PROC error(er)
  253.   IF handle THEN Close(handle)
  254.   SELECT er
  255.     CASE ER_NONE;   WriteF('Done.\n')
  256.     CASE ER_IN;     WriteF('Could not read "\s"\n',infile)
  257.     CASE ER_OUT;    WriteF('Could not write "\s"\n',outfile)
  258.     CASE ER_MEM;    WriteF('Could not allocate memory\n')
  259.     CASE ER_WORK;   WriteF('Work buffer overflow\n')
  260.     CASE ER_BREAK;  WriteF('User terminated convertion\n')
  261.     CASE ER_FORM;   WriteF('.i file format error\n')
  262.     CASE ER_TEMPW;  WriteF('Trouble creating temporarily file\n')
  263.     CASE ER_TEMPR;  WriteF('Trouble reading temporarily file\n')
  264.     CASE ER_INVOKE; WriteF('Could not invoke A68k\n')
  265.     CASE ER_OFORM;  WriteF('Error in object order line \d in "ram:iconvert.s"\n',a+1)
  266.     CASE ER_I;      WriteF('Not a ".i" file: "\s"\n',infile)
  267.   ENDSELECT
  268.   IF line THEN WriteF('At line \d in file "\s"\n',line,infile)
  269.   IF er>0 THEN DeleteFile(outfile)
  270.   CleanUp(0)
  271. ENDPROC
  272.