home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / wp / qp2.zip / QP.C < prev    next >
C/C++ Source or Header  |  1993-03-18  |  9KB  |  384 lines

  1. #include <ctype.h>
  2. #include <conio.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. typedef enum { TRACTOR, MANUAL } _papermode ;
  8. typedef enum { SINGLE, DOUBLE } _printmode ;
  9.  
  10. FILE *printfile = stdout ;
  11. FILE *target = NULL ;
  12. _papermode papermode = MANUAL ;
  13. _printmode printmode = SINGLE ;
  14. int totallines = 0 ;
  15. int totalpages ;
  16. int tabsize = 8 ;
  17.  
  18. #define USLETTER        61
  19. int formlength = USLETTER ;
  20.  
  21. #define ABORT   0x1b
  22.  
  23. #define CPL80   "\x1b\x50"
  24. #define CPL96   "\x1b\x4d"
  25. #define CPL120  "\x1b\x67"
  26. #define CPL137  "\x1b\x50\xf"
  27. #define CPL160  "\x1b\x4d\xf"
  28.  
  29. #define RELEASE "\x12"
  30. #define INIT    "\x1b\x40"
  31.  
  32. #define FORMFEED    '\x0c'
  33. #define TAB        '\t'
  34. #define NEWLINE        '\n'
  35. #define DELIMITATOR    '|'
  36. #define SPACE        ' '
  37. #define BS        '\b'
  38.  
  39. typedef struct {
  40.     int len ;
  41.     char *pitch ;
  42.     char *name ;
  43.     int dbsz ;
  44. } printerline ;
  45. printerline prtl[5] = {
  46.     { 160, CPL160, "160 CPL (ELITE COMPRESS PITCH, 20 CPI)", 79 },
  47.     { 137, CPL137, "137 CPL (PICA COMPRESS PITCH, 17 CPI)", 67 },
  48.     { 120, CPL120, "120 CPL (MICRON PITCH, 15 CPI)", 59 },
  49.     { 96, CPL96, "96 CPL (ELITE PITCH, 12 CPI)", 47 },
  50.     { 80, CPL80, "80 CPL (PICA PITCH, 10 CPI)", 39 }
  51. } ;
  52.  
  53. #define NORMAL  0
  54. int pitch = -1 ;
  55.  
  56. #define MAXCHAR 160
  57. #define BUFSZ 256
  58.  
  59. int formfeed (
  60.     int *counter
  61. ) {
  62.     static int page = 1 ;
  63.  
  64.     if ( *counter == formlength ) {
  65.         fputc( FORMFEED, printfile ) ;
  66.         *counter = 0 ;
  67.         if ( papermode == MANUAL ) {
  68.             fputs( "Insert new paper...\n", stderr ) ;
  69.             if ( getch() == ABORT )
  70.                 return 0 ;
  71.         }
  72.         page++ ;
  73.         fprintf( stderr,
  74.             "Now printing page %d / total is %d pages.\n",
  75.             page, totalpages ) ;
  76.     }
  77.     return 1 ;
  78. }
  79.  
  80. int checkabort ( void )
  81. {
  82.     while ( kbhit() )
  83.         if ( getch() == ABORT ) {
  84.             fputs( "Aborting by user...\n", stderr ) ;
  85.             return 1 ;
  86.         }
  87.     return 0 ;
  88. }
  89.  
  90. int
  91. singleprint ( void )
  92. {
  93.     char s[BUFSZ] ;
  94.     int linecounter = 0, counter = 0 ;
  95.     int i, l ;
  96.  
  97.     while ( !feof( target ) ) {
  98.         if ( checkabort() )
  99.             return 0 ;
  100.         fgets( s, BUFSZ, target ) ;
  101.         l = strlen( s ) ;
  102.         for ( i = 0 ; i < l ; i++ )
  103.             if ( s[i] == FORMFEED ) {
  104.                 counter = formlength ;
  105.                 goto formfee ;
  106.             } else
  107.                 fputc( s[i], printfile ) ;
  108.         linecounter++ ;
  109.         counter++ ;
  110.         if ( linecounter != totallines )
  111. formfee:        if ( !formfeed( &counter ) )
  112.                 return 0 ;
  113.     }
  114.     return 1 ;
  115. }
  116.  
  117. void removetab (
  118.     char *orig,
  119.     char *modi
  120. ) {
  121.     const int l = strlen( orig ) ;
  122.     int i, j, k, m ;
  123.  
  124.     if ( l )
  125.         for ( j = i = 0 ; i < l ; i++ )
  126.             if ( orig[i] == TAB )
  127.                 for ( m = j, k = 0 ;
  128.                     k < tabsize - m % tabsize ; k++, j++ )
  129.                     modi[j] = SPACE ;
  130.             else {
  131.                 modi[j] = orig[i] ;
  132.                 j++ ;
  133.             }
  134.     else
  135.         j = 0 ;
  136.     modi[j] = 0 ;
  137. }
  138.  
  139. void
  140. printline (
  141.     char *left,
  142.     char *right
  143. ) {
  144.     const l = strlen( left ), m = strlen( right ) ;
  145.     const s = prtl[pitch].dbsz ;
  146.     int i, k ;
  147.     for ( i = k = 0 ; i < l && k < s ; i++, k++ ) {
  148.         if ( left[i] == FORMFEED )
  149.             continue ;
  150.         if ( left[i] == BS )
  151.             k -= 2 ;
  152.         else if ( !isprint( left[i] ) )
  153.             k-- ;
  154.         fputc( left[i], printfile ) ;
  155.     }
  156.     for ( ; k < s ; k++ )
  157.         fputc( SPACE, printfile ) ;
  158.     fputc( DELIMITATOR, printfile ) ;
  159.     for ( i = 0 ; i < m ; i++ )
  160.         if ( right[i] != FORMFEED )
  161.             fputc( right[i], printfile ) ;
  162.     fputc( NEWLINE, printfile ) ;
  163. }
  164.  
  165. int
  166. doubleprint ( void )
  167. {
  168.     static char s1[BUFSZ], s2[BUFSZ], s3[BUFSZ] ;
  169.     int counter = 0, linecounter = 0, i, j, k ;
  170.     fpos_t *fpos ;
  171.  
  172.     fpos = ( fpos_t * )malloc( sizeof ( fpos_t ) * formlength * 2 ) ;
  173.  
  174.     if ( fpos == NULL ) {
  175.         fputs( "Not enough memory for double column\n", stderr ) ;
  176.         return 0 ;
  177.     }
  178.     while ( !feof( target ) ) {
  179.         for ( i = 0 ; i < formlength * 2 ; i++ )
  180.             if ( !feof( target ) ) {
  181.                 fgetpos( target, &fpos[i] ) ;
  182.                 do {
  183.                     j = fgetc( target ) ;
  184.                 } while ( !feof( target ) && j != NEWLINE ) ;
  185.             } else
  186.                 fpos[i] = -1 ;
  187.         for ( i = 0 ; i < formlength ; i++ ) {
  188.             s1[0] = s2[0] = s3[0] = 0 ;
  189.             k = 0 ;
  190.             if ( fpos[i] != -1 ) {
  191.                 fsetpos( target, &fpos[i] ) ;
  192.                 fgets( s3, prtl[pitch].dbsz, target ) ;
  193.                 j = strlen( s3 ) ;
  194.                 if ( j > 0 && s3[j - 1] == NEWLINE )
  195.                     s3[j - 1] = 0 ;
  196.                 removetab( s3, s1 ) ;
  197.                 k++ ;
  198.             }
  199.             if ( fpos[i + formlength] != -1 ) {
  200.                 fsetpos( target, &fpos[i + formlength] ) ;
  201.                 fgets( s3, prtl[pitch].dbsz, target ) ;
  202.                 j = strlen( s3 ) ;
  203.                 if ( j > 0 && s3[j - 1] == NEWLINE )
  204.                     s3[j - 1] = 0 ;
  205.                 removetab( s3, s2 ) ;
  206.                 k++ ;
  207.             }
  208.             if ( k ) {
  209.                 if ( checkabort() )
  210.                     return 0 ;
  211.                 printline( s1, s2 ) ;
  212.                 linecounter++ ;
  213.                 counter++ ;
  214.                 if ( linecounter == totallines )
  215.                     goto bye ;
  216.                 if ( !formfeed( &counter ) ) {
  217.                     free( fpos ) ;
  218.                     return 0 ;
  219.                 }
  220.             }
  221.         }
  222.     }
  223. bye:    free( fpos ) ;
  224.     return 1 ;
  225. }
  226.  
  227. void
  228. printout ( void )
  229. {
  230.     int ( *printfunc )( void ) =
  231.         printmode == SINGLE ? singleprint : doubleprint ;
  232.  
  233. #ifndef DEBUG
  234.     if ( printfile == stdprn ) {
  235. #endif
  236.         fputs( "Make sure printer is ON-LINE, and insert paper...\n",
  237.             stderr ) ;
  238.         if ( getch() == ABORT )
  239.             return ;
  240. #ifndef DEBUG
  241.     }
  242. #endif
  243.     fprintf( printfile, INIT ) ;
  244.     fprintf( printfile, prtl[pitch].pitch ) ;
  245.     if ( printfunc() )
  246.         fputc( FORMFEED, printfile ) ;
  247.     fprintf( printfile, INIT ) ;
  248. }
  249.  
  250. preprocess (
  251.     int *wmax,
  252.     int *lmax
  253. ) {
  254.     int max = 0, i, k ;
  255.     char s[BUFSZ] ;
  256.  
  257.     while ( !feof( target ) ) {
  258.         fgets( s, BUFSZ, target ) ;
  259.         for ( k = i = 0 ; i < strlen( s ) ; i++, k++ )
  260.             if ( s[i] == TAB ) {
  261.                 k += tabsize - k % tabsize ;
  262.                 k-- ;
  263.             } else if ( s[i] == BS )
  264.                 k -= 2 ;
  265.             else if ( !isprint( s[i] ) )
  266.                 k-- ;
  267.         totallines++ ;
  268.         if ( max < k )
  269.             max = k ;
  270.     }
  271.     rewind( target ) ;
  272.     *lmax = max ;
  273.     if ( printmode == DOUBLE ) {
  274.         max *= 2 ;
  275.         k = totallines / formlength +
  276.             ( totallines % formlength ? 1 : 0 ) ;
  277.         totallines = formlength *
  278.             ( k / 2 + ( k % 2 ? 1 : 0 ) ) ;
  279.     }
  280.     if ( max <= MAXCHAR )
  281.         for ( k = 0 ; k < 5 ; k++ )
  282.             if ( max <= prtl[k].len )
  283.                 pitch = k ;
  284.     *wmax = max ;
  285.     return pitch != -1 ;
  286. }
  287.  
  288. main (
  289.     int argc,
  290.     char **argv
  291. ) {
  292.     int j, k ;
  293.     char *c ;
  294.  
  295.     if ( argc <= 1 ) {
  296. usage:          fprintf( stderr,
  297.             "Quick Print ! Second Edition\n"
  298.             "Copyright (c) 1993 by Anthony Shih Hao Lee\n\n"
  299.             "Usage: %s -[t|d|p|#num|T<#tab>] file\n"
  300.             "t\tpaper source is tractor (default: manual)\n"
  301.             "p\tsend target to printer (default: console)\n"
  302.             "d\tdouble column printing (defailt: single)\n"
  303.             "#num\tnumber of form (default: 61 lines USLETTER)\n"
  304.             "T<#tab>\tset TAB size (default: 8)\n\n"
  305.             "NB1: This program is ready for Panasonic KXP1124 "
  306.             "in EPSON LQ-2500 mode.\n"
  307.             "NB2: If target is console, then paper source is "
  308.             "tractor.\n"
  309.             "NB3: if double column, line may be truncated to fit "
  310.             "into the column.\n"
  311.             "NB4: Please do not print raw U*IX file due to "
  312.             "newline (0x0a) problem.\n"
  313.             "NB5: if double column, formfeed (0x0c) in the source "
  314.             "will be ignored.\n"
  315.             , argv[0]
  316.         ) ;
  317.         return -1 ;
  318.     }
  319.     for ( j = 1 ; j < argc - 1 ; j++ ) {
  320.             c = argv[j] ;
  321.             if ( *c != '-' && *c != '/' ) {
  322. unknown:                        fprintf( stderr,
  323.                     "ignore unknown option -- `%s'\n",c );
  324.                 continue ;
  325.             }
  326.             c++ ;
  327.             switch ( *c ) {
  328.                 case 'p' :
  329.                     printfile = stdprn ;
  330.                     break ;
  331.                 case 't' :
  332.                     papermode = TRACTOR ;
  333.                     break ;
  334.                 case 'd' :
  335.                     printmode = DOUBLE ;
  336.                     break ;
  337.                 case 'T' :
  338.                     tabsize = atoi( c + 1 ) ;
  339.                     break ;
  340.                 default :
  341.                     goto unknown ;
  342.             }
  343.             if ( isdigit( *c ) )
  344.                 formlength = atoi( c ) ;
  345.     }
  346.     if ( ( target = fopen( argv[argc - 1], "rt" ) ) == NULL ) {
  347.         fprintf( stderr,
  348.             "Cannot find `%s'. aborting...\n", argv[argc - 1] ) ;
  349.         goto usage ;
  350.     }
  351. #ifndef DEBUG
  352.     if ( printfile == stdout )
  353.         papermode = TRACTOR ;
  354. #endif
  355.     if ( !preprocess( &j, &k ) ) {
  356.         fputs( "Warning: some line(s) are too long, <ESC> abort...\n",
  357.             stderr ) ;
  358.         if ( getch() == ABORT )
  359.             return -1 ;
  360.         pitch = NORMAL ;
  361.     }
  362.     fprintf( stderr, "*** STATUS REPORT ***\n"
  363.         "PRINT TARGET : %s\nPAPER SOURCE : %s\nPRINT MODE : %s\n"
  364.         "PAPER LENGTH : %d\nTARGET FILE : %s\nTAB SIZE : %d\n"
  365.         "MAX LINE WIDTH : %d (PRINT WIDTH %d) -- USE %s\n"
  366.         "TOTAL LINES : %d -- USE %d PAGE(S)\n"
  367.         "Whenever you can press <ESC> to abort...\n",
  368.         printfile == stdout ? "CONSOLE" : "PRINTER",
  369.         papermode == MANUAL ? "MANUAL" : "TRACTOR",
  370.         printmode == SINGLE ? "SINGLE COLUMN" : "DOUBLE COLUMN",
  371.         formlength,
  372.         strupr( argv[argc - 1] ),
  373.         tabsize,
  374.         k, j,
  375.         prtl[pitch].name,
  376.         totallines,
  377.         totalpages = totallines / formlength +
  378.             ( totallines % formlength ? 1 : 0 )
  379.         ) ;
  380.     printout() ;
  381.     fcloseall() ;
  382.     return 0 ;
  383. }
  384.