home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / motasm / motasmdoc / src / c / util < prev   
Encoding:
Text File  |  1995-09-10  |  14.4 KB  |  581 lines

  1. #include <setjmp.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <ctype.h>
  7.  
  8. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  9. #include "proto.h"
  10. #include "as.h"
  11. #include "structs.h"
  12. #include "riscos.h"
  13. #include "extvars.h"
  14. #include "swis.h"
  15.  
  16.  
  17. #define FATAL 2
  18. #define SERIOUS 1
  19. #define WARNING 0
  20. #define MAXERR 100
  21.  
  22. /* Throwback routines Copyright © 1992 Niklas Röjemo */
  23.  
  24.  
  25. extern struct oper table[];
  26.  
  27. int             pedantic = 1;
  28.  
  29. static int      ThrowbackStarted;
  30. static char    *Filename;
  31.  
  32. static char     errbuf[1024];
  33.  
  34.  
  35.  
  36. /*
  37.  * void errorInit(int throwback,char *np) { if(throwback) Filename =
  38.  * CanonicalisePath(np); else Filename = 0; }
  39.  */
  40.  
  41. void
  42. errorInit(int throwback, char *np)
  43. {
  44.         if (throwback)
  45.                 Filename = np;
  46.         else
  47.                 Filename = 0;
  48. #ifdef DEBUG
  49.         printf("filename = %s\n", np);
  50. #endif
  51. }
  52.  
  53. void
  54. errorFinish(void)
  55. {
  56.         if (ThrowbackStarted > 0) {
  57.                 ThrowbackStarted = 0;
  58.                 ThrowbackEnd();
  59.         }
  60. }
  61.  
  62. static void
  63. TB(int level, int lineno, char *error)
  64. {
  65.         os_error       *err;
  66.         if (!Filename)
  67.                 return;
  68.         if (!ThrowbackStarted) {
  69.                 err = ThrowbackStart();
  70.                 if (err) {
  71.                         fprintf(stderr, "ThrowbackStart %s\n", err->errmess);
  72.                         exit(-1);
  73.                 }
  74.                 err = ThrowbackSendStart(Filename);
  75.                 if (err) {
  76.                         if (pedantic)
  77.                                 fprintf(stderr, "ThrowbackSendStart %s", err->errmess);
  78.                         ThrowbackStarted = -1;
  79.                 } else
  80.                         ThrowbackStarted = 1;
  81.         }
  82.         if (ThrowbackStarted > 0)
  83.                 ThrowbackSendError(level, lineno, error);
  84. }
  85.  
  86. /*
  87.  * fatal --- fatal error handler
  88.  */
  89. void
  90. fatal(char *str)
  91. {
  92.         pouterror(FATAL, str);  /* added ver TER_2.0 4 Jul 89 */
  93.         TB(FATAL, Local_Line_num, str);
  94.  
  95. #ifdef IBM                      /* changed ver TER_2.0 */
  96.         exit(-1);
  97. #else
  98.         exit(10);               /* Amiga & UNIX prefer positive numbers for
  99.                                  * error minimal error is 10 (no system prob) */
  100. #endif
  101.         return;                 /* never executed */
  102. }
  103.  
  104. /*
  105.  * error --- error in a line print line number and error
  106.  */
  107. void
  108. error(char *str)
  109. {
  110.  
  111.         /*
  112.          * if(N_files > 1)      commented out test for N_files in rel TER_2.0
  113.          * because a single command line source file (which is what N_file
  114.          * counts) can have multiple include source files.
  115.          */
  116.  
  117.         pouterror(SERIOUS, str);
  118.         TB(SERIOUS, Local_Line_num, str);
  119. }
  120.  
  121. /*
  122.  * warn --- trivial error in a line print line number and error
  123.  */
  124. void
  125. warn(char *str)
  126. {
  127.         /*
  128.          * if(N_files > 1)      commented out in rel TER_2.0 same reason as
  129.          * above
  130.          */
  131.         pouterror(WARNING, str);
  132.         TB(WARNING, Local_Line_num, str);
  133. }
  134.  
  135.  
  136. /*
  137.  * delim --- check if character is a delimiter
  138.  */
  139. int
  140. delim(char c)
  141. {
  142.         if (any(c, " \t\n"))
  143.                 return (YES);
  144.         return (NO);
  145. }
  146.  
  147. /*
  148.  * skip_white --- move pointer to next non-whitespace char
  149.  */
  150. char           *
  151. skip_white(char *ptr)
  152. {
  153.         while (*ptr == BLANK || *ptr == TAB)
  154.                 ptr++;
  155.         return (ptr);
  156. }
  157.  
  158. /*
  159.  * eword --- emit a word to code file
  160.  */
  161. void
  162. eword(int wd)
  163. {
  164.         emit(hibyte(wd));
  165.         emit(lobyte(wd));
  166. }
  167.  
  168. /*
  169.  * emit --- emit a byte to code file
  170.  */
  171. int
  172. emit(unsigned char byte)
  173. {
  174. #ifdef DEBUG
  175.         printf("%2x @ %4x\n", byte, Pc);
  176. #endif
  177.         if (Pass == 1) {
  178.                 Pc++;
  179.                 return (YES);
  180.         }
  181.         if (P_total < P_LIMIT)
  182.                 P_bytes[P_total++] = byte;
  183.         E_bytes[E_total++] = byte;
  184.         Pc++;
  185.         if (E_total == E_LIMIT)
  186.                 f_record();
  187.         return (1);
  188. }
  189.  
  190. /*
  191.  * f_record --- flush record out in `S1' format
  192.  */
  193. void
  194. f_record(void)
  195. {                               /* made void for ANSI C compat ver TER_2.0
  196.                                  * 6/18/89 */
  197.         int             i;
  198.         int             chksum;
  199.  
  200.         if (Pass == 1)
  201.                 return;
  202.         if (E_total == 0) {
  203.                 E_pc = Pc;
  204.                 return;
  205.         }
  206.         F_total += E_total;     /* total bytes in file ver (TER)2.01 19 Jun
  207.                                  * 89 */
  208.         chksum = E_total + 3;   /* total bytes in this record */
  209.         chksum += lobyte(E_pc);
  210.         chksum += E_pc >> 8;
  211.         fprintf(Objfil, "S1");  /* record header preamble */
  212.         hexout(E_total + 3);    /* byte count +3 */
  213.         hexout(E_pc >> 8);      /* high byte of PC */
  214.         hexout(lobyte(E_pc));   /* low byte of PC */
  215.         for (i = 0; i < E_total; i++) {
  216.                 chksum += lobyte(E_bytes[i]);
  217.                 hexout(lobyte(E_bytes[i]));     /* data byte */
  218.         }
  219.         chksum = ~chksum;       /* one's complement */
  220.         hexout(lobyte(chksum)); /* checksum */
  221.         if (CRflag == 1)        /* test for CRflag added ver TER_1.1 */
  222.                 fprintf(Objfil, "%c\n", CR);    /* print in IBM format for
  223.                                                  * some PROM boxes */
  224.         else
  225.                 fprintf(Objfil, "\n");  /* this is original statement */
  226.         E_pc = Pc;
  227.         E_total = 0;
  228. }
  229.  
  230. char           *hexstr = "0123456789ABCDEF";
  231.  
  232. void
  233. hexout(int byte)
  234. {
  235.  
  236.         byte = lobyte(byte);
  237.         fprintf(Objfil, "%c%c", hexstr[byte >> 4], hexstr[byte & 017]);
  238.         return;
  239. }
  240.  
  241. /*
  242.  * print_line --- pretty print input line
  243.  */
  244. void
  245. print_line(void)
  246. {
  247.         int             i;
  248.         register char  *ptr;
  249.  
  250.         fprintf(Listfil, "%04d ", Line_num);
  251.         if (P_total || P_force)
  252.                 {fprintf(Listfil,"%04x", Old_pc);}
  253.         else
  254.                 {fprintf(Listfil,"    ");}
  255.  
  256.         for (i = 0; i < P_total && i < 6; i++)
  257.                 {fprintf(Listfil, " %02x", lobyte(P_bytes[i]));}
  258.         for (; i < 6; i++)
  259.                 {fprintf(Listfil,"   ");}
  260.         fprintf(Listfil,"  ");
  261.  
  262.         if (Cflag) {
  263.                 if (Cycles)
  264.                         {fprintf(Listfil, "[%2d ] ", Cycles);}
  265.                 else
  266.                         {fprintf(Listfil,"      ");}
  267.         }
  268.         ptr = Line;
  269.         while (*ptr != '\n')    /* just echo the line back out */
  270.                 {fputc(*ptr++,Listfil);}
  271.         for (; i < P_total; i++) {
  272.                 if (i % 6 == 0)
  273.                         {fprintf(Listfil,"\n    ");};
  274.                 fprintf(Listfil, " %02x", lobyte(P_bytes[i]));
  275.         }
  276.         if (Pflag50 && (++Page_lines >= PageLen))     /* form feed if flag set */
  277.                 NewPage();      /* ver (TER) 2.02 19 Jun 89 */
  278.         fprintf(Listfil,"\n");
  279. }
  280.  
  281. /*
  282.  * any --- does str contain c?
  283.  */
  284. int
  285. any(char c, char *str)
  286. {
  287.         while (*str != EOS)
  288.                 if (*str++ == c)
  289.                         return (YES);
  290.         return (NO);
  291. }
  292.  
  293. /*
  294.  * mapdn --- convert A-Z to a-z
  295.  */
  296. char
  297. mapdn(char c)
  298. {
  299.         if (c >= 'A' && c <= 'Z')
  300.                 return ((char) (c + 040));      /* cast value to char for
  301.                                                  * ANSI C, ver TER_2.0 */
  302.         return (c);
  303. }
  304.  
  305. /*
  306.  * lobyte --- return low byte of an int
  307.  */
  308. unsigned char
  309. lobyte(int i)
  310. {
  311.         return (i & 0xFF);
  312. }
  313.  
  314.  
  315. /*
  316.  * hibyte --- return high byte of an int
  317.  */
  318. unsigned char
  319. hibyte(int i)
  320. {
  321.         return ((i >> 8) & 0xFF);
  322. }
  323.  
  324. /*
  325.  * head --- is str2 the head of str1?
  326.  */
  327. int
  328. head(char *str1, char *str2)
  329. {
  330.         while (*str1 != EOS && *str2 != EOS) {
  331.                 if (*str1 != *str2)
  332.                         break;
  333.                 str1++;
  334.                 str2++;
  335.         }
  336.         if (*str1 == *str2)
  337.                 return (YES);
  338.         if (*str2 == EOS)
  339.                 if (any(*str1, " \t\n,+-];*"))
  340.                         return (YES);
  341.         return (NO);
  342. }
  343.  
  344. /*
  345.  * alpha --- is character a legal letter
  346.  */
  347. int
  348. alpha(char c)
  349. {
  350.         if (c <= 'z' && c >= 'a')
  351.                 return (YES);
  352.         if (c <= 'Z' && c >= 'A')
  353.                 return (YES);
  354.         if (c == '_')
  355.                 return (YES);
  356.         if (c == '.')
  357.                 return (YES);
  358.         return (NO);
  359. }
  360.  
  361.  
  362. /*
  363.  * alphan --- is character a legal letter or digit
  364.  */
  365. int
  366. alphan(char c)
  367. {
  368.         if (alpha(c))
  369.                 return (YES);
  370.         if (c <= '9' && c >= '0')
  371.                 return (YES);
  372.         if (c == '$')
  373.                 return (YES);   /* allow imbedded $ */
  374.         if (c == '@')
  375.                 return (YES);   /* allow imbedded @, added ver TER_2.0 added
  376.                                  * to permit redefinable variables */
  377.         return (NO);
  378. }
  379.  
  380. /*
  381.  * white --- is character whitespace?
  382.  */
  383. int
  384. white(char c)
  385. {
  386.         if (c == TAB || c == BLANK || c == '\n')
  387.                 return (YES);
  388.         return (NO);
  389. }
  390.  
  391. /*
  392.  * alloc --- allocate memory
  393.  */
  394. char           *
  395. alloc(int nbytes)
  396. {
  397.  
  398.         return (malloc(nbytes));
  399. }
  400.  
  401. /*
  402.  * FNameGet --- Find a file name <file> or "file" in the Operand string added
  403.  * ver TER_2.0 6/17/89 note: this routine will return a file name with white
  404.  * space if between delimeters.  This is permitted in AmigaDOS.  Other DOS
  405.  * may hiccup or just use name up to white space
  406.  */
  407.  
  408. int
  409. FNameGet(char *NameString)
  410. /* char *NameString;        pointer to output string */
  411. {
  412.         char           *frompoint;      /* pointers to input string, don't
  413.                                          * bash Operand */
  414.         char           *topoint;/* pointer to output string, don't bash
  415.                                  * NameString */
  416.  
  417.         frompoint = Operand;    /* include file name is in parsed string
  418.                                  * Operand */
  419.         topoint = NameString;   /* copy of pointer to increment in copying */
  420.         if (*frompoint != '<' && *frompoint != '"')
  421.                 return (0);     /* bad syntax */
  422.         frompoint++;            /* skip < or " */
  423.  
  424.         while (*frompoint != '>' && *frompoint != '"') {        /* look for delimeter */
  425.                 if (*frompoint == EOS)
  426.                         return (0);     /* missing delimeter */
  427.                 *topoint++ = *frompoint++;      /* copy path & file name for
  428.                                                  * DOS */
  429.         }
  430.  
  431.         *topoint = EOS;         /* terminate file name */
  432. #ifdef DEBUG2
  433.         printf("FNameGet: file name=%s\n", NameString);
  434. #endif
  435.         return (1);             /* proper syntax anyway */
  436. }
  437.  
  438. /*
  439.  * --- strsave()  find a place to save a string & return pointer to it added
  440.  * ver TER_2.0 6/18/89  function taken from Kernighan & Ritchie 78
  441.  */
  442. char           *
  443. strsave(char *s)
  444. {
  445.         char           *p;
  446.  
  447.         if ((p = alloc(strlen(s) + 1)) != NULL)
  448.                 strcpy(p, s);
  449.         return (p);
  450. }
  451.  
  452. /*
  453.  * pouterror() ---- print out standard error header added rel TER_2.0 6/18/89
  454.  */
  455.  
  456. void
  457. pouterror(int err_type, char *str)
  458. {
  459.         fprintf(stderr, "%s, line no. ", Argv[Cfn]);    /* current file name */
  460.         fprintf(stderr, "%d: ", Local_Line_num);        /* current line number */
  461.         fprintf(stderr, "%s\n", str);
  462.         /*
  463.          * NOTE: THERE IS NO \n ! Calling procedure supplies suffixing error
  464.          * message and \n. viz. file pseudo.c procedure do_pseudo in case
  465.          * INCLUDE. Note also that error count is incremented.
  466.          */
  467.         Page_lines++;           /* increment lines per page */
  468.         if (err_type != WARNING) {
  469.                 Err_count++;
  470.         }
  471. }
  472.  
  473. /*
  474.  * New Page() --- form feed a new page, print heading & inc page number Moved
  475.  * here from do_pseudo (pseudo.c) in ver (TER) 2.02 19 Jun 89 so that can
  476.  * call from print_line() as well for p50 option.
  477.  */
  478.  
  479. void
  480. NewPage(void)
  481. {
  482.         Page_lines = 0;         /* ver TER_2.08 so that OPT PAGE works */
  483.         fprintf(Listfil, "\n\f");
  484.         fprintf(Listfil, "%-10s", Argv[Cfn]);
  485.         fprintf(Listfil, "                                   ");
  486.         fprintf(Listfil, "page %3d\n", Page_num++);
  487. }
  488.  
  489.  
  490. /*
  491.  * LastChar() ----- return a pointer to the last character in a string
  492.  * Exception: will return garbage if NULL string
  493.  */
  494.  
  495. char           *
  496. LastChar(char *strpt)
  497. /* strpt;     pointer to string to be examined */
  498. {
  499.         char           *c;
  500.  
  501.         c = strpt;              /* don't zap original */
  502.         while (*c != EOS)       /* search for end */
  503.                 c++;
  504.         return (--c);           /* back up one to last character */
  505. }
  506.  
  507.  
  508. #define DDEUtils_ThrowbackRegister   0x42585
  509. #define DDEUtils_ThrowbackUnRegister 0x42586
  510. #define DDEUtils_ThrowbackStart      0x42587
  511. #define DDEUtils_ThrowbackSend       0x42588
  512. #define DDEUtils_ThrowbackEnd        0x42580
  513. #define Throwback_ReasonProcessing     0
  514. #define Throwback_ReasonErrorDetails   1
  515. #define Throwback_ReasonInfoDetails    2
  516.  
  517.  
  518.  
  519. os_error       *
  520. ThrowbackStart(void)
  521. {
  522.           _kernel_swi_regs regs;
  523.           return (os_error *) _kernel_swi(os_X | DDEUtils_ThrowbackStart, ®s, ®s);
  524. /*        return os_swi0(os_X | DDEUtils_ThrowbackStart);*/
  525. }
  526.  
  527. static char    *ErrorFile;
  528.  
  529. os_error       *
  530. ThrowbackSendStart(char *filename)
  531. {
  532.         _kernel_swi_regs regs;
  533.         ErrorFile = filename;
  534.  
  535.         regs.r[0] = Throwback_ReasonProcessing;
  536.         regs.r[1] = 0;
  537.         regs.r[2] = (int) filename;
  538.         return (os_error *) _kernel_swi(os_X |  DDEUtils_ThrowbackSend,  ®s, ®s);
  539. /*        return os_swi3(os_X | DDEUtils_ThrowbackSend,
  540.                        Throwback_ReasonProcessing, 0, (int) filename);
  541. */
  542. }
  543.  
  544. os_error       *
  545. ThrowbackSendError(int level, int lineno, char *error)
  546. {
  547.         _kernel_swi_regs regs;
  548.         regs.r[1] = 0;
  549.         regs.r[2] = (int) ErrorFile;
  550.         regs.r[3] = lineno;
  551.         regs.r[5] = (int) error;
  552.         if (level == ThrowbackInfo) {
  553.           regs.r[0] = Throwback_ReasonInfoDetails;
  554.           regs.r[4] = 0;
  555.         } else {
  556.           regs.r[0] = Throwback_ReasonErrorDetails;
  557.           regs.r[4] = level;
  558.         }
  559.         return (os_error *) _kernel_swi(os_X |  DDEUtils_ThrowbackSend,  ®s, ®s);
  560.  
  561.  
  562. /*                return os_swi6(os_X | DDEUtils_ThrowbackSend,
  563.                             Throwback_ReasonInfoDetails, 0, (int) ErrorFile,
  564.                                lineno, 0, (int) error);
  565.         else
  566.                 return os_swi6(os_X | DDEUtils_ThrowbackSend,
  567.                            Throwback_ReasonErrorDetails, 0, (int) ErrorFile,
  568.                                lineno, level, (int) error);
  569. */
  570. }
  571.  
  572. os_error       *
  573. ThrowbackEnd(void)
  574. {
  575.         _kernel_swi_regs regs;
  576.  
  577.         return (os_error *) _kernel_swi(os_X | DDEUtils_ThrowbackEnd, ®s, ®s);
  578.  
  579. /*        return os_swi0(os_X | DDEUtils_ThrowbackEnd);*/
  580. }
  581.