home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / cbase.zip / CBASE10B.ZIP / ROLODECK.ZIP / CVTSS.C next >
Text File  |  1989-10-31  |  6KB  |  249 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "cvtss.c    1.2 - 89/10/31" */
  5.  
  6. #if __STDC__ == 1
  7. #include <ctype.h>
  8. #include <errno.h>
  9. #include <stddef.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #define CONST const
  14. #else
  15. #include <ctype.h>
  16. #include <errno.h>
  17. void *calloc();        /* stdlib.h */
  18. void free();
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <sys/types.h>    /* size_t typedef */
  22. #define CONST
  23. #endif
  24.  
  25. /* m macros */
  26. #define CVT_0    (0x0001)    /* trim the parity bit */
  27. #define CVT_X_SP    (0x0002)    /* discard all spaces and tabs */
  28. #define CVT_X_CTL    (0x0004)    /* discard all control characters */
  29. #define CVT_X_LEADSP    (0x0008)    /* discard leading spaces and tabs */
  30. #define CVT_ONE_SP    (0x0010)    /* reduce spaces, tabs to one space */
  31. #define CVT_UPPER    (0x0020)    /* convert lowercase to uppercase */
  32. #define CVT_6    (0x0040)    /* convert [ to ( and ] to ) */
  33. #define CVT_X_TRAILSP    (0x0080)    /* discard trailing spaces and tabs */
  34. #define CVT_QUOTES    (0x0100)    /* do not alter chars inside quotes */
  35.  
  36. #ifndef min
  37. #define min(a,b)    (((a) < (b)) ? (a) : (b))
  38. #endif
  39.  
  40. /* macro to preserve characters within quotes */
  41. #define QUOTES {                            \
  42.     if (quotes && (*ps == '\"')) {                    \
  43.         *pt++ = *ps++;                        \
  44.         while ((*ps != '\0') && (pt < (tt + n - 1))) {        \
  45.             *pt++ = *ps;                    \
  46.             if (*ps++ == '\"') break;            \
  47.         }                            \
  48.         continue;                        \
  49.     }                                \
  50. }
  51.  
  52. /*man---------------------------------------------------------------------------
  53. NAME
  54.      cvtss - convert string
  55.  
  56. SYNOPSIS
  57.      int cvtss(t, s, m, n)
  58.      char *t;
  59.      const char *s;
  60.      int m;
  61.      int n;
  62.  
  63. DESCRIPTION
  64.      The cvtss function takes the source string pointed to by s,
  65.      performs the conversions indicated by m, and places the result in
  66.      the target string pointed to by t.  n is the size of the target
  67.      string.  At most n - 1 characters are placed in t, terminated by
  68.      a '\0'.
  69.  
  70.      Values for m are constructed by bitwise OR-ing flags from the
  71.      following list.
  72.  
  73.      CVT_X_SP       0x0002      Discard all spaces and tabs.
  74.      CVT_X_CTL      0x0004      Discard all control characters.
  75.      CVT_X_LEADSP   0x0008      Discard leading spaces and tabs.
  76.      CVT_ONE_SP     0x0010      Reduce spaces and tabs to one space.
  77.      CVT_UPPER      0x0020      Convert lowercase to uppercase.
  78.      CVT_X_TRAILSP  0x0080      Discard trailing spaces and tabs.
  79.      CVT_QUOTES     0x0100      Do not alter characters inside quotes.
  80.  
  81.      cvtss will fail if one or more of the following is true:
  82.  
  83.      [EINVAL]       t or s is the NULL pointer.
  84.      [EINVAL]       n is less than 1.
  85.      [ENOMEM]       Not enough memory is available for
  86.                     allocation by the calling process.
  87.  
  88. DIAGNOSTICS
  89.      Upon successful completion, a value of 0 is returned.  Otherwise,
  90.      a value of -1 is returned, and errno set to indicate the error.
  91.  
  92. NOTES
  93.      cvtss is adapted directly from the BASIC function CVT$$.
  94.  
  95. ------------------------------------------------------------------------------*/
  96. int cvtss(t, s, m, n)
  97. char *t;
  98. CONST char *s;
  99. int m;
  100. int n;
  101. {
  102.     int ns = 0;        /* length of s including '\0' */
  103.     char *ts = 0;        /* temporary source string */
  104.     char *tt = 0;        /* temporary target string */
  105.     int quotes = 0;        /* preserve quoted characters flag */
  106.     int bit = 0;        /* bit number */
  107.     char *ps = NULL;    /* pointer into ts */
  108.     char *pt = NULL;    /* pointer into tt */
  109.     int flag = 0;        /* generic flag */
  110.  
  111.     /* validate arguments */
  112.     if ((t == NULL) || (s == NULL) || (n < 1)) {
  113.         errno = EINVAL;
  114.         return -1;
  115.     }
  116.  
  117.     /* find size for ts */
  118.     ns = strlen(s) + 1;
  119.  
  120.     /* create temporary strings */
  121.     ts = (char *)calloc((size_t)ns, (size_t)1);
  122.     if (ts == NULL) {
  123.         errno = ENOMEM;
  124.         return -1;
  125.     }
  126.     tt = (char *)calloc((size_t)n, (size_t)1);
  127.     if (tt == NULL) {
  128.         free(ts);
  129.         errno = ENOMEM;
  130.         return -1;
  131.     }
  132.  
  133.     /* initialize ts with s */
  134.     strncpy(ts, s, ns);
  135.     ts[ns - 1] = 0;
  136.  
  137.     /* perform conversions */
  138.     quotes = m & CVT_QUOTES;    /* set preserve quoted chars flag */
  139.     for (bit = 0; m != 0; bit++) {
  140.         if (!(m & 1)) {
  141.             m >>= 1;
  142.             continue;
  143.         }
  144.         m >>= 1;
  145.         switch (bit) {
  146.         case 0:    /* trim the parity bit */
  147.             /* not implemented */
  148.             break;    /* case 0: */
  149.         case 1:    /* discard all spaces and tabs */
  150.             ps = ts;
  151.             pt = tt;
  152.             while ((*ps != '\0') && (pt < (tt + n - 1))) {
  153.                 QUOTES;
  154.                 if (!((*ps == ' ') || (*ps == '\t'))) {
  155.                     *pt++ = *ps;
  156.                 }
  157.                 ps++;
  158.             }
  159.             *pt = '\0';
  160.             break;    /* case 1: */
  161.         case 2:    /* discard all control characters */
  162.             ps = ts;
  163.             pt = tt;
  164.             while ((*ps != '\0') && (pt < (tt + n - 1))) {
  165.                 QUOTES;
  166.                 if (!iscntrl(*ps)) {
  167.                     *pt++ = *ps;
  168.                 }
  169.                 ps++;
  170.             }
  171.             *pt = '\0';
  172.             break;    /* case 2: */
  173.         case 3:    /* discard leading spaces and tabs */
  174.             for (ps = ts; *ps != '\0'; ps++) {
  175.                 if ((*ps != ' ') && (*ps != '\t')) {
  176.                     break;
  177.                 }
  178.             }
  179.             strncpy(tt, ps, n);
  180.             tt[n - 1] = '\0';
  181.             break;    /* case 3: */
  182.         case 4:    /* reduce spaces and tabs to one space */
  183.             ps = ts;
  184.             pt = tt;
  185.             flag = 0;
  186.             while ((*ps != '\0') && (pt < (tt + n - 1))) {
  187.                 QUOTES;
  188.                 if (flag) {
  189.                     if ((*ps != ' ') && (*ps != '\t')) {
  190.                         *pt++ = *ps;
  191.                         flag = 0;
  192.                     }
  193.                 } else {
  194.                     *pt++ = *ps;
  195.                     if ((*ps == ' ') || (*ps == '\t')) {
  196.                         flag = 1;
  197.                     }
  198.                 }
  199.                 ps++;
  200.             }
  201.             *pt = '\0';
  202.             break;    /* case 4: */
  203.         case 5:    /* convert lowercase to uppercase */
  204.             ps = ts;
  205.             pt = tt;
  206.             while ((*ps != '\0') && (pt < (tt + n - 1))) {
  207.                 QUOTES;
  208.                 *pt++ = toupper(*ps++);
  209.             }
  210.             *pt = '\0';
  211.             break;    /* case 5: */
  212.         case 6:    /* convert [ to ( and ] to ) */
  213.             /* not implemented */
  214.             break;    /* case 6: */
  215.         case 7:    /* discard trailing spaces and tabs */
  216.             for (ps = ts + strlen(ts) - 1; (ps >= ts); ps--) {
  217.                 if ((*ps != ' ') && (*ps != '\t')) {
  218.                     break;
  219.                 }
  220.             }
  221.             strncpy(tt, ts, n);
  222.             tt[min(n - 1, ps + 1 - ts)] = '\0';
  223.             break;    /* case 7: */
  224.         case 8:    /* do not alter characters inside quotes */
  225.             continue;
  226.             break;    /* case 8: */
  227.         default:
  228.             free(tt);
  229.             free(ts);
  230.             errno = EINVAL;
  231.             return -1;
  232.             break;
  233.         }
  234.         strncpy(ts, tt, ns);
  235.         ts[ns - 1] = 0;
  236.     }
  237.  
  238.     /* load target string */
  239.     strncpy(t, ts, n);
  240.     t[n - 1] = '\0';
  241.  
  242.     /* free temporary strings */
  243.     free(tt);
  244.     free(ts);
  245.  
  246.     errno = 0;
  247.     return 0;
  248. }
  249.