home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / k / ksh48.zip / sh / misc.c < prev    next >
C/C++ Source or Header  |  1992-09-08  |  8KB  |  443 lines

  1. /*
  2.  * Miscellaneous functions
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Id: misc.c,v 1.3 1992/08/12 14:15:42 sjg Exp $";
  7. #endif
  8.  
  9. #include "stdh.h"
  10. #include <signal.h>
  11. #include <errno.h>
  12. #include <setjmp.h>
  13. #include "sh.h"
  14. #include "expand.h"
  15. #ifndef NOSTDHDRS
  16. # include <limits.h>
  17. #else
  18. # define UCHAR_MAX    0xFF
  19. #endif
  20.  
  21. char ctypes [UCHAR_MAX+1];    /* type bits for unsigned char */
  22.  
  23. static char *   cclass      ARGS((char *p, int sub));
  24.  
  25. /*
  26.  * Fast character classes
  27.  */
  28. void
  29. setctypes(s, t)
  30.     register /* const */ char *s;
  31.     register int t;
  32. {
  33.     register int i;
  34.  
  35.     if ((t&C_IFS)) {
  36.         for (i = 0; i < UCHAR_MAX+1; i++)
  37.             ctypes[i] &=~ C_IFS;
  38.         ctypes[0] |= C_IFS; /* include \0 in C_IFS */
  39.     }
  40.     ctypes[(unsigned char) *s++] |= t;    /* allow leading \0 in string */
  41.     while (*s != 0)
  42.         ctypes[(unsigned char) *s++] |= t;
  43. }
  44.  
  45. void
  46. initctypes()
  47. {
  48.     register int c;
  49.  
  50.     for (c = 'a'; c <= 'z'; c++)
  51.         ctypes[c] |= C_ALPHA;
  52.     for (c = 'A'; c <= 'Z'; c++)
  53.         ctypes[c] |= C_ALPHA;
  54.     ctypes['_'] |= C_ALPHA;
  55.     setctypes("0123456789", C_DIGIT);
  56.     setctypes("\0 \t\n|&;<>()", C_LEX1);
  57.     setctypes("*@#!$-?", C_VAR1);
  58.     setctypes("=-+?#%", C_SUBOP);
  59. }
  60.  
  61. /* convert unsigned long to base N string */
  62.  
  63. char *
  64. ulton(n, base)
  65.     register unsigned long n;
  66.     int base;
  67. {
  68.     register char *p;
  69.     static char buf [20];
  70.  
  71.     p = &buf[sizeof(buf)];
  72.     *--p = '\0';
  73.     do {
  74.         *--p = "0123456789ABCDEF"[n%base];
  75.         n /= base;
  76.     } while (n != 0);
  77.     return p;
  78. }
  79.  
  80. char *
  81. strsave(s, ap)
  82.     register char *s;
  83.     Area *ap;
  84. {
  85.   return s ? strcpy((char*) alloc((size_t)strlen(s)+1, ap), s) : NULL;
  86. }
  87.  
  88. static struct option {
  89.     char *name;
  90.     int flag;
  91. } options[] = {
  92.     {"allexport",    FEXPORT},
  93.     {"bgnice",    FBGNICE},
  94. #if defined(EDIT) && defined(EMACS)
  95.     {"emacs",    FEMACS},
  96. #endif
  97.     {"errexit",    FERREXIT},
  98.     {"hashall",    FHASHALL},
  99.     {"ignoreeof",    FIGNEOF},
  100.     {"interactive",    FTALKING},
  101.     {"keyword",    FKEYWORD},
  102.     {"markdirs",    FMARKDIRS},
  103.     {"monitor",    FMONITOR},
  104.     {"noexec",    FNOEXEC},
  105.     {"noglob",    FNOGLOB},
  106.     {"nounset",    FNOUNSET},
  107.     {"privileged",    FPRIVILEGED},
  108.     {"stdin",    FSTDIN},
  109.     {"trackall",    FHASHALL},
  110.     {"verbose",    FVERBOSE},
  111. #if defined(EDIT) && defined(VI)
  112.     {"vi",        FVI},
  113. #endif
  114.     {"xtrace",    FXTRACE},
  115.     {NULL,        0}
  116. };
  117.  
  118. /*
  119.  * translate -o option into F* constant
  120.  */
  121. int
  122. option(n)
  123.     const char *n;
  124. {
  125.     register struct option *op;
  126.  
  127.     for (op = options; op->name != NULL; op++)
  128.         if (strcmp(op->name, n) == 0)
  129.             return op->flag;
  130.     return 0;
  131. }
  132.  
  133. char *
  134. getoptions()
  135. {
  136.     register int c;
  137.     char m [26+1];
  138.     register char *cp = m;
  139.  
  140.     for (c = 'a'; c <= 'z'; c++)
  141.         if (flag[FLAG(c)])
  142.             *cp++ = (char) c;
  143.     *cp = 0;
  144.     return strsave(m, ATEMP);
  145. }
  146.  
  147. void
  148. printoptions()
  149. {
  150.     register struct option *op;
  151.  
  152.     for (op = options; op->name != NULL; op++)
  153.         if (flag[op->flag])
  154.             shellf("%s ", op->name);
  155.     shellf("\n");
  156. }
  157.  
  158. /* atoi with error detection */
  159.  
  160. getn(as)
  161.     char *as;
  162. {
  163.     register char *s;
  164.     register int n;
  165.  
  166.     s = as;
  167.     if (*s == '-')
  168.         s++;
  169.     for (n = 0; digit(*s); s++)
  170.         n = (n*10) + (*s-'0');
  171.     if (*s)
  172.         errorf("%s: bad number\n", as);
  173.     return (*as == '-') ? -n : n;
  174. }
  175.  
  176. /*
  177.  * stripped down strerror for kill and exec
  178.  */
  179. char *
  180. strerror(i)
  181.     int i;
  182. {
  183.     switch (i) {
  184.       case EINVAL:
  185.         return "Invalid argument";
  186.       case EACCES:
  187.         return "Permission denied";
  188.       case ESRCH:
  189.         return "No such process";
  190.       case EPERM:
  191.         return "Not owner";
  192.       case ENOENT:
  193.         return "No such file or directory";
  194.       case ENOTDIR:
  195.         return "Not a directory";
  196.       case ENOEXEC:
  197.         return "Exec format error";
  198.       case ENOMEM:
  199.         return "Not enough memory";
  200.       case E2BIG:
  201.         return "Argument list too long";
  202.       default:
  203.         return "Unknown system error";
  204.     }
  205. }
  206.  
  207. /* -------- gmatch.c -------- */
  208.  
  209. /*
  210.  * int gmatch(string, pattern)
  211.  * char *string, *pattern;
  212.  *
  213.  * Match a pattern as in sh(1).
  214.  * pattern character are prefixed with MAGIC by expand.
  215.  */
  216.  
  217. static    char    *cclass ARGS((char *, int));
  218.  
  219. int
  220. gmatch(s, p)
  221.     register char *s, *p;
  222. {
  223.     register int sc, pc;
  224.  
  225.     if (s == NULL || p == NULL)
  226.         return 0;
  227.     while ((pc = *p++) != 0) {
  228.         sc = *s++;
  229.         if (pc ==  MAGIC)
  230.             switch (*p++) {
  231.               case '[':
  232.                 if (sc == 0 || (p = cclass(p, sc)) == NULL)
  233.                     return (0);
  234.                 break;
  235.  
  236.               case '?':
  237.                 if (sc == 0)
  238.                     return (0);
  239.                 break;
  240.  
  241.               case '*':
  242.                 s--;
  243.                 do {
  244.                     if (*p == '\0' || gmatch(s, p))
  245.                         return (1);
  246.                 } while (*s++ != '\0');
  247.                 return (0);
  248.  
  249.               default:
  250.                 if (sc != p[-1])
  251.                     return 0;
  252.                 break;
  253.             }
  254.         else
  255.             if (sc != pc)
  256.                 return 0;
  257.     }
  258.     return (*s == 0);
  259. }
  260.  
  261. static char *
  262. cclass(p, sub)
  263.     register char *p;
  264.     register int sub;
  265. {
  266.     register int c, d, not, found = 0;
  267.  
  268.     if ((not = (*p == MAGIC && *++p == NOT)))
  269.         p++;
  270.     do {
  271.         if (*p == MAGIC)
  272.             p++;
  273.         if (*p == '\0')
  274.             return NULL;
  275.         c = *p;
  276.         if (p[1] == '-' && p[2] != ']') {
  277.             d = p[2];
  278.             p++;
  279.         } else
  280.             d = c;
  281.         if (c == sub || (c <= sub && sub <= d))
  282.             found = 1;
  283.     } while (*++p != ']');
  284.  
  285.     return (found != not) ? p+1 : NULL;
  286. }
  287.  
  288. /* -------- qsort.c -------- */
  289.  
  290. /*
  291.  * quick sort of array of generic pointers to objects.
  292.  */
  293.  
  294. void
  295. qsortp(base, n, f)
  296.     void **base;        /* base address */
  297.     size_t n;        /* elements */
  298.         int (*f)(void *, void *); /* compare function */
  299. {
  300.     qsort1(base, base + n, f);
  301. }
  302.  
  303. #define    swap2(a, b)    {\
  304.     register void *t; t = *(a); *(a) = *(b); *(b) = t;\
  305. }
  306. #define    swap3(a, b, c)    {\
  307.     register void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\
  308. }
  309.  
  310. void
  311. qsort1(base, lim, f)
  312.     void **base, **lim;
  313.     int (*f)();
  314. {
  315.     register void **i, **j;
  316.     register void **lptr, **hptr;
  317.     size_t n;
  318.     int c;
  319.  
  320.   top:
  321.     n = (lim - base) / 2;
  322.     if (n == 0)
  323.         return;
  324.     hptr = lptr = base+n;
  325.     i = base;
  326.     j = lim - 1;
  327.  
  328.     for (;;) {
  329.         if (i < lptr) {
  330.             if ((c = (*f)(*i, *lptr)) == 0) {
  331.                 lptr --;
  332.                 swap2(i, lptr);
  333.                 continue;
  334.             }
  335.             if (c < 0) {
  336.                 i += 1;
  337.                 continue;
  338.             }
  339.         }
  340.  
  341.       begin:
  342.         if (j > hptr) {
  343.             if ((c = (*f)(*hptr, *j)) == 0) {
  344.                 hptr ++;
  345.                 swap2(hptr, j);
  346.                 goto begin;
  347.             }
  348.             if (c > 0) {
  349.                 if (i == lptr) {
  350.                     hptr ++;
  351.                     swap3(i, hptr, j);
  352.                     i = lptr += 1;
  353.                     goto begin;
  354.                 }
  355.                 swap2(i, j);
  356.                 j -= 1;
  357.                 i += 1;
  358.                 continue;
  359.             }
  360.             j -= 1;
  361.             goto begin;
  362.         }
  363.  
  364.         if (i == lptr) {
  365.             if (lptr-base >= lim-hptr) {
  366.                 qsort1(hptr+1, lim, f);
  367.                 lim = lptr;
  368.             } else {
  369.                 qsort1(base, lptr, f);
  370.                 base = hptr+1;
  371.             }
  372.             goto top;
  373.         }
  374.  
  375.         lptr -= 1;
  376.         swap3(j, lptr, i);
  377.         j = hptr -= 1;
  378.     }
  379. }
  380.  
  381. int
  382. xstrcmp(p1, p2)
  383.     void *p1, *p2;
  384. {
  385.     return (strcmp((char *)p1, (char *)p2));
  386. }
  387.  
  388. void
  389. cleanpath(pwd, dir, clean)
  390.     char *pwd, *dir, *clean;
  391. {
  392.     register char  *s, *d, *p, c;
  393.     char *slash = DIRSEPSTR;
  394.     register int inslash = 0;
  395.  
  396.     d = clean;
  397. #ifdef OS2
  398.     if (!ISDIRSEP(*dir) && !(isalpha(dir[0]) && dir[1] == ':')) {
  399. #else
  400.     if (!ISDIRSEP(*dir)) {
  401. #endif
  402.         s = pwd;
  403.         while (*d++ = *s++)
  404.             ;
  405.         if (d >= clean + 2 && ISDIRSEP(*(d - 2)))
  406.             d--;
  407.         else
  408.             *(d - 1) = '/';
  409.     }
  410.  
  411.     s = dir;
  412.     while (*s) {
  413.                 c = (*d++ = *s++);
  414.         if (ISDIRSEP(c) && d > clean + 1) {
  415.                         p = d - 2;
  416.             if (ISDIRSEP(*p)) {
  417.                 --d;
  418.             } else if (*p == '.') {
  419.                                 p--;
  420.                 if (ISDIRSEP(*p)) {
  421.                     d -= 2;
  422.                 } else if (*p == '.' && --p && ISDIRSEP(*p)) {
  423.                     while (p > clean && --p && 
  424.                            !ISDIRSEP(*p))
  425.                         ;
  426.                     d = p + 1;
  427.                 }
  428.             }
  429.         }
  430.         if (!*s && !inslash && !ISDIRSEP(*(s - 1))) {
  431.             inslash = 1;
  432.             s = slash;
  433.         }
  434.     }
  435.  
  436.     if (ISDIRSEP(*(d - 1)) && (d - 1) > clean)
  437. #ifdef OS2
  438.         if (*(d - 2) != ':')
  439. #endif
  440.         d--;
  441.     *d = '\0';
  442. }
  443.