home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / printer / pcroff.arc / SOURCE.ARC / PRINTCAP.C < prev    next >
Text File  |  1985-03-23  |  6KB  |  252 lines

  1. /*    READS IN THE PRINTCAP FILE AND SETS VARIABLES IN PCROFF */
  2.  
  3. #include <stdio.h>
  4. #include <b:printcap.h>
  5.  
  6. #define    ESC    '\033'
  7. #define    DQUOTE    '\042'
  8. #define    BSLASH    '\134'
  9.  
  10. #define    INIT    1
  11. #define    CKNAME    2
  12.  
  13. int    lineno = 1;
  14. int    o_dev;
  15. int    c;        /* LAST CHARACTER READ */
  16. char    workword[80], printer[4];
  17. FILE    *Pcapfile;
  18.  
  19. /*
  20.  *    READ THE "PRINTCAP" FILE, AND SET UP PARAMETERS
  21.  */
  22. printcap ()
  23. {
  24.     int j;
  25.     if (NULL ==(Pcapfile = fopen("PRINTCAP","r"))) {
  26.         if (printer[0]=='\0') {
  27.             fprintf(stderr,"PCroff: no default in PRINTCAP file\n");
  28.             fprintf(stderr,"   Using -t style printer control\n");
  29.             o_dev=2;
  30.             return (0);
  31.         }
  32.         fprintf(stderr,"PCroff: cannot open PRINTCAP file\n");
  33.         exit(1);
  34.     }
  35.     if (printer[0]=='\0')     /* NEED DEFAULT PRINTER */
  36.         if (!get_default()) return;
  37.     for (j=0;j<3;j++)  printer[j] = tolower(printer[j]);    /* CONVERT
  38.                    PRINTER NAME TO LOWER CASE FOR SEARCH */
  39.     fprintf(stderr,"PCroff: using printer spec for  %s \n",printer);
  40.     while (!nextprint()) {}    /* CONTINUE READING PRINTER SPECS
  41.                    UNTIL FOUND OR NO MORE */
  42. }
  43.  
  44. /*
  45.  *    IF THE NEXT PRINTER SPEC IS A "DEFAULT" STATEMENT,
  46.  *    PUT THE NAME IN "PRINTER". OTHERWISE SET UP TO USE -t PRINTER
  47.  */
  48. int
  49. get_default ()
  50. {
  51.     int i;
  52.     getword(workword);
  53.     if (strcmp (workword,"default")) {
  54.         fprintf(stderr,"PCroff: no default in PRINTCAP file\n");
  55.         fprintf(stderr,"   Using -t style printer control\n");
  56.         o_dev=2;
  57.         return (0);
  58.     }
  59.     getuntil('=');
  60.     getword(workword);
  61.     strncpy(printer,workword,3);
  62.     if (skipspace()) errout("unexpected end of PRINTCAP file.");
  63.     if (getc(Pcapfile) != '.') errout("default spec missing period.");
  64. }
  65.  
  66. /*
  67.  *    READ THE NEXT PRINTER SPEC.  IF A DEFAULT STATEMENT, CHUCK IT.
  68.  *    IF IT'S FOR THE SPECIFIED PRINTER, EXECUTE IT AND RETURN 1.
  69.  *    OTHERWISE CHUCK IT AND RETURN 0;
  70.  */
  71. int
  72. nextprint()
  73. {
  74.     /*    THIS WORKS ON A STATE-MACHINE BASIS.  SEE THE #DEFINES
  75.      *    FOR THE STATE DEFINITIONS.
  76.      */
  77.     int state,retflag;
  78.     char pname[3];        /* CURRENT PRINTER NAME */
  79.     retflag=0;
  80.     state=INIT;
  81.     if (skipspace()) errout("can't find spec for correct printer.");
  82.  
  83.     for (;;) {    /* MAIN LOOP OF STATE MACHINE */
  84.         if(skipspace()) errout("unexpected end of PRINTCAP file.");
  85.         switch (state) {
  86.         case INIT:
  87.             getword(workword);
  88.             if (!strcmp (workword,"default")) {
  89.                 getuntil('=');
  90.                 getword (workword);
  91.                 getuntil('.');
  92.                 return(0);
  93.             }
  94.             if (!strncmp (workword,printer,3))    /* MATCH */
  95.                 retflag=1;
  96.             state=CKNAME;
  97.             break;
  98.         case CKNAME:
  99.             switch (c=getc(Pcapfile)) {
  100.             case '.':    /* END OF THIS SPEC */
  101.                 return (retflag);
  102.                 break;
  103.             case '|':    /* ANOTHER NAME */
  104.                 state=INIT;
  105.                 break;
  106.             case ',':
  107.             case ':':
  108.             case ';':    /* DO A PARAMETER */
  109.                 getparm(retflag);
  110.                 break;
  111.             default:
  112.                 errout("illegal separator in PRINTCAP file");
  113.             }
  114.             break;
  115.         }
  116.     }
  117.     return retflag;
  118. }
  119.  
  120. /*
  121.  *    GET THE NEXT WORD, IF ANY, AND CONVERT TO LOWER CASE
  122.  */
  123. getword (word)
  124. char *word;
  125. {
  126.     if (skipspace()) errout("premature end of PRINTCAP file");
  127.     for (;;) {
  128.         c = getc(Pcapfile);
  129.         if (c==EOF) errout("premature end of PRINTCAP file");
  130.         if (!isalnum(c)) break;
  131.         /* SUCK ALPHANUMERICS INTO *word, CONVERTING TO LOWER */
  132.         *word++ = tolower (c);
  133.     }
  134.     ungetc(c,Pcapfile);
  135.     *word = '\0';
  136. }
  137.  
  138. /*
  139.  *    READ IN THE NEXT PARAMETER SPECIFICATION, AND EXECUTE IT
  140.  *    IF FLAG NOT ZERO.
  141.  */
  142. getparm(flag)
  143. int flag;
  144. {
  145.     struct fontstring parmval;
  146.     getword (workword);
  147.     getuntil('=');
  148.     getseq(&parmval);
  149.     if (!flag) return;
  150.     if (!strcmp (workword,"us")) copyfont(&parmval,&s_ul);
  151.     if (!strcmp (workword,"ue")) copyfont(&parmval,&e_ul);
  152.     if (!strcmp (workword,"bs")) copyfont(&parmval,&s_bo);
  153.     if (!strcmp (workword,"be")) copyfont(&parmval,&e_bo);
  154.     if (!strcmp (workword,"is")) copyfont(&parmval,&s_it);
  155.     if (!strcmp (workword,"ie")) copyfont(&parmval,&e_it);
  156. }
  157.  
  158. /*
  159.  *    COPY A FONTSTRING SPECIFICATION FROM ONE STRUCT TO ANOTHER
  160.  */
  161. copyfont (from,to)
  162. struct fontstring *from,*to;
  163. {
  164.     int i;
  165.     to->len=from->len;
  166.     for (i=0; i<from->len; i++)
  167.         to->seq[i] = from->seq[i];
  168. }
  169.  
  170. /*
  171.  *    READ FROM PRINTCAP A SEQUENCE SURROUNDED BY DOUBLE QUOTES
  172.  */
  173. getseq (cseq)
  174. struct fontstring *cseq;
  175. {
  176.     int octnum, i;
  177.     char *ss;
  178.     ss = cseq->seq;
  179.     cseq->len=0;
  180.     if (skipspace()) errout("unexpected end of PRINTCAP file");
  181.     if ((c=getc(Pcapfile))!=DQUOTE) errout("double quote expected");
  182.     for (;;) {
  183.         c = getc(Pcapfile);
  184.         if (c==EOF) errout("premature end of PRINTCAP file");
  185.         if (c==DQUOTE) break;    /* FOUND END OF WORD */
  186.         if (c==BSLASH) {    /* READ OCTAL CHARACTER */
  187.             octnum=0;
  188.             for (i=0; i<3; i++) {
  189.                 c=getc(Pcapfile);
  190.                 if (c>='0' && c<='7')
  191.                     octnum = 8*octnum + c - '0';
  192.                 else
  193.                   errout("error in reading octal number");
  194.             }
  195.             c = octnum;
  196.         }
  197.         *ss++ = c;    /* STORE THE CHARACTER IN CSEQ */
  198.         cseq->len++;
  199.     }
  200. }
  201.  
  202. /*
  203.  *    FIND NEXT NON-BLANK IN PRINTCAP FILE, BUT DON'T READ.
  204.  *    IF EOF, RETURN 1, OTHERWISE RETURN 0.
  205.  */
  206. int
  207. skipspace()
  208. {
  209.     for (;;) {
  210.         switch (c=getc(Pcapfile)) {
  211.         case EOF:
  212.         case 26:    /* decimal for ^Z */
  213.             return (1);
  214.             break;
  215.         case ' ':
  216.         case '\t':
  217.         case 13:    /* decimal for CR */
  218.             break;
  219.         case '\n':
  220.         case 10:    /* decimal for LF */
  221.             lineno++;
  222.             break;
  223.         default:
  224.             ungetc(c,Pcapfile);
  225.             return (0);
  226.         }
  227.     }
  228. }
  229.  
  230. /*
  231.  *    FIND NEXT OCCURRENCE OF CC IN PRINTCAP FILE.
  232.  */
  233. getuntil(cc)
  234. char cc;
  235. {
  236.     while (cc != (c=getc(Pcapfile))) {
  237.         if (c=='\n')  lineno++;
  238.         if (c==EOF)  errout("unexpected end of PRINTCAP file");
  239.     }
  240. }
  241.  
  242. /*
  243.  *    PRINT AN ERROR MESSAGE AND EXIT TO DOS
  244.  */
  245. errout(msg)
  246. char *msg;
  247. {
  248.     fprintf(stderr,"PCroff: %s\n",msg);
  249.     fprintf(stderr,"        Line %d in PRINTCAP file.\n",lineno);
  250.     exit(1);
  251. }
  252.