home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / ELEMC.ZIP / STRINGS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1985-05-09  |  10.5 KB  |  299 lines

  1.  
  2.  
  3.  
  4. #include <stdio.h>
  5.  
  6. #include <ctype.h>
  7.  
  8.  
  9.  
  10. /*
  11.  
  12. ;;      file:   _STRING.C
  13.  
  14. ;;
  15.  
  16. ;; --------------- Command Tail Processing Functions ---------------
  17.  
  18. ;;
  19.  
  20. ;;      This next set of functions are meant to be used together. Examples
  21.  
  22. ;;on their use follows.
  23.  
  24. ;;
  25.  
  26. ;;
  27.  
  28. ;;int num_args(string)  Returns the number of args in the string, seperated
  29.  
  30. ;;                      by delims (see delim(), below). Leading delimiters
  31.  
  32. ;;                      are ignored.
  33.  
  34. ;;
  35.  
  36. ;;char *next_arg(string)        Returns a pointer to the next arg, delimited 
  37.  
  38. ;;                      by a delim, skipping over the current arg. Use via
  39.  
  40. ;;                      ptr= nextarg(ptr) to skip to each argument. All 
  41.  
  42. ;;                      switches at the end of the current arg are skipped.
  43.  
  44. ;;
  45.  
  46. ;;
  47.  
  48. ;;char *skip_delim(string) Skips leading delims in a string. returns a pointer.
  49.  
  50. ;;
  51.  
  52. ;;cpyarg(to,from)               Copies a string, up to the next delim or switch.
  53.  
  54. ;;                      Leading and trailing delimiters are stripped (from 
  55.  
  56. ;;                      the output string) and a null terminator is added.
  57.  
  58. ;;
  59.  
  60. ;;                      after cpyarg()          FROM: foo/b
  61.  
  62. ;;                                              TO: foo
  63.  
  64. ;;
  65.  
  66. ;;delim(c)              Returns true if the character is a delimiter.
  67.  
  68. ;;                      Nulls are not considered a delimiter. The list of
  69.  
  70. ;;                      delimiters is contained in the array '_dlmlst', and
  71.  
  72. ;;                      can be changed via newdelim().
  73.  
  74. ;;
  75.  
  76. ;;newdelim(s)           Replace the list of delimiters. The string 's' must
  77.  
  78. ;;                      be less than 20 chars.
  79.  
  80. ;;
  81.  
  82. ;;isswitch(c)           Returns true if the character is the current DOS
  83.  
  84. ;;                      switch character.
  85.  
  86. ;;
  87.  
  88. ;;char filtchar(c)      Convert a character to one legal for an MSDOS filename.
  89.  
  90. ;;                      Illegal characters such as switch or path seperators,
  91.  
  92. ;;                      control characters, etc are changed to '$'. Bit 7 is
  93.  
  94. ;;                      masked off. (Disallows foreign language support??)
  95.  
  96. ;;
  97.  
  98. ;;wild(string)          Returns true if the string contains a star or question.
  99.  
  100. ;;
  101.  
  102. ;;char *strip_path(out,in) Copies the disk specifier or pathname to the output
  103.  
  104. ;;                      array, and returns a pointer to the name in the input
  105.  
  106. ;;                      string. Drive specs are considered a path, and are
  107.  
  108. ;;                      treated as such by DOS. Stripping "a:foo" and
  109.  
  110. ;;                      "bin/foo/framis.asm" result in:
  111.  
  112. ;;
  113.  
  114. ;;                              IN:     "A:"
  115.  
  116. ;;                              IN:     "bin\foo"
  117.  
  118. ;;
  119.  
  120. ;;                              OUT:    "A:"
  121.  
  122. ;;                              OUT:    "bin\"
  123.  
  124. ;;
  125.  
  126. ;;strip_switch(out,in)  Copy the switches from the in string, remove the switch
  127.  
  128. ;;                      character and put all the characters in the out array.
  129.  
  130. ;;                      Each is converted to upper case, and the string is null
  131.  
  132. ;;                      terminated.
  133.  
  134. ;;
  135.  
  136. ;;ispath_delim(c)       Returns true if the character is a legal pathname
  137.  
  138. ;;char c;               component seperator. The only two characters legal
  139.  
  140. ;;                      (here at least) are \ and-or /. For example:
  141.  
  142. ;;
  143.  
  144. ;;                      Switch character = /
  145.  
  146. ;;                              ispath_delim('/') == 0
  147.  
  148. ;;                              ispath_delim('\\') == 1
  149.  
  150. ;;                      Switch character = -
  151.  
  152. ;;                              ispath_delim('/') == 1
  153.  
  154. ;;                              ispath_delim('\\') == 1
  155.  
  156. ;;                      Switch character = \
  157.  
  158. ;;                              ispath_delim('/') == 1
  159.  
  160. ;;                              ispath_delim('\\') == 0
  161.  
  162. ;;
  163.  
  164. ;;
  165.  
  166. ;; --------- Command Tail Processing Examples ----------
  167.  
  168. ;;
  169.  
  170. ;;      This is an example of one way to use the above functions to process
  171.  
  172. ;;an MSDOS program command tail. You do not need to know what the system switch
  173.  
  174. ;;character or legal path seperators are. If you can't handle paths, strip them
  175.  
  176. ;;off. Assume there is a pointer, p, that points to a command tail string:
  177.  
  178. ;;
  179.  
  180. ;;      p= "  source.ext abc.asm/v+\bin\def.com /x/y/z"
  181.  
  182. ;;
  183.  
  184. ;;      p= skip_delim(p);               /* p= "source.exe abc...... */
  185.  
  186. ;;
  187.  
  188. ;;      p= next_arg(p);                 /* p= "abc.asm/v.... "  */
  189.  
  190. ;;      cpyarg(work,p);                 /* work= "abc.asm"  */
  191.  
  192. ;;      s= strip_path(work,p));         /* s= "abc.asm"   path= ""  */
  193.  
  194. ;;      strip_switch(sw,p);             /* sw= "V"  */
  195.  
  196. ;;
  197.  
  198. ;;      p= next_arg(p);                 /* p= "\bin\def.com"  */
  199.  
  200. ;;      cpyarg(work,p);                 /* work= "\bin\def.com"  */
  201.  
  202. ;;      s= strip_path(path,p);          /* s= "def.com"  path= "\bin\"  */
  203.  
  204. ;;      strip_switch(sw,p);             /* sw= ""  */
  205.  
  206. ;;
  207.  
  208. ;;      p= next_arg(p);                 /* p= "/x/y/z"  */
  209.  
  210. ;;      cpyarg(work,p);                 /* work= ""  */
  211.  
  212. ;;      s= strip_path(path,p);          /* s= ""  path= ""  */
  213.  
  214. ;;      strip_switch(sw,p);             /* sw= "XYZ"  */
  215.  
  216. ;;
  217.  
  218. ;;      p= next_arg(p);                 /* p= ""  */
  219.  
  220. ;;
  221.  
  222. ;;      while (num_args(p)              /* while not end of string ... */
  223.  
  224. ;;      while (*p)                      /* another way ... */
  225.  
  226. ;;
  227.  
  228. ;;
  229.  
  230. ;;char *name,sw[4],path[40];
  231.  
  232. ;;
  233.  
  234. ;;      p= skip_delim(p);
  235.  
  236. ;;      while (num_args(p) > 0) {       /* *p points to the current arg, */
  237.  
  238. ;;              name= strip_path(path,p);
  239.  
  240. ;;              strip_switch(sw,p);
  241.  
  242. ;;              printf("Path= %s, Name= %s, Switches= %s\n",path,name,sw);
  243.  
  244. ;;      }
  245.  
  246. ;;
  247.  
  248. */
  249.  
  250. /* Return the number of args left in the string. */
  251.  
  252.  
  253.  
  254. num_args(string)
  255.  
  256. char *string;
  257.  
  258. {
  259.  
  260. int count;
  261.  
  262.  
  263.  
  264.         count= 0;
  265.  
  266.         string= (char *)skip_delim(string);     /* skip leading blanks, */
  267.  
  268.         while (*string) {
  269.  
  270.                 ++count;                        /* count one, */
  271.  
  272.                 string= (char *)next_arg(string); /* find next, */
  273.  
  274.         }
  275.  
  276.         return(count);
  277.  
  278. }
  279.  
  280. /* Return a pointer to the next argument in the string. */
  281.  
  282.  
  283.  
  284. next_arg(string)
  285.  
  286. char *string;
  287.  
  288. {
  289.  
  290.         while ((!delim(*string)) && *string)            /* skip this one, */
  291.  
  292.                 ++string;                               /* up to delim, */
  293.  
  294.         string= (char *)skip_delim(string);             /* then skip delims, */
  295.  
  296.         return(string);
  297.  
  298. }
  299.  
  300.  
  301.  
  302. /* Skip over the leading delimiters in a string. */
  303.  
  304.  
  305.  
  306. skip_delim(string)
  307.  
  308. char *string;
  309.  
  310. {
  311.  
  312.         while (delim(*string) && *string)
  313.  
  314.                 ++string;
  315.  
  316.         return(string);
  317.  
  318. }
  319.  
  320. /* Copy the string to the destination array, stopping if we find one
  321.  
  322. of our delimiters or switches. */
  323.  
  324.  
  325.  
  326. cpyarg(to,from)
  327.  
  328. char *to;
  329.  
  330. char *from;
  331.  
  332. {
  333.  
  334.         while ( (!delim(*from)) && (!isswitch(*from)) && *from) 
  335.  
  336.                 *to++= *from++;
  337.  
  338.         *to= '\0';
  339.  
  340.         return;
  341.  
  342. }
  343.  
  344. /* Strip any switches from the input string, put into the output array. */
  345.  
  346.  
  347.  
  348. strip_switch(out,in)
  349.  
  350. char *out;
  351.  
  352. char *in;
  353.  
  354. {
  355.  
  356.         while (*in && (!isswitch(*in)))         /* skip to end of string */
  357.  
  358.                 ++in;                           /* or first switch, */
  359.  
  360.  
  361.  
  362.         while (*in && isswitch(*in)) {          /* copy switch args while */
  363.  
  364.                 ++in;
  365.  
  366.                 *out++ = toupper(*in);          /* stripping switch chars, */
  367.  
  368.                 ++in;
  369.  
  370.         }
  371.  
  372.         *out= '\0';                             /* terminate it, */
  373.  
  374.         return;
  375.  
  376. }
  377.  
  378. /* ----- List of legal delimiters. This is the default list ----- */
  379.  
  380.  
  381.  
  382. char _dlmlst[20] = { " \t,+" }; /* space, tab, comma, plus */
  383.  
  384.  
  385.  
  386. /* Change the list of delimiters. */
  387.  
  388.  
  389.  
  390. newdelim(s)
  391.  
  392. char *s;
  393.  
  394. {
  395.  
  396.         strcpy(_dlmlst,s);
  397.  
  398.         return;
  399.  
  400. }
  401.  
  402.  
  403.  
  404. /* Return true if the character is a delimiter from the list above. */
  405.  
  406.  
  407.  
  408. delim(c)
  409.  
  410. char c;
  411.  
  412. {
  413.  
  414. int i;
  415.  
  416.         for (i= 0; _dlmlst[i]; ++i) {
  417.  
  418.                 if (c == _dlmlst[i]) return(1);
  419.  
  420.         }
  421.  
  422.         return(0);
  423.  
  424. }
  425.  
  426. /* return true if the character is the current switch character. */
  427.  
  428.  
  429.  
  430. isswitch(c)
  431.  
  432. char c;
  433.  
  434. {
  435.  
  436.         return(c == _charop(0,0));
  437.  
  438. }
  439.  
  440. /* Clean up the character for a legal MSDOS filename. Convert undesireable
  441.  
  442. characters to a dollar. */
  443.  
  444.  
  445.  
  446. char filtchar(c)
  447.  
  448. char c;
  449.  
  450. {
  451.  
  452.         c&= 0x7f;                       /* strip bit 7, */
  453.  
  454.         if (isswitch(c) || ispath_delim(c) || (c < ' ') || (c > '~') )
  455.  
  456.                 c= '$';                 /* dont allow illegal chars */
  457.  
  458.         c= toupper(c);                  /* all uppercase, */
  459.  
  460.         return(c);
  461.  
  462. }
  463.  
  464. /* Return 1 if the string is a wild filespec. */
  465.  
  466.  
  467.  
  468. wild(string)
  469.  
  470. char *string;
  471.  
  472. {
  473.  
  474. char *p;
  475.  
  476.  
  477.  
  478.         p= string;
  479.  
  480.         while (*p) {
  481.  
  482.                 if (*p == '?')
  483.  
  484.                         return(1);
  485.  
  486.                 if (*p == '*')
  487.  
  488.                         return(1);
  489.  
  490.                 ++p;
  491.  
  492.         }
  493.  
  494.         return(0);                              /* not wild. */
  495.  
  496. }
  497.  
  498. /* Strip the pathname or disk specifier from a filename, return it in a
  499.  
  500. seperate array. We do this by initially copying the entire name in, then
  501.  
  502. searching for the colon or slash. Right after the last one we find,
  503.  
  504. stuff a null, removing the name part. 
  505.  
  506.  
  507.  
  508. Also return a pointer to the name part in the input name. */
  509.  
  510.  
  511.  
  512. strip_path(out,in)
  513.  
  514. char *out;
  515.  
  516. char *in;
  517.  
  518. {
  519.  
  520. char *name;
  521.  
  522. char *endpath;
  523.  
  524.  
  525.  
  526.         strcpy(out,in);                 /* duplicate, for working, */
  527.  
  528.         name= in;                       /* point to name, */
  529.  
  530.         endpath= out;                   /* and end of path part, */
  531.  
  532.  
  533.  
  534.         while (*in) {                   /* look for slashes or colons, */
  535.  
  536.                 if (*in == ':') {       /* if a colon, */
  537.  
  538.                         endpath= ++out; /* point to name, */
  539.  
  540.                         name= ++in;
  541.  
  542.                 } else if (ispath_delim(*in)) {
  543.  
  544.                         endpath= ++out; /* move the pointer up, */
  545.  
  546.                         name= ++in;
  547.  
  548.                 } else {
  549.  
  550.                         ++in;
  551.  
  552.                         ++out;
  553.  
  554.                 }
  555.  
  556.         }
  557.  
  558.         *endpath= '\0';                 /* delete the name part, */
  559.  
  560.         return(name);                   /* return ptr to name part. */
  561.  
  562. }
  563.  
  564.  
  565.  
  566. /* Return true if the character is a legal path name component seperator.
  567.  
  568. The legal ones here are \ or /, depending on what the switch character is. */
  569.  
  570.  
  571.  
  572. ispath_delim(c)
  573.  
  574. char c;
  575.  
  576. {
  577.  
  578.         if ((c == '\\') && (!isswitch('\\'))) return(1);
  579.  
  580.         if ((c == '/') && (!isswitch('/'))) return(1);
  581.  
  582.         return(0);
  583.  
  584. }
  585.  
  586.  
  587.  
  588. 4% ') && (!isswitch('\\'))) return(1);
  589.  
  590.         if ((c == '/') && (!isswitch('/'))) return(1);
  591.  
  592.         return(0