home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 9 / amigaformatcd09.iso / coverdisks / subsdisk / subs.dms / subs.adf / cookie.LZX / cookietool / src / cdbsplit.c next >
Encoding:
C/C++ Source or Header  |  1996-11-19  |  7.7 KB  |  218 lines

  1. /*************************************************************************\
  2.             cdbsplit: split parts off your cookie database,
  3.    by keyword, by line length, by number of lines, or as groups of
  4.                         "similar" cookies.
  5. Expected file format is plain text with a "%%" line ending each cookie. 
  6. Usage:
  7.     cdbsplit [options] <database> <newfile>
  8. options:           meaning:
  9.     -l<lines> / -L<lines>  range for number of lines in a cookie
  10.     -w<width> / -W<width>  range for cookie line width
  11.     -k<keywd> / -K<keywd>  search for (or avoid) a keyword
  12.     -f<n> / -F<n>    extract the first <n> / all but the first <n> cookies
  13.     -m<n>       find groups of cookies starting with <n> matching characters
  14.     -d[0-3]     how fussy about word delimiters? (default: 2)
  15.     -c          case-sensitive comparisons (for both keywords and groups)
  16.     -a          append, if output file exists (instead of failing)
  17. \*************************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include "strstuff.h"
  24.  
  25. char version[] = "$VER: cdbsplit 2.1 (19.11.96)";
  26.  
  27. #define FBUFSIZE 16384  /* we'll use larger file buffers */
  28. #define CBUFSIZE 20000
  29. #define LBUFSIZE 2000
  30. char line[LBUFSIZE];    /* large enough to hold the longest line */
  31. char cbuf[CBUFSIZE];    /* large enough to hold one complete cookie */
  32. char cbak[CBUFSIZE];    /* backup of the last cookie, to find groups */
  33. char uppercase[256];    /* conversion table */
  34.  
  35. int l_min=0, l_max=0, w_min=0, w_max=0, matchlen=0, avoid=0;
  36. long firstonly=0;
  37. char target[100];
  38.  
  39.  
  40. void help(char *s)
  41. /* print a help text and nag about illegal parameter <s> */
  42. {
  43.   if (s) printf("illegal option '%s'\n", s);
  44.   printf("usage:  cdbsplit [options] <cookiefile> <newfile>\n");
  45.   printf("where options are:\n");
  46.   printf(" -l<lines> / -L<lines>  range for number of lines in a cookie\n");
  47.   printf(" -w<width> / -W<width>  range for cookie line width\n");
  48.   printf(" -k<keywd> / -K<keywd>  search for (or avoid) a keyword\n");
  49.   printf(" -f<n>     / -F<n>      extract / avoid the first <n> cookies\n");
  50.   printf(" -m<m>     extract groups of cookies with <m> matching chars\n");
  51.   printf(" -d[0-3]   how fussy about word delimiters? (default: 2)\n");
  52.   printf(" -c        case sensitive comparisons\n");
  53.   printf(" -a        append to an existing output file\n");
  54. }
  55.  
  56.  
  57. void filter_cookies(FILE *fp1, FILE *fp2, FILE *fp3)
  58. {
  59.   long count=0, hits=0, cbuflen, result;
  60.   int ok=0, ok2, lines, width, w;
  61.  
  62.   strcpy(cbak,""); strcpy(cbuf,""); cbuflen = lines = width = 0;
  63.   while (fgets(line,LBUFSIZE,fp1)) {
  64.     if (strncmp(line,"%%",2)==0) {   /* "end of cookie"-marker */
  65.       /* perform the checks: */
  66.       if (matchlen) {
  67.         ok2 = ok; ok = (strn_cmp(cbak, cbuf, matchlen) == 0);
  68.         if (*cbak) {  /* skip the first loop */
  69.           if (ok || ok2) {
  70.             result = fprintf(fp2, "%s%%%%\n", cbak); hits++;
  71.           } else
  72.             result = fprintf(fp3, "%s%%%%\n", cbak);
  73.           if (result<=0) { printf("\nfile error, aborted !!!\n"); exit(20); }
  74.         }                 
  75.         strcpy(cbak, cbuf);
  76.       } else {
  77.         ok = (lines >= l_min) && (width >= w_min);
  78.         if (l_max)  ok = ok && (lines <= l_max);
  79.         if (w_max)  ok = ok && (width <= w_max);
  80.         if (firstonly>0)  ok = ok && (count < firstonly);
  81.         if (firstonly<0)  ok = ok && (count >= -firstonly);
  82.         if (target[0]) {                               
  83.           ok2 = str_str(cbuf, target) != NULL;
  84.           ok = (avoid) ? ok && !ok2 : ok && ok2;
  85.         }
  86.         if (ok) {          /* "good" cookie, copy it */
  87.           result = fprintf(fp2, "%s%%%%\n", cbuf); hits++;
  88.         } else                    /* dump "bad" cookies to the other file */
  89.           result = fprintf(fp3, "%s%%%%\n", cbuf);
  90.         if (result<=0) { printf("\nfile error, aborted !!!\n"); exit(20); }
  91.       }
  92.       count++;
  93.       if (count%100 == 0) {
  94.         printf("Copying cookies, %ld hits, %ld misses.\r", hits, count-hits);
  95.         fflush(stdout);
  96.       }
  97.       strcpy(cbuf,"");    /* start a new cookie */
  98.       cbuflen = lines = width = 0;
  99.     } else {
  100.       w = strlen(line);
  101.       if ((cbuflen += w) >= CBUFSIZE) {
  102.         printf("\ncookie too big (>%ld chars)\n", CBUFSIZE);
  103.         exit(20);
  104.       }
  105.       strcat(cbuf,line); lines++;
  106.       if (w > width)  width = w;
  107.     }
  108.   }
  109.   if (matchlen) {   /* one cookie still pending in this mode */
  110.     if (ok) {
  111.       result = fprintf(fp2, "%s%%%%\n", cbak); hits++;
  112.     } else
  113.       result = fprintf(fp3, "%s%%%%\n", cbak);
  114.     if (result<=0) { printf("\nfile error, aborted !!!\n"); exit(20); }
  115.   }
  116.   printf("\nDone, %ld hits out of %ld.\n", hits, count);
  117. }
  118.  
  119.  
  120. int main(int argc, char *argv[])
  121. {
  122.   char *s;
  123.   char name1[100], name2[100];
  124.   char name3[] = "cdb_temp_kickme";
  125.   int append = 0, case_sense = 0, bordermode = 2;
  126.   FILE *infile, *hitfile, *dumpfile;
  127.  
  128.   name1[0] = name2[0] = target[0] = '\0';
  129.   if (argc < 3) {
  130.     help(NULL);
  131.     return 5;
  132.   }
  133.   while (--argc) {
  134.     s = *++argv;
  135.     if (*s != '-') {
  136.       if (name1[0] == '\0')
  137.         strcpy(name1, s);
  138.       else
  139.         strcpy(name2, s);
  140.     } else {
  141.       switch (*++s) {
  142.         case 'k': strcpy(target, ++s); break;
  143.         case 'K': strcpy(target, ++s); avoid=1; break;
  144.         case 'm': matchlen = atoi(++s); break;
  145.         case 'l': l_min = atoi(++s); break;
  146.         case 'L': l_max = atoi(++s); break;
  147.         case 'w': w_min = atoi(++s); break;
  148.         case 'W': w_max = atoi(++s); break;
  149.         case 'f': firstonly = atol(++s); break;
  150.         case 'F': firstonly = -atol(++s); break;
  151.         case 'a': append = 1; break;
  152.         case 'c': case_sense = 1; break;
  153.         case 'd': if isdigit(*++s)
  154.             bordermode = atoi(s);
  155.           else {
  156.             help(argv[0]); return 5;
  157.           } break;
  158.         default: help(argv[0]); return 5;
  159.       }
  160.     }
  161.   }
  162.   str_setup(bordermode, case_sense);   /* !!! */
  163.   if (name1[0] == '\0' || name2[0] == '\0') {
  164.     help(NULL);
  165.     return 5;
  166.   }
  167.   if (!(infile = fopen(name1,"r"))) {
  168.     printf("Can't open '%s' for input!\n", name1);
  169.     return 10;
  170.   }
  171.   setvbuf(infile, NULL, _IOFBF, FBUFSIZE);
  172.   if (!append && (hitfile = fopen(name2,"r"))) {
  173.     printf("Error: '%s' exists!  Use -a to append.\n", name2);
  174.     return 10;
  175.   }
  176.   if (!(hitfile = fopen(name2,"a"))) {
  177.     printf("Can't open '%s' for output!\n", name2);
  178.     return 10;
  179.   }
  180.   setvbuf(hitfile, NULL, _IOFBF, FBUFSIZE);
  181.   if (!(dumpfile = fopen(name3,"w"))) {
  182.     printf("Can't open '%s' for output!\n", name3);
  183.     return 10;
  184.   }
  185.   setvbuf(dumpfile, NULL, _IOFBF, FBUFSIZE);
  186.   printf("cdbsplit "); print_strstat();
  187.   printf("Extracting from '%s' to '%s',\n", name1, name2);
  188.   if (matchlen) {
  189.     printf("  searching for groups of cookies with %d matching characters.\n",
  190.       matchlen);
  191.   } else {
  192.     if (target[0] != '\0')
  193.       printf("  %s is \"%s\".\n", 
  194.         (avoid) ? "string to avoid" : "search string", target);
  195.     if (l_max)
  196.       printf("  looking for cookies %d - %d lines long.\n", l_min, l_max);
  197.     else if (l_min)
  198.       printf("  looking for cookies at least %d lines long.\n", l_min);
  199.     if (w_max)
  200.       printf("  looking for cookies %d - %d columns wide.\n", w_min, w_max);
  201.     else if (w_min)
  202.       printf("  looking for cookies at least %d columns wide.\n", w_min);
  203.     if (firstonly>0)
  204.       printf("  stopping after %ld cookies.\n", firstonly);
  205.     else if (firstonly<0)
  206.       printf("  starting after %ld cookies.\n", -firstonly);
  207.   }               
  208.   /* OK, here we go: */
  209.   filter_cookies(infile,hitfile,dumpfile);
  210.   fclose(infile); fclose(hitfile); fclose(dumpfile);
  211.   if (remove(name1) != 0 || rename(name3, name1) != 0) {
  212.     printf("Couldn't overwrite the input file!  Your cookies are in '%s'.\n", name3);
  213.     return 5;
  214.   }
  215.   return 0;
  216. }
  217.  
  218.