home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / rpos2101.zip / PARSE.C < prev    next >
C/C++ Source or Header  |  1998-07-02  |  10KB  |  355 lines

  1. /*
  2.  * parse.c : Text parsing and searching
  3.  * by Rob Linwood (auntfloyd@biosys.net)
  4.  * Rev 1.1 - 18-Mar-1998 : RCL : Fixed bug in parse
  5.  * Rev 1.2 - 06-Apr-1998 : RCL : Fixed bug in rtrim.  Added other stuff
  6.  * Rev 1.3 - 16-Jun-1998 : RCL : Fixed bug in find.  Removed DOS-specific conio
  7.  * Rev 1.4 - 18-Jun-1998 : RCL : Added all-new numstr.  Rewrote parse to use
  8.  *                               scopy instead of "for" loop
  9.  * To jump to a function, search for ": function" with your editor. (ie,
  10.  * search for ": ws" to jump to ws() )
  11.  *
  12.  * To create a standalone test program, define the STANDALONE symbol.
  13.  * To force parse() to check if the substring number it is passed is valid,
  14.  * define the CHECKALL symbol.
  15.  */
  16.  
  17.    /**********************************************************************
  18.     Parse.c - Text Parsing and Searching Library
  19.     Copyright 1998 Rob Linwood
  20.  
  21.     This program is free software; you can redistribute it and/or modify
  22.     it under the terms of the GNU General Public License as published by
  23.     the Free Software Foundation; either version 2 of the License, or
  24.     (at your option) any later version.
  25.  
  26.     This program is distributed in the hope that it will be useful,
  27.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  28.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  29.     GNU General Public License for more details.
  30.  
  31.     You should have received a copy of the GNU General Public License
  32.     along with this program; if not, write to the Free Software
  33.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  34.     **********************************************************************/
  35.  
  36.  
  37.  
  38. #include <string.h>
  39. #include <ctype.h>
  40.  
  41. #include <stdio.h>
  42.  
  43. #define wspace(x, y) neither( x, ' ', '\t', y )
  44.  
  45. /* Is this a standalone program or just a library? */
  46. #ifdef STANDALONE
  47.  
  48. #include <stdio.h>
  49.  
  50. int firstnot( char *d, const char e, char first );
  51. int neither( char *d, const char e, const char f, char first );
  52. int find( char *d, char *e, int first );
  53. int parse( char *d, int i, char *c );
  54. int numstr( char *d );
  55. char *rtrim( char *str );
  56. char *ltrim( char *str );
  57. int rws( char *str);
  58. char *scopy( char *dest, char *src, int index, int count );
  59. int ws( char *str);
  60.  
  61. void main()
  62. {
  63.   int bob, bob2, i;
  64.   char buf[40] = "";
  65.   
  66.   puts( "firstnot() test" );
  67.   bob = firstnot( "ggggXggggX", 'g', 0 );
  68.   printf( "%d\n", bob );
  69.   bob2 = firstnot( "ggggXggggX", 'g', bob+1 );
  70.   printf( "%d\n", bob2 );
  71.   bob = firstnot( "ggggXggggX", 'g', bob2+1 );
  72.   printf( "%d\n\n", bob );
  73.   
  74.   puts( "neither() test" );
  75.   bob2 = neither( "zggggXggggXz", 'g', 'X', 0 );
  76.   printf( "%d\n", bob2 );
  77.   bob = neither(  "zggggXggggXz", 'g', 'X', bob2+1 );
  78.   printf( "%d\n\n", bob );
  79.   puts( "find() test" );
  80.   bob = find( "Dilbert and     Dogbert", " \t", 0 );
  81.   printf( "%d\n", bob );
  82.   bob2 = find( "Dilbert and     Dogbert", " \t", bob+1 );
  83.   printf( "%d\n\n", bob2 );
  84.   
  85.   puts( "parse() test" );
  86.   for(bob2=1; bob2<15; bob2++) {
  87.     bob = parse( " The  world  is coming to an end!", bob2, buf );
  88.     if( !bob )
  89.       printf( "%s ", buf );
  90.     else
  91.       printf( "Error: %d\n\n", bob );
  92.     /* set to nulls */
  93.     for(i=0; i<strlen(buf); i++) {
  94.         buf[i] = 0;
  95.     }
  96.   }
  97.   printf( "\n" ); 
  98.   
  99.   /* should be -1 */
  100.   puts( "find() test part 2" );
  101.   printf( "%d\n", find( "The happy Teletubby is  purple", " \t", 25 ) );
  102.   
  103.   /* should be 5 */
  104.   puts( "numstr() test" );
  105.   printf( "%d\n", numstr( " The happy Teletubby is  purple" ) );
  106.    
  107. }
  108. #endif  /* ifdef STANDALONE */
  109.  
  110. /*
  111.  * Name: firstnot - Finds first instance of a character which is not the
  112.  *                     one specified
  113.  * Input: d - Pointer to string to search through
  114.  *        e - Char to search against
  115.  *        first - Position in d to start the search at
  116.  * Output: Returns the position of the first character which is not e.
  117.  *         Returns -1 if there was an error
  118.  * Example: firstnot( "ggggXgggX", "g", 0 ) returns 4
  119.  */
  120.  
  121. int firstnot( char *d, const char e, char first )
  122. {
  123.   char k;
  124.   
  125.   for(k=first; k<strlen(d); k++) {
  126.     if( d[k] != e )
  127.       return k;
  128.   }
  129.   return -1;
  130. }
  131.  
  132. /*
  133.  * Name: neither -  Finds the first character after the two specified
  134.  * Input: d - Pointer to the string to search through
  135.  *        e - The first char to search against
  136.  *        f - The second char to search against
  137.  *        first - The location in d to start searching at
  138.  * Output: Returns the location of the first char which is not e or f.
  139.  *         Returns -1 on errors
  140.  * Notes: This is just like firstnot() except it takes to chars as args.
  141.  * Example: neither( "ggggXgggXzgg", 'g', 'X', 0 ) returns 9.
  142.  */
  143.  
  144. int neither( char *d, const char e, const char f, char first )
  145. {
  146.   char k;
  147.   
  148.   for(k=first; k<strlen(d); k++) {
  149.     if( (d[k] != e) && (d[k] != f) )
  150.       return k;
  151.   }
  152.   return -1;
  153. }
  154.  
  155. /*
  156.  * Name: find - Search for any chars in the string e in string d
  157.  * Input: d - pointer to a string to search through
  158.  *        e - pointer to a list of chars to search for
  159.  *        first - location in d to start search at
  160.  * Output: Returns the location of the first occurence of a char in e in d.
  161.  *         Returns -1 on errors
  162.  * Example: find( "xrcedfg", "dg", 0 ) returns 4.
  163.  */
  164.  
  165. int find( char *d, char *e, int first )
  166. {
  167.   int k, k2;
  168.   
  169.   for(k=first; k<strlen(d); k++) {
  170.     for(k2=0; k2<strlen(e); k2++) {
  171.       if( d[k] == e[k2] )
  172.     return k;
  173.     }
  174.   }
  175.   return -1;
  176. }
  177.  
  178. /*
  179.  * Name    : scopy
  180.  * Descrip : Like the Pascal Copy function, scopy copies a portion of a
  181.  *           string from src to dest, starting at index, and going for
  182.  *           count characters.
  183.  * Input   : dest - pointer to a string to recieve the copied portion
  184.  *           src - pointer to a string to use as input
  185.  *           index - character to start copying at
  186.  *           count - number of characters to copy
  187.  * Output  : dest contains the slice of src[index..index+count]
  188.  * Notes   : None
  189.  * Example : scopy( last, "Charlie Brown", 8, 5 ) - puts "Brown" in last
  190. . */
  191.  
  192. char *scopy( char *dest, char *src, int index, int count )
  193. {
  194.   int k;
  195.   
  196.   for(k=0;k<=count;k++) {
  197.     dest[k] = src[k+index];
  198.   }
  199.   dest[k] = '\0';
  200.   return dest;
  201. }
  202.  
  203. /*
  204.  * Name: numstr - Returns number of substrings in a string
  205.  * Input : d - a pointer to the string to search through
  206.  * Output: returns number of substrings in string d
  207.  * Example: numstr( "bob and    Figment  are THE  Bombz  " ) returns 6
  208.  */
  209. int numstr( char *d )
  210. {
  211.  
  212.   int k2, k3;
  213.   int cnt = 0;
  214.  
  215.   k3 = -1;
  216.  
  217.   /* new version */  
  218.   do {
  219.     k2 = wspace( d, k3+1 ); /* find start of substring */
  220.     if( k2 == -1 ) /* if there is no start, we return */
  221.       return cnt;
  222.     k3 = find( d, " \t", k2 ); /* find end of substring */
  223.     if( k3 == -1 )
  224.       return ++cnt;
  225.     ++cnt;   /* increase counter if there is a start & a finish */
  226.   } while( k3 != -1 );
  227.   return -1;
  228. }
  229.  
  230. /*
  231.  * Name: parse - Returns specified substrings seperated by whitespace
  232.  * Input: d - a pointer to the string to parse
  233.  *          i - the number of the substring you want
  234.  *          c - a pointer to the string where we place the substring
  235.  * Output: Returns nonzero on errors and zero when there are no errors
  236.  * Example: parse( " bob ate  cheese", 3, buffer ) places "cheese" in buffer
  237.  */
  238.  
  239. int parse( char *d, int i, char *c )
  240. {
  241.   int k, k2, k3, k4;
  242. #ifdef CHECKALL
  243.   if( i > numstr(d) )
  244.     return -1;
  245. #endif /* ifdef CHECKALL */
  246.  
  247.   k3 = -1;
  248.   
  249.   for(k=1; k<=i; k++) {
  250.     k2 = wspace( d, k3+1 ); /* find start of substring */
  251.     if( k2 == -1 )
  252.       return -1;
  253.     k3 = find( d, " \t", k2 ); /* find end of substring */
  254.   }
  255.   if( k3 == -1 ) { 
  256.     k3 = strlen( d );
  257.   }     
  258.   else
  259.     --k3; 
  260.   
  261.   scopy( c, d, k2, k3-k2 );
  262.    
  263. //  c[k4] = '\0';
  264.  
  265.   return 0;
  266. }
  267.  
  268. /*
  269.  * Name    : rtrim
  270.  * Descrip : Removes all trailing whitespace from a string
  271.  * Input   : str = pointer to a string to strip
  272.  * Output  : Returns a pointer to str
  273.  * Notes   : None.
  274.  * Example : rtrim( "Bob was busy   " ) - returns "Bob was busy"
  275.  */
  276.  
  277. char *rtrim( char *str )
  278. {
  279.  
  280.   int i = strlen( str ) - 1;
  281.   
  282.   while( (isspace(str[i])) && (i>=0) )
  283.     str[i--] = '\0';
  284.   
  285.   return str;
  286. }
  287.  
  288. /*
  289.  * Name    : ltrim
  290.  * Descrip : Removes all leading whitespace from a string
  291.  * Input   : str = pointer to a string to strip
  292.  * Output  : Retruns a pointer to str
  293.  * Notes   : None
  294.  * Example : ltrim( "  Woof! " ) - returns "Woof! "
  295.  */
  296.  
  297. char *ltrim( char *str )
  298. {                                  
  299.   int i, w;                  
  300.   
  301.   w = ws( str );
  302.   if( (w != 0) && (w != -1) ) {
  303.     for(i=0; i<strlen(str)-w; i++) 
  304.       str[i] = str[i+w];
  305.     str[i] = '\0';
  306.   }
  307.   return str;
  308. }
  309.  
  310. /*
  311.  * Name    : rws
  312.  * Descrip : Reverse WhiteSpace: Finds the last charater in a string which
  313.  *           is not a space or a tab
  314.  * Input   : str = pointer to a string to search through
  315.  * Output  : Returns the position of the last non-whitespace character
  316.  * Notes   : Just like, ws(), but backwards
  317.  * Example : rws( "Hey, you!  " ) - returns 8
  318.  */
  319.  
  320. int rws( char *str)
  321. {
  322.   int k;
  323.   
  324.   for(k=strlen(str);k>-1;k--) {
  325.     if( (str[k] != ' ') && (str[k] != '\t') )
  326.       return k;
  327.   }
  328.   return -1;
  329. }
  330.  
  331.  
  332. /*
  333.  * Name    : ws
  334.  * Descrip : WhiteSpace: finds the first character which isn't a tab or space
  335.  * Input   : str = pointer to string to use as input
  336.  * Output  : Returns position of fitsrt non-whitespace character
  337.  * Notes   : none
  338.  * Example : ws( "   Howdy, world!" ) - returns 3
  339.  */
  340.  
  341. int ws( char *str)
  342. {
  343.   int k;
  344.  
  345.   for(k=0;k<strlen(str);k++) {
  346.     if( (str[k] != ' ') && (str[k] != '\t') )
  347.       return k;
  348.   }
  349.   return -1;
  350. }
  351.  
  352.  
  353.  
  354.  
  355.