home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / BASTRNGS.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  212 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  BASIC-like string operations
  5. **
  6. **  public domain by Bob Stout
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdarg.h>
  12. #include <limits.h>
  13. #include <assert.h>
  14. #include "sniptype.h"
  15. #include "bastrngs.h"
  16.  
  17. static int stralloc_ptr;
  18. static char *strings[8];
  19. static int str_tag[8];
  20.  
  21. /*
  22. **  stralloc() is the key function in this package, maintaining a pool of
  23. **  reusable strings.
  24. */
  25.  
  26. char *stralloc(size_t length)
  27. {
  28.       register int i;
  29.  
  30.       if (UINT_MAX == length)       /* Assume size_t == unsigned int    */
  31.             return NULL;
  32.  
  33.       i = stralloc_ptr++;
  34.       ++length;                     /* Allow for terminating NUL        */
  35.  
  36.       if ((!strings[i]) || (length > strlen(strings[i])))
  37.       {
  38.             strings[i] = (char *)realloc(strings[i], length);
  39.             assert(NULL != strings[i]);
  40.             str_tag[i] = -1;
  41.       }
  42.       else  str_tag[i] = 0;
  43.       stralloc_ptr &= 7;
  44.       return (strings[i]);
  45.       /* Maintains 8 strings in a circular buffer */
  46. }
  47.  
  48. /*
  49. **  free the string pool.
  50. */
  51.  
  52. void str_free(char *string)
  53. {
  54.       register int i;
  55.  
  56.       for (i = 0; i < 8; ++i)
  57.       {
  58.             if (strings[i] == string)
  59.             {
  60.                   if (str_tag[i])
  61.                         free(strings[i]);
  62.                   return;
  63.             }
  64.       }
  65. }
  66.  
  67. /*
  68. **  return the leftmost N characters from a string, equivalent to LEFT$
  69. */
  70.  
  71. char *left(char *string, size_t N)
  72. {
  73.       char *buf;
  74.       size_t strlength = strlen(string);
  75.  
  76.       if (N > strlength)
  77.             N = strlength;
  78.       buf = stralloc(N);
  79.       memcpy(buf, string, N);
  80.       buf[N] = NUL;
  81.       return buf;
  82. }
  83.  
  84. /*
  85. **  return the rightmost N characters from a string, equivalent to RIGHT$
  86. */
  87.  
  88. char *right(char *string, size_t N)
  89. {
  90.       char *buf;
  91.       size_t strlength = strlen(string);
  92.  
  93.       if (N > strlength)
  94.             N = strlength;
  95.       buf = stralloc(N);
  96.       strcpy(buf, &string[strlength-N]);
  97.       return buf;
  98. }
  99.  
  100. /*
  101. **  return a substring, N characters long beginning at position M,
  102. **  equivalent to MID$
  103. */
  104.  
  105. char *mid(char *string, size_t M, size_t N)
  106. {
  107.       char *buf;
  108.       size_t strlength = strlen(string);
  109.  
  110.       if (M > strlength)
  111.             return NULL;
  112.       if (N > (strlength - M))
  113.             N = strlength - M;
  114.       buf = stralloc(N);
  115.       memcpy(buf, &string[M-1], N);
  116.       buf[N] = NUL;
  117.       return buf;
  118. }
  119.  
  120. /*
  121. **  string concatenation function, equivalent to A$=B$+C$+...
  122. */
  123.  
  124. char *string_add(char *string, ...)
  125. {
  126.       va_list arg_ptr;
  127.       char *temp1, *temp2, *buf;
  128.  
  129.       va_start(arg_ptr, string);
  130.       temp1 = string;
  131.       do
  132.       {
  133.             if(NULL == (temp2 = va_arg(arg_ptr, char *)))
  134.                   break;
  135.             buf = stralloc(strlen(temp1) + strlen(temp2));
  136.             temp1 = strcat(strcpy(buf, temp1), temp2);
  137.       } while (NULL != temp2);
  138.       return temp1;
  139. }
  140.  
  141. /*
  142. **  create a string of repeated characters, equivalent to STRING$()
  143. */
  144.  
  145. char *string(int ch, size_t N)
  146. {
  147.       char *buf;
  148.  
  149.       if (N)
  150.       {
  151.             buf = stralloc(N);
  152.             memset(buf, ch, N);
  153.       }
  154.       buf[N] = NUL;
  155.       return buf;
  156.                   
  157. }
  158.  
  159. /*
  160. **  BASIC INSTR$() work alike - returns position (1-based) of findstr in
  161. **  string, starting search at position start_pos (also 1-based).
  162. **
  163. **  Function suggested by Tika Carr
  164. */
  165.  
  166. unsigned int instr(const unsigned int start_pos,
  167.                    const char        *string,
  168.                    const char        *findstr)
  169. {
  170.       char *p;
  171.       unsigned int pos;
  172.  
  173.       if (start_pos > strlen(string))
  174.             return 0;
  175.       else  pos = start_pos - 1;    /* BASIC offsets are one-based, not
  176.                                        zero-based as in C               */
  177.  
  178.       if (NULL != (p = strstr(string + pos, findstr)))
  179.             return (int)(p - (char *)string) + 1; /* Position 0 = position 1 */
  180.       else  return 0;
  181. }
  182.  
  183. #ifdef TEST
  184.  
  185. /*
  186. **  Demo main()
  187. */
  188.  
  189. main()
  190. {
  191.       char *x = "European", *y = "Hardware", *z = "Skaters", *q;
  192.       char *a = "This is a test", *b = "is" ,
  193.            *c = "\nSearching for \"%s\" in \"%s\" starting at position %d\n";
  194.       unsigned int i, pos;
  195.  
  196.       z = string_add(left(x, 2), right(y, 2), mid(z, 2, 2), "!", NULL);
  197.       q = string('!', 4);
  198.       printf("%s%s\n", z, q);
  199.  
  200.       for (i = 2; i < strlen(a); i+= 2)
  201.       {
  202.             printf(c, b, a, i);
  203.             if (0 != (pos = instr(i, a, b)))
  204.                   printf("Found at position %d\n", pos);
  205.             else  puts("Not found");
  206.       }
  207.  
  208.       return 0;
  209. }
  210.  
  211. #endif /* TEST */
  212.