home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / h2t.zip / H2T.C next >
C/C++ Source or Header  |  1993-05-09  |  12KB  |  336 lines

  1. /***************************************************************************/
  2. /*Hex2text - Text Formatter for IBM(TM) Telnet Hexdump Output              */
  3. /*-------------------------------------------------------------------      */
  4. /*                                                                         */
  5. /* DISCLAIMER: The author assumes no responsibility for the performance    */
  6. /* or lack thereof of this software & is not responsible for any damage to */
  7. /* data or equipment which might be caused for its use. The user assumes   */
  8. /* all responsibility and risk for use and dermination of suitability of   */
  9. /* this program for any purpose. USE AT YOUR OWN RISK. I do.               */
  10. /*                                                                         */
  11. /* LICENSE: You are free to use this program and modify and distribute it  */
  12. /* to your hearts content provided that this source is distributed with    */
  13. /* the program, and no charge (other than a nominal charge for copying and */
  14. /* distribution, e.g. user groups diskettes) is made.                      */
  15. /*                                                                         */
  16. /* Rationale:                                                              */
  17. /* ----------                                                              */
  18. /*Faced with a need to get flat ASCII text output (in a TTY) fashion from  */
  19. /*the library database server, after installing 1.2.1 TCP/IP for OS/2 2.0, */
  20. /*I found I was not able to coax telnet into anything more than civil than */
  21. /*a 3 field dump containing some input/output line codes, hexadecimal, and */
  22. /*a partial ASCII listing in the rightmost column.                         */
  23. /*                                                                         */
  24. /*The "prettydump" option described in the documentation did not seem to   */
  25. /*affect the format of the output, either on or off. File output from      */
  26. /*telnet is enabled by the -n <tracefile> argument or escaping to the      */
  27. /*telnet command prompt & issuing "set tracefile <logfile>". Capture of    */
  28. /*data is toggled by escaping to the telnet command prompt and setting the */
  29. /*netdata option (e.g. "set netdata on").                                  */
  30. /*                                                                         */
  31. /*What comes out of telnet is like this:                                   */
  32. /*                                                                         */
  33. /*--------------------Start Example Hex Dump-------------------------      */
  34. /*< 0x0                53656172 63682072 6573756c 743a2020  |Search result:  |*/
  35. /*< 0x10        32302063 69746174 696f6e73 20696e20  |20 citations in |*/
  36. /*< 0x20        74686520 4d65646c 696e6520 64617461  |the Medline data|*/
  37. /*< 0x30        62617365 0d0a0d0a 546f2064 6973706c  |base....To displ|*/
  38. /*< 0x40        61792041 42535452 4143542c 20747970  |ay ABSTRACT, typ|*/
  39. /*< 0x50        65204420 3c726563 6f726420 6e756d62  |e D <record numb|*/
  40. /*< 0x60        65723e20 4142532e 0d0a5479 70652048  |er> ABS...Type H|*/
  41. /*< 0x70        454c5020 666f7220 6f746865 72206469  |ELP for other di|*/
  42. /*< 0x80        73706c61 79206f70 74696f6e 732e0d0a  |splay options...|*/
  43. /*--------------------End Example Hex Dump---------------------------      */
  44. /*                                                                         */
  45. /*and what hex2text processes it to is this:                               */
  46. /*                                                                         */
  47. /*----------------------Start Example Conversion---------------------      */
  48. /*Search result:  20 citations in the Medline database                     */
  49. /*                                                                         */
  50. /*To display ABSTRACT, type D <record number> ABS.                         */
  51. /*Type HELP for other display options.                                     */
  52. /*----------------------END Example Conversion-----------------------      */
  53. /*                                                                         */
  54. /*For command line switch options just run hex2text with no arguments.     */
  55. /*For anything more complicated, for heavens sake, use 'sed' ....          */                                                                         */
  56. /*                                                                         */
  57. /* Comments and Suggestions (be nice, it's free) to David J. Looney        */
  58. /* Compuserve ID 75246,3364                                                */
  59. /***************************************************************************/
  60.  
  61.     /**** Dependencies/Includes ************/
  62. #ifndef _STDIO_H
  63. #include <stdio.h>
  64. #endif
  65. #ifndef _STDLIB_H
  66. #include <stdlib.h>
  67. #endif
  68. #ifndef _STRING_H
  69. #include <string.h>
  70. #endif
  71. #ifndef _STDARG_H
  72. #include <stdarg.h>
  73. #endif
  74. #ifndef _CTYPE_H
  75. #include <ctype.h>
  76. #endif
  77.  
  78.     /**** Function Declarations *************/
  79. int toupper(int c);
  80. int hc(int c);
  81. void PrintUsage(int c);
  82.  
  83.     /**** Main Program *********************/
  84. void main(int argc, char* argv[])
  85. {
  86.     int  i,j,c,c1,cnt,texln,spflag;
  87.     char currntln[256],BrkStr[128];
  88.     char *DblRet="\r\n\r\n";
  89.     char *BrkPtr;
  90.     static char *texbuf[12000];
  91.     int StripAnsi, CRetLFeed, KeepInput, KeepOutput, FormatPara;
  92.     int FormFeed, SquashSpaces, BreakText;
  93.     FILE *in,*out;
  94.  
  95.     /**** Set Default Settings **************/
  96.     StripAnsi= 1;    CRetLFeed= 0;    KeepInput= 1;
  97.     KeepOutput=1;    FormatPara=0;   FormFeed=  0;
  98.     SquashSpaces=0;    BreakText=0;
  99.  
  100.     /**** Exit if Insufficient Arguments ****/
  101.     if(argc<3) PrintUsage(1);
  102.  
  103.     /**** Otherwise Open Files **************/
  104.     if((in =fopen(argv[1],"r"))==NULL) PrintUsage(2);
  105.     if((out=fopen(argv[2],"w"))==NULL) PrintUsage(3);
  106.  
  107.     /**** Process Options *******************/
  108.     for(c=3; c<argc; c++) {
  109.         if(argv[c][0]!='-' && argv[c][0]!='/') PrintUsage(6);
  110.         switch(toupper(argv[c][1])){
  111.             case 'A' : StripAnsi=0;
  112.                    break;
  113.             case 'B' : BreakText=1;
  114.                    for(i=2; i<=strlen(argv[c]); i++){
  115.                       BrkStr[i-2]=argv[c][i];
  116.                    }
  117.                    break;
  118.             case 'C' : CRetLFeed=1;
  119.                    break;
  120.             case 'F' : FormFeed=1;
  121.                    break;
  122.             case 'I' : KeepInput=0;
  123.                    break;
  124.             case 'O' : KeepOutput=0;
  125.                    break;
  126.             case 'P' : FormatPara=1;
  127.                    CRetLFeed=1;
  128.                    break;
  129.             case 'S' : SquashSpaces=1;
  130.                    break;
  131.             case '?' :
  132.             case 'H' :
  133.             default  : PrintUsage(0);
  134.         }
  135.     }
  136.  
  137.     /**** Read, Parse, and Convert Lines ****/
  138.     /**** Read Lines into Buffer ************/
  139.     /**** Discard All but Hex Code **********/
  140.     texln=0;
  141.     while(fgets(currntln,256,in)!=NULL){
  142.         if(KeepOutput || currntln[0]=='<') {
  143.          if(KeepInput || currntln[0]=='>') {
  144.         texbuf[texln]=(char*) malloc(strlen(currntln)*sizeof(char));
  145.         if(texbuf[texln]==NULL){
  146.             fprintf(stderr,"Out of Memory !\n");
  147.             exit(4);
  148.         }
  149.         strcpy(texbuf[texln],strchr(currntln,'\t'));
  150.         cnt=0;
  151.         for(c=0; c<40; c++){
  152.             if(!isspace(texbuf[texln][c])){
  153.                 texbuf[texln][cnt]=texbuf[texln][c];
  154.                 cnt++;
  155.             }
  156.         }
  157.         texbuf[texln][cnt]=0;
  158.         texln++;
  159.          }
  160.         }
  161.     }
  162.     fclose(in);
  163.  
  164.     /**** Convert Hex to Binary  ************/
  165.     for(i=0; i<texln; i++){
  166.        cnt=0;
  167.        for(j=0; j<strlen(texbuf[i]); j++){
  168.           c=16*hc(texbuf[i][j])+hc(texbuf[i][j+1]);
  169.           j++;
  170.           texbuf[i][cnt]=c;
  171.           cnt++;
  172.        }
  173.        texbuf[i][cnt]=0;
  174.     }
  175.  
  176.     /**** Insert Desired Added Breaks *******/
  177.     if(BreakText){
  178.        strrev(BrkStr);
  179.        for(i=0; i<texln; i++){
  180.           strrev(texbuf[i]);
  181.           if((BrkPtr= strstr(texbuf[i],BrkStr))!=NULL){
  182.          strcpy(currntln,BrkPtr);
  183.          cnt=strlen(texbuf[i])-strlen(currntln);
  184.          texbuf[i][cnt]=0;
  185.          strrev(currntln);
  186.          strrev(texbuf[i]);
  187.          strcat(currntln,DblRet);
  188.          strcat(currntln,texbuf[i]);
  189.          strcpy(texbuf[i],currntln);
  190.           }
  191.           else strrev(texbuf[i]);
  192.        }
  193.     }
  194.  
  195.     /**** Parse Binary as Indicated & Write */
  196.     for(i=0; i<texln; i++){
  197.       cnt=0;
  198.       for(c=0; c<strlen(texbuf[i]); c++){
  199.          if(StripAnsi && texbuf[i][c]==27) c=c+3;
  200.          else {
  201.           if((texbuf[i][c]==0x0C)&&FormFeed)
  202.             {texbuf[i][cnt]=0x0C; cnt++;}
  203.           if(texbuf[i][c]==0x0D){
  204.             if(CRetLFeed){ texbuf[i][cnt]=0x0A; cnt++;}
  205.             else {texbuf[i][cnt]=0x0D; cnt++;}
  206.           }
  207.           if(texbuf[i][c]==0x0A){
  208.             if(!CRetLFeed){texbuf[i][cnt]=0x0A; cnt++;}
  209.           }
  210.           if(texbuf[i][c]>31 && texbuf[i][c]<127){
  211.             texbuf[i][cnt]=texbuf[i][c];
  212.             cnt++;
  213.           }
  214.          }
  215.       }
  216.       texbuf[i][cnt]=0;
  217.     }
  218.  
  219.     /**** Third Pass for Paragraph Format **/
  220.     if(FormatPara){
  221.        for(i=0; i<texln; i++){
  222.           cnt=0;
  223.           for(c=0; c<strlen(texbuf[i]); c++){
  224.          if(texbuf[i][c]==0x0A){
  225.             if(texbuf[i][c+1]==0x0A){
  226.                c++;
  227.                texbuf[i][cnt]=0x0D;
  228.                cnt++;
  229.                texbuf[i][cnt]=0x0A;
  230.                cnt++;
  231.             }
  232.          }
  233.          else {texbuf[i][cnt]=texbuf[i][c];  cnt++;}
  234.           }
  235.           texbuf[i][cnt]=0;
  236.        }
  237.     }
  238.  
  239.     /**** Second Pass for Stripping Spaces **/
  240.     if(SquashSpaces){
  241.        spflag=0;
  242.        for(i=0; i<texln; i++){
  243.           cnt=0;
  244.           for(c=0; c<strlen(texbuf[i]); c++){
  245.          if(texbuf[i][c]==0x20){
  246.             if(!spflag) {texbuf[i][cnt]=0x20; cnt++; spflag=1;}
  247.          } else {
  248.             texbuf[i][cnt]=texbuf[i][c];
  249.             cnt++;
  250.             spflag=(isspace(texbuf[i][c])?1:0);
  251.          }
  252.           }
  253.        texbuf[i][cnt]=0;
  254.        }
  255.     }
  256.  
  257.     /**** Output to File, Free Memory *******/
  258.     for(i=0; i<texln; i++){
  259.        for(c=0; c<strlen(texbuf[i]); c++){
  260.           fputc((int) texbuf[i][c],out);
  261.        }
  262.        free((char*) texbuf[i]);
  263.     }
  264.     free((char**)texbuf);
  265.     fclose(out);
  266. }
  267.  
  268.  
  269. int toupper(int c)
  270. {
  271.     return(((c>96)&&(c<123))?c-32:c);
  272. }
  273.  
  274. void PrintUsage(int code)
  275. {
  276.     fprintf(stderr,"╔══════════════════════════════════════════════════════════╗\n");
  277.     fprintf(stderr,"║HEX2TEXT Text Formatter Utility for IBM(TM) Telnet Hexdump║\n");
  278.     fprintf(stderr,"║by David J. Looney, 05-09-93.                             ║\n");
  279.     fprintf(stderr,"╚══════════════════════════════════════════════════════════╝\n");
  280.     fprintf(stderr,"Usage:\n");
  281.     fprintf(stderr,"h2t <infile> <outfile> [-/aA] [-/iI] [-/oO] [-/pP] [-/hH?]\n");
  282.     fprintf(stderr,"Where - or / is the delimiter character,\n");
  283.     fprintf(stderr,"  aA|NSI/VTxxx codes are kept,\n");
  284.     fprintf(stderr,"  bB|phrase inserts <LF><LF> after \"phrase\",\n");
  285.     fprintf(stderr,"  cC|arraige Return ---> Linefeeds,\n");
  286.     fprintf(stderr,"  fF|ormfeeds are kept,\n");
  287.     fprintf(stderr,"  hH|elp - prints this message,\n");
  288.     fprintf(stderr,"  iI|ncoming lines are skipped,\n");
  289.     fprintf(stderr,"  oO|utput from keyboard is skipped,\n");
  290.     fprintf(stderr,"  pP|aragraph - keeps CR/LF only if double,\n");
  291.     fprintf(stderr,"  sS|paces are compressed.\n");
  292.     fprintf(stderr,"E.g. \"hex2text foo.log foo.txt /o /p /s /boptions.\" formats output\n");
  293.     fprintf(stderr,"     from UCSD Melvyl Library System for direct import to DeScribe.\n\n");
  294.     exit(code);
  295. }
  296.  
  297. int hc(int i)
  298. {
  299.     switch(toupper(i)) {
  300.         case '0'    : i=0;
  301.                   break;
  302.         case '1'    : i=1;
  303.                   break;
  304.         case '2'    : i=2;
  305.                   break;
  306.         case '3'    : i=3;
  307.                   break;
  308.         case '4'    : i=4;
  309.                   break;
  310.         case '5'    : i=5;
  311.                   break;
  312.         case '6'    : i=6;
  313.                   break;
  314.         case '7'    : i=7;
  315.                   break;
  316.         case '8'    : i=8;
  317.                   break;
  318.         case '9'    : i=9;
  319.                   break;
  320.         case 'A'    : i=10;
  321.                   break;
  322.         case 'B'    : i=11;
  323.                   break;
  324.         case 'C'    : i=12;
  325.                   break;
  326.         case 'D'    : i=13;
  327.                   break;
  328.         case 'E'    : i=14;
  329.                   break;
  330.         case 'F'    : i=15;
  331.                   break;
  332.         default        : i=10;
  333.     }
  334.     return(i);
  335. }
  336.