home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / adrule10.zip / ADDRULES.CPP next >
C/C++ Source or Header  |  1994-06-04  |  13KB  |  356 lines

  1. /* Addrules.Cpp
  2.  
  3.  
  4.         Addrules Copyright 1994, Rollin White
  5.  
  6.         Addrules is a simple program to read an EchoAreaList style file
  7.         and ad the area descriptions it contains to either an .SQR or
  8.         .DSC file for use with Maximus.  For an explaination of their
  9.         difference, please see the Max documentation.
  10.  
  11.         This is a quick hack.  There are lots of short cuts, bad naming
  12.         conventions, and inefficencies.  But then what good would a hack
  13.         be without them.
  14.  
  15.         05/31/94        rw  Initial coding.
  16.         06/04/94        rw  Added support for configurable extension
  17.                             Added support for merging files
  18.  
  19.  
  20. */
  21.  
  22. #include <iostream.h>
  23. #include "tree.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <String.h>
  27. #include <ctype.h>
  28. #include <errno.h>
  29.  
  30.  
  31.  
  32.  
  33. /* w_wrap.c */
  34.  
  35. /*
  36. **  This is an attempt at a useful word-wrap function.  It is given an array
  37. **  of characters ( a string ) and it modifies the string, replacing any
  38. **  new-lines found with spaces and placing new-lines where needed to make
  39. **  lines of the width specified, placing them only where there was previously
  40. **  white-space. ( ie. Words are not split across lines. )  At the present
  41. **  time it is rather stupid. 1) It doesn't know enough to split a line at an
  42. **  existing hyphen.  2) It has no clue about how to hyphenate words.  3) It
  43. **  makes no attempt at dealing intelligently with a singly word longer than
  44. **  the specified line length 4) It does not deal intelligently with multiple
  45. **  spaces new-lines, etc. ( eg. has no clue of paragraph seperation, etc. )
  46. **  OTOH, it does deal well with unformatted, left justified text.
  47. **
  48. **  Tabs will be considered the size specified.  Note that word_wrap() does
  49. **  not actually expand tabs.  This is only to inform it of the number of
  50. **  spaces the output device will expand them to, so it will know how much
  51. **  they expand a line.  The only time word_wrap does anything with tabs, is
  52. **  if the tab size is set to zero, in which case each tab is replaced with a
  53. **  single space character.  This often provides the most useful output, since
  54. **  tabs will often be in the wrong places after re-formatting, and is
  55. **  therfore the default.
  56. **
  57. **
  58. **  Publicly available contents:
  59. **
  60. **      char *word_wrap(char *string,long line_len);
  61. **          Does the actual word-wrapping, as described above;
  62. **          Parameters:
  63. **            string:     actual string to work with
  64. **            line_len:   length of lines for output
  65. **          Returns:        pointer to justified string.
  66. **
  67. **          void set_tab_size(int size);
  68. **            Set the number of spaces that tabs will be expanded to on output
  69. **            default tab size is zero. (each tab replaced with a space char )
  70. **            word_wrap does not actually expand tabs.  This only lets it keep
  71. **            track of how many spaces they take up.  If this is set to
  72. **            zero, each tab will be replaced with a single space.
  73. **
  74. **  Other procedures:
  75. **      int get_word(char *string);
  76. **          returns the number of characters in the next word in string,
  77. **          including leading white-space characters.
  78. **
  79. **  This compiles without warnings and runs with the following compilers:
  80. **      MS Quick C 2.51:
  81. **      Borland C++ 2.0:            either as C or C++
  82. **      GNU C++ 1.39, DOS port:     either as C or C++
  83. **  As far as I know, it uses only portable, standard C constructs.  It should
  84. **  compile and run with little or no modification under nearly any C compiler
  85. **  and environment.
  86. **
  87. **
  88. **  This code was written Nov 16, 1991 by Jerry Coffin.
  89. **  It is hereby placed in the public domain, for free use by any and
  90. **  all who wish to do so, for any use, public, private, or commercial.
  91. */
  92.  
  93. #include <stdlib.h>
  94.  
  95. static int tab_size = 0;                  /* size to consider tabs as */
  96. #define EOL '\n'        /* the end of line character */
  97.  
  98. static size_t get_word(char *string);     /* returns size of next word*/
  99.  
  100. void set_tab_size(size_t size)
  101. {
  102.       tab_size = size;
  103. }
  104.  
  105. void word_wrap(char *string, int line_len)
  106. {
  107.       size_t len,                         /* length of current word */
  108.              current_len = 0;             /* current length of line */
  109.      size_t start_line = 0;              /* index of beginning if line */
  110.      int i;
  111.  
  112.       while (0 != (len = get_word(&string[current_len + start_line])))
  113.      {
  114.         i=len;
  115.         while(i>=0)
  116.         {
  117.           if(string[current_len+start_line+i]=='\r' )
  118.           {
  119.             start_line += current_len + 1 + len;
  120.             current_len=0-len;
  121.             i=-1;
  122.             continue;
  123.           }
  124.           i--;
  125.         }
  126.           if (current_len + len < line_len)
  127.                   current_len += len;
  128.             else
  129.             {
  130.                string[start_line+current_len] = EOL;
  131.                start_line += current_len + 1;
  132.                current_len = 0;
  133.           }
  134.      }
  135.      return;
  136. }
  137.  
  138. static size_t get_word(char *string)
  139. {
  140.       register int i = 0, word_len = 0;
  141.  
  142.       if (!string[0])
  143.             return 0;
  144.       while (isspace(string[i]))
  145.       {
  146.           if ('\r' == string[i])
  147.           {
  148.             word_len++;
  149.             break;
  150.           }
  151.             if ('\t' == string[i])
  152.             {
  153.                   if (0 == tab_size)
  154.                         string[i] = ' ';
  155.                   else  word_len += tab_size-1;
  156.             }
  157.             else if ('\n' == string[i])
  158.                   string[i]=' ';
  159.             word_len++;
  160.             i++;
  161.       }
  162.       while (string[i] && !isspace(string[i++]))
  163.             word_len++;
  164.       return word_len;
  165. }
  166.  
  167.  
  168. void ShowUsage( void ){
  169.         cout << "Correct command line is:\n";
  170.         cout << "    ADDRULES <Squish.Cfg> <Elarea.dat> <Ext> [<MergeDir>]\n";
  171.         cout << "    Where:\n";
  172.         cout << "        <Squish.Cfg> is the path and filename of your Squish.Cfg File\n";
  173.         cout << "        <Elarea.Dat> is the path and filename of your ELArea.Dat style file\n";
  174.         cout << "        <Ext> is the three letter extension of the resulting files to have.\n";
  175.         cout << "               Usually SQR or DSC.  For an explaination of the difference,\n";
  176.         cout << "               see the Maximus manual.\n";
  177.         cout << "        <MergeDir> The directory that contains files of the same name as the\n";
  178.         cout << "               area filename to merge with the resulting files.(optional)\n";
  179.         exit(0);
  180. }
  181.  
  182.  
  183. /* replace with C++ stream I/O? */
  184.  
  185. void WriteText ( FILE   *fp, char       *Text){
  186.         if ( fp != NULL )      {
  187.                 fputs(Text, fp);
  188.                 fputs("\n\n", fp);
  189.         }
  190. }
  191.  
  192. void GenerateRule( char *FileName, char *Rule, char *Ext) {
  193.         FILE    *fp = NULL;
  194.         char    Path[4096];    /* Plenty of room for an HPFS path */
  195.  
  196.         if ( FileName != NULL ) {
  197.                 strcpy(Path, FileName);
  198.                 strcat(Path, ".");
  199.                 strcat(Path, Ext);
  200.                 fp = fopen(Path, "w");
  201.                 word_wrap(Rule, 78);
  202.                 WriteText(fp, Rule);
  203.                 fclose(fp);
  204.         }
  205. }
  206.  
  207. int AppendFile ( char *Source, char *AppendFile ){
  208.         FILE    *Src, *Apnd;
  209.         char    Buffer[4096];
  210.  
  211.         Src = fopen(Source, "a+");
  212.         if ( Src == NULL ){
  213.                 return -1;
  214.         }
  215.         Apnd = fopen(AppendFile, "r");
  216.         if ( Apnd == NULL ){
  217.                 return -1;
  218.         }
  219.         fputs("\nConference Rules:\n\n", Src);
  220.         while ( !feof(Apnd) ){
  221.                 fgets(Buffer, sizeof(Buffer), Apnd);
  222.                 fputs(Buffer, Src);
  223.         }
  224.         fclose(Src);
  225.         fclose(Apnd);
  226.  
  227. }
  228.  
  229. void MergeFiles( char *BaseFile, char *Ext, char *SourceDir ){
  230.  
  231.         char    *FileNamePtr;
  232.         char    *DirPtr;
  233.         char    Source[512], Append[512];
  234.  
  235.  
  236.         FileNamePtr = strrchr(BaseFile, '\\');
  237.         if (FileNamePtr == NULL )
  238.                 return;
  239.         FileNamePtr ++;
  240.  
  241.         sprintf(Source, "%s.%s", BaseFile, Ext);
  242.         sprintf(Append, "%s\\%s.txt", SourceDir, FileNamePtr);
  243.         AppendFile(Source, Append);
  244. }
  245.  
  246. int main ( int argc, char *argv[]){
  247.  
  248.         FILE    *Sqfp, *Elfp;
  249.         binary_tree   SquishList;
  250.         char    Buffer[8192];
  251.         char    *Ptr, *Ptr2, *Ptr3;
  252.  
  253.  
  254.         cout << "AddRules V1.0.  Copyright 1994, Rollin White\n";
  255.  
  256.         if ( argc < 4 ){
  257.                 ShowUsage();
  258.         }
  259.  
  260.         /* argv[1] = Squish.cfg
  261.            argv[2] = Elarea.Dat
  262.            argv[3] = extension
  263.            argv[4] = merge dir
  264.            */
  265.  
  266.         if ( ( Sqfp = fopen ( argv[1], "r")) == NULL ){
  267.                 cerr << "Error opening file " << argv[1] << "\n";
  268.                 return -1;
  269.         }
  270.         if (( Elfp = fopen ( argv[2], "r")) == NULL ) {
  271.                 cerr << "Error opening file " << argv[2] << "\n";
  272.                 return -1;
  273.         }
  274.  
  275. /* Parses Squish.Cfg.  This method is far from fool proof and will
  276. encounter a few false hits.  The general method is:
  277.         1.  Search for "Echoarea"
  278.         2.  Skip spaces following the text
  279.         3.  Find the next space and terminate the string there.  The
  280.                 result is the echotag
  281.         4.  Skip spaces.
  282.         5.  Find the next space and terminate there.  The result is the
  283.                 base path for the area.
  284.         6.  The two are added to SquishList which is a template binary
  285.                 tree.
  286. */
  287.  
  288.         cout << "Reading " << argv[1] << "\n";
  289.  
  290.         while ( !feof(Sqfp) ){
  291.                 fgets(Buffer, sizeof(Buffer), Sqfp);
  292.                 Ptr2 = strlwr(Buffer);
  293.                 Ptr = strstr (Ptr2 , "echoarea");
  294.                 if ( Ptr != NULL ){
  295.                         Ptr += 8;
  296.                         while (isspace(*Ptr))
  297.                                 Ptr++;
  298.                         Ptr2 = strchr ( Ptr, ' ');
  299.                         if ( Ptr2 != NULL ){
  300.                                 *Ptr2 = '\0';
  301.                                 Ptr2++;
  302.                                 while ( isspace(*Ptr2) )
  303.                                         Ptr2++;
  304.                                 Ptr3 = strchr ( Ptr2, ' ');
  305.                                 if ( Ptr3 != NULL ){
  306.                                         *Ptr3 = '\0';
  307.                                         if ( strcmp(Ptr2,"") != 0 && strcmp(Ptr,"") != 0){
  308.                                                 SquishList[Ptr] = strdup(Ptr2);
  309.                                                 cout << "Processing " << Ptr << "                     \r";
  310.                                         }
  311.                                 }
  312.                         }
  313.                 }
  314.  
  315.         }
  316.         fclose (Sqfp);
  317.  
  318.  
  319. /* Repeat a similar process for the Echo Area data file.  This time
  320. rather than spaces, we key off of delimter combinations such as quote
  321. comma quote. */
  322.  
  323.         cout << "\nReading " << argv[2] << "\n";
  324.         while ( !feof(Elfp) ){
  325.                 fgets(Buffer, sizeof(Buffer), Elfp);
  326.                 Ptr = Buffer+1;
  327.                 Ptr2 = strchr(Ptr, '\"');
  328.                 if ( Ptr2 != NULL ){
  329.                         *Ptr2 = '\0';
  330.                         Ptr2++;
  331.                         Ptr3 = strstr(Ptr2, "\",\"");
  332.                         if ( Ptr3 != NULL ){
  333.                                 Ptr3+=3;
  334.                                 Ptr2 = strstr(Ptr3, "\",");
  335.                                 if ( Ptr2 != NULL ){
  336.                                         *Ptr2 = '\0';
  337.                                         Ptr2 = SquishList[strlwr(Ptr)];
  338.                                         if ( Ptr2 != NULL ){
  339.                                                 GenerateRule(Ptr2,
  340.                                                         Ptr3, argv[3]);
  341.  
  342.                                                 if ( argc == 5) {
  343.                                                         if (argv[4][strlen(argv[4])] == '\\' )
  344.                                                                 argv[4][strlen(argv[4])] = '\0';
  345.                                                         MergeFiles(Ptr2,argv[3], argv[4]);
  346.                                                 }
  347.                                         }
  348.  
  349.                                         cout << "Processing " << Ptr << "                     \r";
  350.                                 }
  351.                         }
  352.                 }
  353.         }
  354.         fclose(Elfp);
  355. }
  356.