home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / dev / p2c-1.20.lha / P2C / src / stuff.c < prev    next >
C/C++ Source or Header  |  1993-12-21  |  14KB  |  840 lines

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989, 1990, 1991 Free Software Foundation.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation (any version).
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING.  If not, write to
  16. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  17.  
  18.  
  19.  
  20. #define PROTO_STUFF_C
  21. #include "trans.h"
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28. /* Called regularly, for debugging purposes */
  29.  
  30. void debughook()
  31. {
  32. #if 0
  33.     Symbol *sp;
  34.     Meaning *mp;
  35.     static int flag = 0;
  36.  
  37.     sp = findsymbol_opt("DEFSTIPPLES");
  38.     if (sp) {
  39.     mp = sp->mbase;
  40.     if (mp) {
  41.         flag = 1;
  42.         if (mp->sym != sp || mp->snext)
  43.         intwarning("debughook", "Inconsistent!");
  44.     } else
  45.         if (flag)
  46.         intwarning("debughook", "Missing!");
  47.     }
  48. #endif
  49. }
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56. /* The "Strlist" data type, like in NEWASM */
  57.  
  58.  
  59. /* Add a string to end of strlist */
  60.  
  61. Strlist *strlist_append(base, s)
  62. register Strlist **base;
  63. register char *s;
  64. {
  65.     register Strlist *p;
  66.  
  67.     while (*base)
  68.         base = &(*base)->next;
  69.     *base = p = ALLOCV(sizeof(Strlist) + strlen(s), Strlist, strlists);
  70.     p->next = NULL;
  71.     p->value = 0;
  72.     strcpy(p->s, s);
  73.     return p;
  74. }
  75.  
  76.  
  77.  
  78. /* Insert a string at front of strlist */
  79.  
  80. Strlist *strlist_insert(base, s)
  81. register Strlist **base;
  82. register char *s;
  83. {
  84.     register Strlist *p;
  85.  
  86.     p = ALLOCV(sizeof(Strlist) + strlen(s), Strlist, strlists);
  87.     p->next = *base;
  88.     *base = p;
  89.     p->value = 0;
  90.     strcpy(p->s, s);
  91.     return p;
  92. }
  93.  
  94.  
  95.  
  96. /* Add a string to a sorted strlist */
  97.  
  98. Strlist *strlist_add(base, s)
  99. register Strlist **base;
  100. register char *s;
  101. {
  102.     register Strlist *p;
  103.  
  104.     while ((p = *base) && strcmp(p->s, s) < 0)
  105.         base = &p->next;
  106.     if (!p || strcmp(p->s, s)) {
  107.         p = ALLOCV(sizeof(Strlist) + strlen(s), Strlist, strlists);
  108.         p->next = *base;
  109.         *base = p;
  110.         strcpy(p->s, s);
  111.     }
  112.     p->value = 0;
  113.     return p;
  114. }
  115.  
  116.  
  117.  
  118. /* Append two strlists together */
  119.  
  120. void strlist_mix(base, sl)
  121. register Strlist **base;
  122. Strlist *sl;
  123. {
  124.     if (sl) {
  125.     while (*base)
  126.         base = &(*base)->next;
  127.     *base = sl;
  128.     }
  129. }
  130.  
  131.  
  132.  
  133. /* Remove the first element of a strlist */
  134.  
  135. void strlist_eat(base)
  136. register Strlist **base;
  137. {
  138.     register Strlist *p;
  139.  
  140.     if ((p = *base) != NULL) {
  141.         *base = p->next;
  142.         FREE(p);
  143.     }
  144. }
  145.  
  146.  
  147.  
  148. /* Remove all elements of a strlist */
  149.  
  150. void strlist_empty(base)
  151. register Strlist **base;
  152. {
  153.     register Strlist *p;
  154.  
  155.     if (!base) {
  156.     intwarning("strlist_empty", "NULL base pointer [312]");
  157.     return;
  158.     }
  159.     while ((p = *base) != NULL) {
  160.         *base = p->next;
  161.         FREE(p);
  162.     }
  163. }
  164.  
  165.  
  166.  
  167. /* Remove first occurrence of a given string */
  168.  
  169. void strlist_remove(base, s)
  170. register Strlist **base;
  171. register char *s;
  172. {
  173.     register Strlist *p;
  174.  
  175.     while ((p = *base) != NULL) {
  176.     if (!strcmp(p->s, s)) {
  177.         *base = p->next;
  178.         FREE(p);
  179.     } else
  180.         base = &p->next;
  181.     }
  182. }
  183.  
  184.  
  185.  
  186. /* Remove a given entry from a strlist */
  187.  
  188. void strlist_delete(base, sl)
  189. register Strlist **base, *sl;
  190. {
  191.     register Strlist *p;
  192.  
  193.     while ((p = *base) && p != sl)
  194.         base = &p->next;
  195.     if (p) {
  196.         *base = p->next;
  197.         FREE(p);
  198.     }
  199. }
  200.  
  201.  
  202.  
  203. /* Find the first occurrence of a string */
  204.  
  205. Strlist *strlist_find(base, s)
  206. register Strlist *base;
  207. register char *s;
  208. {
  209.     if (!s)
  210.     return NULL;
  211.     while (base && strcmp(base->s, s))
  212.         base = base->next;
  213.     return base;
  214. }
  215.  
  216.  
  217.  
  218. /* Case-insensitive version of strlist_find */
  219.  
  220. Strlist *strlist_cifind(base, s)
  221. register Strlist *base;
  222. register char *s;
  223. {
  224.     if (!s)
  225.     return NULL;
  226.     while (base && strcicmp(base->s, s))
  227.         base = base->next;
  228.     return base;
  229. }
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236. /* String comparisons */
  237.  
  238.  
  239. int strcincmp(s1, s2, n)
  240. register char *s1, *s2;
  241. register int n;
  242. {
  243.     register unsigned char ch1, ch2;
  244.  
  245.     while (--n >= 0) {
  246.         if (!(ch1 = *s1++))
  247.             return (*s2) ? -1 : 0;
  248.         if (!(ch2 = *s2++))
  249.             return 1;
  250.         if (islower(ch1))
  251.             ch1 = _toupper(ch1);
  252.         if (islower(ch2))
  253.             ch2 = _toupper(ch2);
  254.         if (ch1 != ch2)
  255.             return ch1 - ch2;
  256.     }
  257.     return 0;
  258. }
  259.  
  260.  
  261.  
  262. int strcicmp(s1, s2)
  263. register char *s1, *s2;
  264. {
  265.     register unsigned char ch1, ch2;
  266.  
  267.     for (;;) {
  268.         if (!(ch1 = *s1++))
  269.             return (*s2) ? -1 : 0;
  270.         if (!(ch2 = *s2++))
  271.             return 1;
  272.         if (islower(ch1))
  273.             ch1 = _toupper(ch1);
  274.         if (islower(ch2))
  275.             ch2 = _toupper(ch2);
  276.         if (ch1 != ch2)
  277.             return ch1 - ch2;
  278.     }
  279. }
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286. /* File name munching */
  287.  
  288.  
  289. void fixfname(fn, ext)
  290. char *fn, *ext;
  291. {
  292.     char *cp, *cp2;
  293.  
  294.     if (!ext)
  295.         return;
  296.     cp = my_strrchr(fn, '.');
  297.     cp2 = my_strrchr(fn, '/');
  298.     if (cp && (!cp2 || cp > cp2)) {
  299.         if (!cp[1])     /* remove trailing '.' */
  300.             *cp = 0;
  301.     } else {
  302.         strcat(fn, ".");
  303.         strcat(fn, ext);
  304.     }
  305. }
  306.  
  307.  
  308.  
  309. void removesuffix(fn)
  310. char *fn;
  311. {
  312.     char *cp, *cp2;
  313.  
  314.     cp = my_strrchr(fn, '.');
  315.     if (!cp)
  316.         return;
  317. #if defined(unix) || defined(__unix)
  318.     cp2 = my_strrchr(fn, '/');
  319.     if (cp2 && cp < cp2)
  320.         return;
  321. #endif
  322.     *cp = 0;
  323. }
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330. /* Dynamically-allocated strings */
  331.  
  332.  
  333. char *stralloc(s)
  334. char *s;
  335. {
  336.     register char *buf = ALLOC(strlen(s) + 1, char, strings);
  337.     strcpy(buf, s);
  338.     return buf;
  339. }
  340.  
  341.  
  342.  
  343. void strchange(v, s)
  344. char **v, *s;
  345. {
  346.     s = stralloc(s);   /* do this first in case **v and *s overlap */
  347.     FREE(*v);
  348.     *v = s;
  349. }
  350.  
  351.  
  352.  
  353.  
  354.  
  355. /* Handy string formatting */
  356.  
  357. #define NUMBUF 8
  358. static char *(formatbuf[NUMBUF]);
  359. static int nextformat = -1;
  360.  
  361. #define getformat()  ((nextformat=(nextformat+1)%NUMBUF), formatbuf[nextformat])
  362.  
  363.  
  364. #define FF_UCASE   0x1
  365. #define FF_LCASE   0x2
  366. #define FF_REMSUFF 0x4
  367. #define FF_UNDER   0x8     /* Thanks to William Bader for suggesting these */
  368. #define FF_PRESERVE 0x10
  369. #define FF_REMSLASH 0x20
  370. #define FF_REMUNDER 0x40
  371.  
  372. Static void cvcase(buf, flags)
  373. char *buf;
  374. int flags;
  375. {
  376.     char *cp, *cp2;
  377.     int ulflag, i;
  378.  
  379.     if (flags & FF_PRESERVE) {
  380.         ulflag = 0;
  381.     for (cp = buf; *cp; cp++) {
  382.         if (isupper(*cp))
  383.         ulflag |= 1;
  384.         else if (islower(*cp))
  385.         ulflag |= 2;
  386.     }
  387.     if (ulflag == 3)
  388.         flags &= ~(FF_UCASE | FF_LCASE);
  389.     }
  390.     if ((flags & FF_UNDER) && *buf) {
  391.         for (cp = buf + 1; *cp; cp++) {
  392.             if (isupper(*cp) && islower(cp[-1])) {
  393.         for (i = strlen(cp); i >= 0; i--)
  394.             cp[i+1] = cp[i];
  395.         *cp++ = '_';
  396.         }
  397.     }
  398.     }
  399.     if (flags & FF_UCASE) {
  400.     if (flags & FF_LCASE) {
  401.         for (cp = buf; *cp; cp++) {
  402.         if (cp == buf || !isalpha(cp[-1]))
  403.             *cp = toupper(*cp);
  404.         else
  405.             *cp = tolower(*cp);
  406.         }
  407.     } else
  408.         upc(buf);
  409.     } else if (flags & FF_LCASE)
  410.     lwc(buf);
  411.     if (flags & FF_REMUNDER) {
  412.     for (cp = cp2 = buf; *cp; cp++) {
  413.         if (isalnum(*cp))
  414.         *cp2++ = *cp;
  415.     }
  416.     if (cp2 > buf)
  417.         *cp2 = 0;
  418.     }
  419. }
  420.  
  421.  
  422. char *format_gen(fmt, i1, i2, dbl, s1, s2, s3)
  423. char *fmt;
  424. long i1, i2;
  425. double dbl;
  426. char *s1, *s2, *s3;
  427. {
  428.     char *buf = getformat();
  429.     char *dst = buf, *src = fmt, *cp, *cp2, *saves2 = s2;
  430.     int wid, prec;
  431.     int flags;
  432.     char fmtbuf[50], *fp;
  433.  
  434.     debughook();
  435.     while (*src) {
  436.     if (*src != '%') {
  437.         *dst++ = *src++;
  438.         continue;
  439.     }
  440.     src++;
  441.     wid = -1;
  442.     prec = -1;
  443.     flags = 0;
  444.     fp = fmtbuf;
  445.     *fp++ = '%';
  446.     for (;;) {
  447.         if (*src == '-' || *src == '+' || *src == ' ' || *src == '#') {
  448.         *fp++ = *src;
  449.         } else if (*src == '^') {
  450.         flags |= FF_UCASE;
  451.         } else if (*src == '_') {
  452.         flags |= FF_LCASE;
  453.         } else if (*src == 'R') {
  454.         flags |= FF_REMSUFF;
  455.         } else if (*src == '~') {
  456.         flags |= FF_UNDER;
  457.         } else if (*src == '!') {
  458.         flags |= FF_REMUNDER;
  459.         } else if (*src == '?') {
  460.         flags |= FF_PRESERVE;
  461.         } else if (*src == '/') {
  462.         flags |= FF_REMSLASH;
  463.         } else
  464.         break;
  465.         src++;
  466.     }
  467.     if (isdigit(*src)) {
  468.         wid = 0;
  469.         whil