home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1987 / 07 / filter / filter.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-10  |  13.2 KB  |  346 lines

  1. /********************************************************************
  2. *  TITEL           :  Filterprogramm                                *
  3. *                                                                   *
  4. *  DATEI           :  filter.c                                      *
  5. *  VERSION         :  1.0                                           *
  6. *  AUTOR           :  Joachim Eckart                                *
  7. *  DATUM           :  12/86                                         *
  8. ********************************************************************/
  9. /* usage filter.ttp [-m] [-c] [-b] [-fFILTERDATEI] QUELLE [ZIEL]    *
  10. *                                                                   *
  11. *         m: ausblenden 7. bit -- Radikalkur                        *
  12. *         c: Controlcodes au₧er CR,LF ausfiltern                    *
  13. *            gefiltert wird erst nach Umsetzung (s. Filterdatei)    *
  14. *         f: Name der Filterdatei, fehlt dieser wird nur gemä₧      *
  15. *            -m,-c,-b gefiltert. Im Extremfall wird nur kopiert.    *
  16. *         b: aus mehreren aufeinanderfolgenden blanks wird eins     *
  17. *            gemacht                                                *
  18. *    QUELLE: zu filternde Datei                                     *
  19. *      ZIEL: gefilterte Datei, fehlt diese wird FILTER.FIL          *
  20. *            genommen.                                              *
  21. *                                                                   *
  22. * Anmerkung: Die Reihenfolge der Argumente ist beliebig. Als QUELLE *
  23. *            wird das erste Nicht-Schalter-Argument genommen. Das   *
  24. *            zweite, falls vorhanden ist das ZIEL.                  *
  25. *   FILTER-                                                         *
  26. *   DATEI  : Mit beliebigem Editor erstellte Datei. Enthält pro     *
  27. *            Zeile eine Umsetzungsanweisung der Form: xxx yyy .     *
  28. *            Das Zeichen mit dem dezimalen Code xxx wird durch yyy  *
  29. *            ersetzt. 999 für yyy filtert das Zeichen xxx völlig    *
  30. *            aus. xxx und yyy können durch eine beliebige nicht     *
  31. *            numerische Zeichenfolge getrennt werden. Werden führ-  *
  32. *            ende Nullen nicht weggelassen ist überhaupt kein Trenn-*
  33. *            zeichen erforderlich. Beginnt eine Zeile mit '*' oder  *
  34. *            ';' wird dise Zeile als Kommentar angesehen. Sie werden*
  35. *            zur Laufzeit angezeigt, soda₧ der Ablauf gut zu ver-   *
  36. *            folgen ist.                                            *
  37. ********************************************************************/
  38.  
  39. #include <stdio.h>
  40. #include "arg.h"         /* Definitionen für Argument Parser       */
  41. #include "scr.h"         /* an sich  .c ,aber dann übersetzt make  */
  42. #include "itoa.h"        /* an sich  .c ,aber dann übersetzt make  */
  43.  
  44. /*******************************************************************/
  45. /*          Globale Variablen und Funktionen für ARGUMENTS         */
  46. /*******************************************************************/
  47.  
  48. FILE *in,*out,*fil;  /*         File handles                        */
  49.  
  50. int filt[256];  /* gelesenes Zeichen wird gemä₧ Inhalt gefiltert    */
  51.  
  52. char *err[]= {  /*  Fehlermeldungen                                 */
  53.               "Fehler in Argumenten",                      /*   0   */
  54.               "Öffnen Filterdatei nicht möglich !",        /*   1   */
  55.               "Öffnen Eingabedatei nicht möglich !",       /*   2   */
  56.               "Öffnen Ausgabedatei nicht möglich !",       /*   3   */
  57.               "Falsche Struktur in der Filterdatei !",     /*   4   */
  58.               "Fehler beim Lesen aus  Eingabedatei !",     /*   5   */
  59.               "Fehler beim Schreiben in Ausgabedatei !",   /*   6   */
  60.               "Ein - und Ausgabedatei sind identisch !",   /*   7   */
  61.               "Programm abgebrochen -- Drücke Taste",      /*   8   */
  62.              };
  63. char *info[] = {             
  64.      "usage filter.ttp [-m] [-c] [-b] [-fFILTERDATEI] QUELLE [ZIEL]",
  65.      "",
  66.      "-m    : Ausblenden 7. bit  (Radikalkur).",
  67.      "-c    : Controlcodes au₧er CR,LF ausfiltern.",
  68.      "        Gefiltert wird erst nach Umsetzung.",
  69.      "-f    : Name der Filterdatei, fehlt dieser wird nur gemä₧",
  70.      "        -m,-c,-b gefiltert. Im Extremfall wird nur kopiert.",
  71.      "-b    : Aus mehreren aufeinanderfolgenden blanks wird eins",
  72.      "        gemacht.",  
  73.      "QUELLE: Zu filternde Datei",    
  74.      "ZIEL  : Gefilterte Datei; fehlt diese wird FILTER.FIL",
  75.      "        genommen."
  76. };
  77. #define ISIZE ( sizeof(info)/ sizeof(char *) )       /* Einträge    */
  78.              
  79. int mask = 0xff;    /* = 1111 1111 d.h Zeichen bleibt wie es ist    */
  80. int control = 0;    /* wenn 1, dann control codes filtern           */
  81. int blank = 0;      /* wenn 1, dann blanks killen                   */
  82. char *filtfile = "";      /* unbedingt als pointer nicht als Vektor */
  83. char *infile = "required.dat";   /*          "             "        */
  84. char *outfile = "filter.fil";    /*          "             "        */
  85.  
  86. mask_f()  /* wenn Schalter -m vorhanden wird das 7. bit maskiert    */
  87. {
  88. mask=0x7f; /* Radikalfilter ausknipsen 7.bit durch bitweises und    */
  89. }          /* = 0111 1111                                           */
  90.  
  91. out_f(s) /* wird immer aufgerufen, wenn in argv dann zeigt s darauf */
  92. register char *s; /* andernfalls ist s ein Leerstring               */
  93. {
  94. if (strlen(s)) 
  95.   outfile = s; 
  96. }
  97.  
  98. ARGUMENTS arg_tab[] = {
  99. OPT,FUNC,SCHALTER,'M',(long )&mask_f,      /* mask_f() Adresse      */
  100. OPT,BOOLEAN,SCHALTER,'C',(long)&control,   /* Adresse control       */
  101. OPT,BOOLEAN,SCHALTER,'B',(long)&blank,     /* Adresse blank         */
  102. OPT,STRING,SCHALTER,'F',(long )&filtfile,  /* Zeiger auf Zeiger     */
  103. NON_OPT,STRING,NO_SCHLT,' ',(long )&infile,/* Zeiger auf Zeiger     */
  104. OPT,FORCE_FUNC,NO_SCHLT,' ',(long )&out_f  /* out_f() immer         */
  105. };
  106.  
  107. #define TSIZE ( sizeof(arg_tab)/ sizeof(ARGUMENTS) ) /* Einträge    */
  108.  
  109. /********************************************************************/
  110. /*                     Hilfsfunktionen für main()                   */
  111. /********************************************************************/
  112.  
  113. usage(message)                      /* Fehlermeldung und Abbruch    */
  114. register char *message;
  115. {   
  116.     pos(0,24);rev_on();
  117.     put_s(message); 
  118.     rev_off();
  119.     get_hidden();
  120.     exit(); /* Schlie₧en aller Dateien und Programm beenden         */
  121. }
  122.  
  123. help()
  124. {
  125. register int i;
  126.   cls();
  127.   for(i = 0; i < ISIZE; i++)
  128.     {
  129.       pos(10,i + 1);
  130.       put_s(info[i]);
  131.     }
  132.   usage(err[0]);
  133. }
  134.  
  135. var_init()  /* filt[0] = 0, ......filt[255] = 255                   */             
  136. {
  137. register int i;
  138.   crs_off();
  139.   i = -1;
  140.   while(++i < 256)
  141.     filt[i]= i;
  142. }
  143.  
  144. get_filtfile() /* Filterdatei lesen/ verarbeiten und schlie₧en      */
  145. {
  146. char line[81];
  147. register char *lp; 
  148. static int lc = 0;    /* line counter für Filterdatei               */
  149.  lp = line;
  150.  if(!(fil = fopen(filtfile,"r"))) usage(err[1]);
  151.  while((fgets(lp,81,fil)) != (char *) 0)
  152.    {
  153.      lc++; /* mitzählen für Ausgabe Zeilennummer im Fehlerfall      */
  154.      *(lp + strlen(lp) - 1) = '\0'; /* newline weg                  */
  155.      if(*lp == '*' || *lp == ';')   /* Kommentarzeile ?             */
  156.        disp_comment(line + 1);      /* Kommentar anzeigen           */
  157.      else if(!parse_line(lp)) { put_fs(23,REV | LEFT,"ZEILE :");
  158.                               print_i(lc);
  159.                               usage(err[4]);} /* Fehlerhafte Zeile  */
  160.    }
  161.  fclose(fil);
  162. }
  163.  
  164. #define isdigit(c) ((c) >= '0' && (c) <= '9') /*      Ziffer ?      */
  165. #define outrange(z) ((z) < 0 || (z) > 255)    /*  8 bit ascii ?     */
  166. #define EOL (*line == '\0')  /* übers Stringende hinaus ?           */
  167.  
  168. int parse_line(line) /* zwei Zahlen in Zeile suchen                 */
  169. register char *line;
  170. {
  171. register char a[4];
  172. int x,y,i;
  173.  
  174.   i = 0; a[0] = '\0';
  175.   while(!isdigit(*line) && !EOL) 
  176.   line ++;                          /* mache nichts wenn keine Zahl */
  177.   
  178.   while(isdigit(*line) && i < 4 && !EOL) /* hole erste Zahl         */         
  179.     a[i++] = *line++;
  180.   a[i] = '\0';
  181.   if(strlen(a))     /*     überhaupt was zahlartiges gelesen ?      */
  182.     x = atoi(a);
  183.   else x = 9999;    /*  dummy-wert für keine Zahl gelesen           */
  184.   
  185.   i = 0; a[0] = '\0';
  186.   while(!isdigit(*line) && !EOL) 
  187.   line++;                           /* mache nichts wenn keine Zahl*/
  188.   
  189.   while(isdigit(*line) && i < 4 && !EOL) /* hole zweite Zahl        */         
  190.     a[i++] = *line++;
  191.   a[i] = '\0';
  192.   if(strlen(a))
  193.     y = atoi(a);
  194.   else y = 9999; /*  dummy-wert für keine Zahl gelesen              */
  195.  
  196.   if(outrange(x) || (outrange(y) && y != 999)) 
  197.     return(0);       /* 999 ist ok , bedeudet ausfiltern            */   
  198.   else {
  199.     filt[x] = y;
  200.     return(1);   }   /* Zeile war ok                                */
  201. }
  202.  
  203. open_files()  /* Quell- und Zieldatei öffnen                        */
  204. {
  205.   if(!(in = fopen(infile,BR))) usage(err[2]); 
  206.   if(!(out = fopen(outfile,BW))) usage(err[3]); 
  207. }
  208.  
  209. close_files() /* Quell- und Zieldatei schlie₧en                     */
  210. {
  211.   fclose(in);
  212.   fclose(out);
  213.   crs_on();
  214. }
  215.  
  216. check_error()  /* Lesefehler ?                                      */
  217. {
  218.   if(ferror(in)) usage(err[5]);
  219.   if(ferror(out)) usage(err[6]);
  220. }
  221.  
  222. display()     /*      Titel anzeigen                                */
  223. {
  224.   cls();
  225.   put_fs(2,REV | CENTER,
  226.          "************************************************");
  227.   put_fs(3,REV | CENTER,
  228.          "***                F I L T E R               ***");
  229.   put_fs(4,CENTER,"*** Simultanfilterprogramm für Einzelzeichen ***");
  230.   put_fs(5,CENTER,"***   (C) 1986 by J.Eckart & PASCAL Int.     ***");
  231.   put_fs(6,REV | CENTER,
  232.          "************************************************");
  233.  
  234. }
  235.  
  236. disp_comment(s)  /* display a comment line                          */
  237. register char *s;
  238. {
  239. static int cnt = 1;
  240.   if(strlen(s) > 62) *(s + strlen(s)) = '\0';
  241.   if(!(cnt % 8)) cnt = 1;
  242.   pos(16,14 + cnt++);
  243.   clrright();
  244.   put_s(s);
  245. }
  246.  
  247. show_file()                        /* Dateiinfo anzeigen            */
  248. {
  249.     rev_on();
  250.     pos(16,8);put_s("EINGABE :");
  251.     pos(16,9);put_s("AUSGABE :");
  252.     pos(16,10);put_s("FILTER  :");
  253.     pos(16,11);put_s("MASKE   :");
  254.     pos(16,12);put_s("^CODES  :");
  255.     pos(16,13);put_s("BLANKS  :");
  256.     rev_off();
  257.     pos(25,8);put_s(infile);
  258.     pos(25,9);put_s(outfile); 
  259.     pos(25,10);
  260.     if(strlen(filtfile))
  261.       put_s(filtfile);
  262.     else
  263.       put_s("keine Filterdatei");
  264.     pos(25,11);
  265.     if(mask == 0x7f)
  266.       put_s("Ja");
  267.     else
  268.       put_s("Nein"); 
  269.     pos(25,12);
  270.     if(control)
  271.       put_s("Filtern");
  272.     else
  273.       put_s("Nicht filtern");
  274.     pos(25,13);
  275.     if(blank)
  276.       put_s("viele --> eins");
  277.     else
  278.       put_s("so lassen");      
  279. }
  280.  
  281. ok()   /*  Noch mal nachfragen                                      */
  282. {
  283. int c;
  284.   put_fs(24,REV | RIGHT,"Ausführung starten? J/N");
  285.   c = get_hidden();
  286.   if (c != 'J' && c != 'j') usage(err[8]);
  287.   put_fs(24,REV | RIGHT,"J  ");
  288. }
  289.   
  290. ready() /* Ende kundtun                                             */
  291. {
  292.   put_fs(24,REV | RIGHT,"FERTIG -- TASTE DRÜCKEN");
  293.   get_hidden();
  294. }
  295.  
  296. /********************************************************************/
  297. /*                               main()                             */
  298. /********************************************************************/
  299.  
  300. #define iscntrl(c) ( ((c) >= 0 && (c) < 32 || (c) == 127)\
  301.                     && !((c) == 10 || (c) == 13) ) /* control code? */
  302. main(argc,argv)
  303. int argc;
  304. char **argv;
  305. {
  306. int i;
  307. int c,lastc;        /* gelesenes und zuletzt gelesenes Zeichen      */
  308. char m[10];
  309. var_init();
  310. lastc = 333;       /* nicht vorkommender Wert als Initialisierung   */
  311.  
  312. if(parse_args(argc,argv,arg_tab,TSIZE)) /* Argument Parser aufrufen */
  313.   help();                               /* Fehler in Argumenten     */
  314.   
  315. cls();
  316. display(); 
  317. show_file();                            /* Anzeigen                 */
  318. if(!strcmp(infile,outfile))  /*   Quelle und Ziel identisch         */
  319.   usage(err[7]);   /*  das darf aber nicht sein                     */
  320. ok();              /*  wirklich alles in Ordnung so ?               */
  321. if(strlen(filtfile))
  322.   get_filtfile();  /*  Filerdatei bearbeiten                        */
  323. open_files();      /*  Quelle und Ziel öffnen                       */
  324. pos(0,24);         /*  falls Ausgabe mit CON: als Ziel              */
  325.  
  326. while((c = getc(in)) != EOF)    /*     Zeichen lesen                */
  327.   {
  328.     check_error();              /*  Lesefehler ?                    */
  329.     if(filt[c] == 999) continue;   /* Zeichen unterschlagen         */
  330.     
  331.     c &= mask;  /*  Maskieren - ohne -m Schalter nur Pseudo         */
  332.     if(blank && c == ' ' && lastc == ' ')  /* blanks killen ?       */
  333.         continue ; 
  334.  
  335.     if( !(control && iscntrl(c))   /* control code und -c prüfen    */
  336.        || c != filt[c]         )   /* umgesetzte haben Priorität    */
  337.        
  338.       putc((char)filt[c],out);     /* Zeichen schreiben             */
  339.     lastc = c;
  340.   }
  341.   
  342. close_files();                     /* Dateien schlie₧en             */
  343. ready();                           /* fertig                        */
  344. }
  345. /*          EOS    E n d  O f  S o u r c e                          */
  346.