home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / amigem.lha / amigem / genglue / genglue.c next >
Encoding:
C/C++ Source or Header  |  1995-01-10  |  5.4 KB  |  242 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include "genglue.h"
  5. #include "machine.h"
  6.  
  7. int reverse,basepar,baserel,single;
  8. char *precede="",*precedevec="";
  9. char *progname;
  10.  
  11. char namebuf[80];
  12. int regbuf[NUMREGS];
  13. int regbufcnt;
  14. int liboffset;
  15. int libbasereg=DEFAULTBASEREG;
  16. char libbasevar[30];
  17. int preserve;
  18. int linecount=0;
  19. int iflag;
  20.  
  21. void skipcomment(void)
  22. {
  23.   int c;
  24.   while((c=getchar())!='\n'&&c!=EOF)
  25.     ;
  26.   ungetc(c,stdin);
  27. }
  28.  
  29. char *commands[]=
  30. {
  31.   "flags","offset","basereg","basevar"
  32. };
  33.  
  34. void getcommand(void)
  35. {
  36.   char command[20];
  37.   int i,c,commandcount=0;
  38.   while(islower(c=getchar())&&commandcount<20)
  39.     command[commandcount++]=c;
  40.   if(c!=' ')
  41.   {
  42.     exit(20);
  43.   }
  44.   for(i=0;i<sizeof(commands)/sizeof(char *);i++)
  45.     if(!strncmp(command,commands[i],commandcount))
  46.     {
  47.       switch(i)
  48.       {
  49.         case 0: /* flags */
  50.         {
  51.           int d;
  52.           d=getchar();
  53.           if(d=='-'||d=='+')
  54.           {
  55.             while(islower(c=getchar()))
  56.               switch(c)
  57.               {
  58.                 case 'p': /* Preserve all registers */
  59.                   preserve=(d=='+'?2:0);
  60.                   break;
  61.                 case 'q': /* Preserve all address registers */
  62.                   preserve=(d=='+');
  63.                   break;
  64.                 case 'b': /* Function may destroy contents of a5/a6 too */
  65.                   preserve=(d=='+'?-1:0);
  66.                   break;
  67.                 case 'd': /* Function may destroy all registers */
  68.                   preserve=(d=='+'?-2:0);
  69.                   break;
  70.                 case 'i': /* Return result in Z bit of ccr */
  71.                   iflag=(d=='+');
  72.                   break;
  73.                 default:
  74.                   fprintf(stderr,"Invalid flag: %c\n",c);
  75.                   exit(20);
  76.                   break;
  77.           }
  78.       }else
  79.             ungetc(d,stdin);
  80.           ungetc(c,stdin);
  81.           break;
  82.     }
  83.       case 1: /* offset */
  84.       {
  85.         liboffset=0;
  86.         while(isdigit(c=getchar()))
  87.           liboffset=liboffset*10+(c-'0');
  88.         ungetc(c,stdin);
  89.         break;
  90.       }
  91.       case 2: /* basereg */
  92.       {
  93.         if(regnum(c=getchar())<0)
  94.           ERROR("Invalid register name");
  95.         libbasereg=regnum(c);
  96.         if(libbasereg==SPREGNUM)
  97.           ERROR("Invalid base register");
  98.         break;
  99.       }
  100.       case 3: /* basevar */
  101.       {
  102.         int basenamecnt=0;
  103.         if(isalpha(c=getchar())||c=='_')
  104.         {
  105.           libbasevar[basenamecnt++]=c;
  106.           while((isalnum(c=getchar())||c=='_')&&basenamecnt<29)
  107.             libbasevar[basenamecnt++]=c;
  108.     }
  109.         libbasevar[basenamecnt++]='\0';
  110.         if(!basenamecnt)
  111.           ERROR("Invalid base variable name");
  112.         ungetc(c,stdin);
  113.         break;
  114.       }
  115.       default:
  116.         ERROR("Invalid command");
  117.         break;
  118.       }
  119.     }
  120. }
  121.  
  122. void getline(void)
  123. {
  124.   int c;
  125.   int namebufcnt=0;
  126.   regbufcnt=0;
  127.   while(((c=getchar())=='_'||isalnum(c))&&namebufcnt<79)
  128.     namebuf[namebufcnt++]=c;
  129.   namebuf[namebufcnt++]='\0';
  130.   if(c==',')
  131.   {
  132.     while(regnum(c=getchar())>=0&®bufcnt<NUMREGS)
  133.       regbuf[regbufcnt++]=regnum(c);
  134.   }
  135.   ungetc(c,stdin);
  136. }
  137.  
  138. void putglue(void)
  139. {
  140.   if(reverse)
  141.     reverseglue();
  142.   else
  143.     normglue();
  144. }
  145.  
  146. int main(int argc,char *argv[])
  147. {
  148.   int i,fc=0,c;
  149.  
  150.   progname=argv[0];
  151.  
  152.   for(i=1;i<argc;i++)
  153.   {
  154.     if(argv[i][0]!='-')
  155.     {
  156.       switch(fc++)
  157.       {
  158.         case 0:
  159.           if(freopen(argv[i],"r",stdin)==NULL)
  160.           {
  161.             fprintf(stderr,"%s: Couldn't open input file '%s'\n",progname,argv[i]);
  162.             exit(20);
  163.           }
  164.           break;
  165.         case 1:
  166.           if(freopen(argv[i],"w",stdout)==NULL)
  167.           {
  168.             fprintf(stderr,"%s: Couldn't open output file '%s'\n",progname,argv[i]);
  169.             exit(20);
  170.           }
  171.           break;          
  172.       }
  173.     }else
  174.     {
  175.       if(argv[i][1])
  176.         switch(argv[i][1])
  177.         {
  178.           case 'r': /* Build the library part of the glue */
  179.             reverse=1;
  180.             break;
  181.           case 'l': /* Add library base to the paramater list (as first argument) */
  182.             basepar=1;
  183.             break;
  184.           case 'b': /* Baserelative code */
  185.             baserel=1;
  186.             break;
  187.           case 's': /* Generate single files */
  188.             single=1;
  189.             break;
  190.           case 'p': /* Precede functionnames with string */
  191.             if(++i>=argc)
  192.               ERROR("Missing argument");
  193.             precede=argv[i];
  194.             break;
  195.           case 'q': /* Precede the jump vector's name with string */
  196.             if(++i>=argc)
  197.               ERROR("Missing argument");
  198.             precedevec=argv[i];
  199.             break;
  200.           default:
  201.             fprintf(stderr,"%s: Invalid option -%c\n",argv[0],argv[i][1]);
  202.             break;
  203.         }
  204.     }
  205.   }
  206.   while((c=getchar())!=EOF)
  207.   {
  208.     linecount++;
  209.     if(c=='#')
  210.       skipcomment();
  211.     else if(c=='@')
  212.       getcommand();
  213.     else if(isalpha(c)||c=='_')
  214.     {
  215.       ungetc(c,stdin);
  216.       getline();
  217.       if(single)
  218.       {
  219.         char namebuf2[100];
  220.         namebuf2[0]='\0';
  221.         strncat(namebuf2,precede,100);
  222.         strncat(namebuf2,namebuf,100);
  223.         strncat(namebuf2,".s"   ,100);
  224.  
  225.         if(freopen(namebuf2,"w",stdout)==NULL)
  226.         {
  227.           fprintf(stderr,"%s: Couldn't open output file '%s'\n",progname,namebuf2);
  228.           exit(20);
  229.         }        
  230.       }
  231.       putglue();
  232.       liboffset++;
  233.     }else if(c=='\n')
  234.       ungetc(c,stdin);
  235.     else
  236.       ERROR("Syntax error");
  237.     if((c=getchar())!='\n'&&c!=EOF)
  238.       ERROR("Syntax error");
  239.   }
  240.   return 0;
  241. }
  242.