home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 304_01 / roff58.c < prev    next >
Text File  |  1990-02-14  |  13KB  |  490 lines

  1. /********************************************************/
  2. /*         ROFF5, Version 2.00            */
  3. /*    (c) 1983,4,8,9 by Ernest E. Bergmann        */
  4. /*    730 Seneca Street, Bethlehem, Pa. 18015        */
  5. /*                            */
  6. /* Permission is hereby granted for all commercial and    */
  7. /* non-commercial reproduction and distribution of this    */
  8. /* material provided this notice is included.        */
  9. /********************************************************/
  10. #include <roff5.h>
  11. #if (VERSION!=2) || (subVERSION!=00)
  12. #error ***************This is version 2.00******************
  13. #endif
  14. /********************************************************/
  15. char *fgets3()
  16. {    int count,c,i,*pw;
  17.     char *cptr,*pc, *pc2;
  18.     ENTRY *pe;
  19.     char wbuf[LSZ],*fnd;
  20.     count = MAXLINE;
  21.     cptr = &LINE[0];
  22.     if ( (c=ngetc(ifp))==EOF) return (LIN=NULL);
  23.     do {    if(c==ICVAL[0])/*need macro substitution*/
  24.           {for(i=0;ICVAL[0]!=(wbuf[i]=ngetc(ifp));i++)
  25.             {if(wbuf[i]=='\n')
  26.                 {if(i) putback('\n');
  27.                 break;
  28.                 }
  29.             }
  30.           if(i)
  31.            {wbuf[i]='\0';
  32.             if (*wbuf=='\"')    /*comment rest of line*/
  33.             {*cptr='\n';
  34.              *(++cptr)='\0';
  35.              do c=ngetc(ifp);
  36.              while((c!='\n')&&(c!=EOF));
  37.              return( LIN=LINE );
  38.             }
  39.             else if(readonly(wbuf)) ; /* handled as predefined */
  40.             else if(NULL!=(pw=(int *)find2(wbuf,&RLINK)))/*register?*/
  41.             {itoC(*pw,wbuf,*(FORMAT *)(pw+1));
  42.             pbstr(wbuf);
  43.             }
  44.             else if(NULL!=(fnd=find2(wbuf,&SLINK))) pbstr(fnd);
  45.             else{
  46.             char buff[128];
  47.             unsigned siz;
  48.             ENTRY *where;
  49.  
  50.                 pc=wbuf;
  51.             pe=(ENTRY *)buff;
  52.             pe->link=SLINK.link;
  53.             pc2=(char *)&(pe->ident);
  54.             transfer(&pc,&pc2,'\0');
  55.             fprintf(stderr,"%cPlease define <%s>:",
  56.                         BELL,wbuf);
  57.             gets(wbuf);
  58.             pc=wbuf;
  59.             transfer(&pc,&pc2,'\0');
  60.             siz = pc2 - buff;
  61.             if (NULL==(where=(ENTRY *)malloc(siz)))
  62.                 exitm("fgets3(): cannot malloc\n");
  63.             SLINK.link = (ENTRY *)memcpy(where,buff,siz);
  64.             pbstr(wbuf);
  65.             }
  66.             continue;
  67.             }
  68.            else if(*wbuf!='\n') putback(ICVAL[0]);
  69.            c=ngetc(ifp);
  70.           }
  71.         if ((*cptr++ = c) == '\n') break;
  72.  
  73.      } while (count--&&(c=ngetc(ifp))!=EOF);
  74.        *cptr = '\0';
  75.     return (LIN=LINE);
  76. }
  77. /**************************************************************
  78. performs the formatting command returned by comtyp1 -sets global
  79.   variables ( indenting, underlining, etc. )
  80. "line" starts just after the ".".
  81. **************************************************************/
  82. void comand()
  83. {CMD c_type;    /* command type  */
  84. int arg_val;    /* argument value, if any */
  85. char arg_typ;    /* relative (+ or -) or absolute or conditional? */
  86. char wbuf[LSZ], *lptr;
  87. int i;
  88. c_type = comtyp1(LIN);
  89. switch (c_type)
  90.     {case UNKNOWN :
  91.         fprintf(stderr, "UNKNOWN COMMAND: <%s>\n", LINE);
  92.         return;
  93.     case DOTDOT : break;/* ignore remark */
  94.     case IG : ignore(); break;
  95.  
  96.     case FI :    /* filled lines  */
  97.         Brk();
  98.         FILL = YES;
  99.         break;
  100.     case NF :    /* non-filled lines */
  101.         Brk();
  102.         FILL = NO;
  103.         break;
  104.     case NA :    /* Not Adjust lines */
  105.         JUSTIFY = NO;
  106.         break;
  107.     case AD :    /* ADjust lines  */
  108.         adjust();
  109.         break;
  110.     case BR :    /* just cause a break */
  111.         Brk();
  112.         break;
  113.     case LS :    /* set line spacing value */
  114.         arg_val = get_val2(LIN, &arg_typ, &lptr );
  115.         setS(LSVAL, arg_val, arg_typ, LS_DEF, 1, HUGE );
  116.         break;
  117.     case TI :    /* set temporary left indent */
  118.         Brk();
  119.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  120.         set ( &TIVAL, arg_val, arg_typ, TI_DEF, 0, RMVAL );
  121.         break;
  122.     case M1:    /* set topmost margin */
  123.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  124.         setS( M1VAL, arg_val, arg_typ, M1_DEF,0,HUGE);
  125.         break;
  126.     case M2:    /* set second top margin */
  127.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  128.         setS( M2VAL, arg_val, arg_typ, M2_DEF,0,HUGE);
  129.         break;
  130.     case M3:    /* set first bottom margin */
  131.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  132.         setS( M3VAL, arg_val, arg_typ, M3_DEF,0,HUGE);
  133.         setTRAP();
  134.         break;
  135.     case M4:    /* set bottom-most margin */
  136.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  137.         setS(M4VAL, arg_val, arg_typ, M4_DEF,0,HUGE);
  138.         setTRAP();
  139.         break;
  140.     case CE :    /* center next arg_val lines */
  141.         Brk();
  142.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  143.         set ( &CEVAL, arg_val, arg_typ,CE_DEF,0, HUGE);
  144.         break;
  145.     case HE :    /* get header title for pages */
  146.         gettl3 ( LIN, EHEAD, &EH2, &EH3 );
  147.         gettl3 ( LIN, OHEAD, &OH2, &OH3 );
  148.         break;
  149.     case OH :    /*get odd header title*/
  150.         gettl3 ( LIN, OHEAD, &OH2, &OH3 );
  151.         break;
  152.     case EH :    /*get even header title*/
  153.         gettl3 ( LIN, EHEAD, &EH2, &EH3 );
  154.         break;
  155.     case FO :    /* get footer title for pages */
  156.         gettl3 ( LIN, EFOOT, &EF2, &EF3 );
  157.         gettl3 ( LIN, OFOOT, &OF2, &OF3 );
  158.         break;
  159.     case OF :    /* get odd page footer title*/
  160.         gettl3 ( LIN, OFOOT, &OF2, &OF3 );
  161.         break;
  162.     case EF :    /* get even page footer title*/
  163.         gettl3 ( LIN, EFOOT, &EF2, &EF3 );
  164.         break;
  165.     case SP :    /* space down arg_val blank lines */
  166.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  167.         set (&SPVAL, arg_val, arg_typ, 1, 0, HUGE);
  168.         *(--LIN)='\0';
  169.         space ( SPVAL );
  170.         break;
  171.     case GO :    /*advance printer to absolute location*/
  172.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  173.         if (arg_val>=VLINENO) break; /*already there*/
  174.         set (&SPVAL, arg_val, arg_typ, 1, 0, HUGE);
  175.         if ((SPVAL>PLINENO)&&!DIVERTING)
  176.         if (PLINENO) space ( SPVAL - VLINENO );
  177.         else space(SPVAL-M1VAL[0]-M2VAL[0]);
  178.         break;
  179.  
  180.     case ST :    /* stop(pause) at each page?*/
  181.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  182.         set(&PAGESTOP,arg_val,'0',YES,NO,YES);
  183.         break;
  184.     case BP :    /* set pageno arg_val - begin page */
  185.         Brk();
  186.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  187.         if(((VLINENO<=0)||(VLINENO>=FOOTLOC))&&
  188.             (arg_val==NO_VAL)) break;
  189.         if ( VLINENO > 0 )    space (HUGE);
  190.         set(&CURPAG,arg_val,arg_typ,CURPAG+1,0,9999);
  191.         NEWPAG = CURPAG;
  192.         break;
  193.     case NE :    /*"need"*/
  194.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  195.         if (arg_val==NO_VAL) arg_val=2;/*default*/
  196.         need(arg_val);
  197.         break;
  198.     case PL :    /* set page length */
  199.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  200.         setS(PLVAL, arg_val, arg_typ, PL_DEF,
  201.           M1VAL[0]+M2VAL[0]+M3VAL[0]+M4VAL[0]+1,HUGE);
  202.         setTRAP();
  203.         break;
  204.     case FF :    /*formfeed*/
  205.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  206.         set(&FFEED,arg_val,'0',FF_DEF,NO,YES);
  207.         break;
  208.     case SC :    /*space character*/
  209.         setchar(SCVAL,TRUE,SC_INI,BLANK,127);
  210.         break;
  211.     case AB :    /*abort*/
  212.         gwLIN(wbuf);    /*skip command*/
  213.         skip_blanks();
  214.         trunc_bl(LIN);
  215.         if(strlen(LIN)) fprintf(stderr,"\n%s\n",LIN);
  216.         else fprintf(stderr,"\n***USER ABORT***\n");
  217.         exit();
  218.     case TF :    /*translate flag */
  219.         setchar(TFVAL,TRUE,TF_DEF,BLANK+1,127);
  220.         break;
  221.     case CF :    /*character flag*/
  222.         setchar(CFVAL,TRUE,CF_DEF,BLANK+1,127);
  223.         break;
  224.     case IC :    /*insert character for macro replace*/
  225.         setchar(ICVAL,TRUE,IC_DEF,BLANK+1,127);
  226.         break;
  227.     case OU :    /*output code string*/
  228.         ocode(); break;
  229.     case FR :    /*define fractional or whole line spacing code*/
  230.         getfr(); break;
  231.     case WH : when();
  232.          setTRAP();
  233.          break;
  234.     case CH : changetrap();
  235.          setTRAP();
  236.          break;
  237.     case IT : itset();
  238.          break;
  239.     case EM : EMset();
  240.          break;
  241.     case DT : dtset();
  242.          break;
  243.     case TL :title3(LIN,CURPAG,PAGFMT); break;
  244.     case DS :    /*define string*/
  245.         insert(); break;
  246.     case DE :    /*define macro*/
  247.     case AM :    /*append macro*/
  248.         mappend(c_type);
  249.         break;
  250.     case NR :    /*number register */
  251.         dovar(); break;
  252.     case DI :    /*diversion to file*/
  253.     case DA :
  254.         dappend(c_type);
  255.         break;
  256.     case SO :    /*source from file*/
  257.         source(); break;
  258.     case OT :    /*Output Transaltion*/
  259.         getot(); break;
  260.     case TM :    /*msg to terminal*/
  261.         gwLIN(wbuf);    /*skip command*/
  262.         skip_blanks();
  263.         trunc_bl(LIN);
  264.         fprintf(stderr,"<%s>\n",LIN);
  265.         break;
  266.     case BJ :    /*break with right justification*/
  267.         if(FILL)/*not applicable otherwise*/
  268.         {spread(OUTBUF,
  269.             min(RMVAL-TIVAL,MAXLINE-1)-OUTW+1,
  270.             OUTWRDS);
  271.         Brk();
  272.         }
  273.         break;
  274.     case AF :    /*assign format to register variable*/
  275.         assignfmt();
  276.         break;
  277.     case CZ :    /*substitute ^Z character in decimal*/
  278.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  279.         set(&CZSUB,arg_val,'0',(int)CZSUB_DEF,0,255);
  280.         break;
  281.     case RL :    /* Ruler Line similar to Wordstar for tabs*/
  282.         gwLIN(wbuf);    /*skip command*/
  283.         skip_blanks();
  284.         trunc_bl(LIN);
  285.         if(LIN[0]=='?') {TIVAL=0; put(RULER); return;}
  286.         else if (LIN[0]=='L') gwLIN(wbuf);
  287.         else if (LIN[0]=='\"') strcpy(wbuf,strtok(LIN,"\""));
  288.         else    {redoRR();
  289.               TIVAL=INVAL;
  290.              return;
  291.             }
  292.         if (verifyRR(wbuf)==FALSE)
  293.             fprintf(stderr,"Bad RULER; request ignored.\n");
  294.         TIVAL=INVAL;
  295.         break;
  296.     case EV :    /* change enviroment */
  297.         {int temp;
  298.         temp=EVVAL[0];
  299.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  300.         setS(EVVAL,arg_val,arg_typ,EV_INI,0,NUMENV-1);
  301.         if (temp!=EVVAL[0]) chgenv(temp,EVVAL[0]);
  302.         break;
  303.         }
  304.     case RM :    /* remove definition */
  305.         rmdef();
  306.         break;
  307.     case RN :    /* rename definition */
  308.         rndef();
  309.         break;
  310.     case PM : showm(get_val2(LIN,&arg_typ,&lptr));
  311.     /*print list of macros*/
  312.           break;
  313.     case MC : exitm(".mc not implemented yet!\n");
  314.     case NM : NNVAL = 0;
  315.           arg_val=get_val2(LIN,&arg_typ,&lptr);
  316.           if(arg_val==NO_VAL) NUMBERING=FALSE;
  317.           else    {NUMBERING=TRUE;
  318.              set(&LN,arg_val,arg_typ,1,1,HUGE);
  319.              setnxtval(&lptr,&LNMOD,1,1,HUGE);
  320.              setnxtval(&lptr,&LNST,1,0,HUGE);
  321.              setnxtval(&lptr,&LNI,0,0,HUGE);
  322.             }
  323.           break;
  324.     case NN : arg_val = get_val2( LIN, &arg_typ, &lptr );
  325.           set(&NNVAL,arg_val,arg_typ,1,1,HUGE);
  326.           break;
  327.     case PC : exitm(".pc not implemented yet!\n");
  328.     case PO : arg_val = get_val2(LIN,&arg_typ,&lptr);
  329.           set(&dotO,arg_val,arg_typ,0,0,70);
  330.           break;
  331.     case LC :    /*Leader Expansion Character*/
  332.         setchar(&LCVAL,FALSE,BLANK,BLANK,127);
  333.         break;
  334.     case TC :    /*Tab expansion Character*/
  335.         setchar(&TCVAL,FALSE,BLANK,BLANK,127);
  336.         break;
  337.     case IE :
  338.     case EL :
  339.     case RIGHT :
  340.     case LEFT :
  341.     case IF :    /* unexpected since filtered by action */
  342.         conderr("conditional by command()");
  343.         break;
  344.       }
  345. }
  346. /*********************************************/
  347. void dolns()
  348. {LIN=LINE;
  349.  while(LIN || FPTR)
  350.    {if(LIN) action();
  351.     else endso();
  352.     if(LIN[0]==COMMAND)
  353.       {if(LIN[1]=='}') conderr(".}");
  354.        else if((LIN[1]=='e')&&(LIN[2]=='l')) conderr(".el");
  355.       }
  356.    }
  357. }
  358. /*******************/
  359. void action()
  360. {if(LIN)    /*not EOF*/
  361.   {if(!(*LIN)) fgets3();
  362.    if(!LIN) return;    /*EOF*/
  363.    if(*LIN != COMMAND) {text(); LIN=LINE; LINE[0]='\0';}
  364.    else{CMD c_type;
  365.     int arg_val;
  366.     char arg_typ, *lptr;
  367.     LIN++;
  368.     c_type=comtyp1(LIN);
  369.     if(c_type<UNKNOWN)    /*conditional grammar*/
  370.       switch(c_type)
  371.        {case IF :    /*"if" conditional*/
  372.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  373.         if (arg_val==NO_VAL) arg_val=FALSE;
  374.         else if (arg_typ=='!') arg_val= !arg_val;
  375.         LIN = lptr;
  376.         while((*LIN==' ')||(*LIN=='\t')||(*LIN=='\n')) LIN++;
  377.         if(arg_val) action();
  378.         else inaction();
  379.         break;
  380.         case IE :    /*"if-else" conditional*/
  381.         arg_val = get_val2( LIN, &arg_typ, &lptr );
  382.         if (arg_val==NO_VAL) arg_val=FALSE;
  383.         else if (arg_typ=='!') arg_val= !arg_val;
  384.         LIN = lptr;
  385.         while((*LIN==' ')||(*LIN=='\t')||(*LIN=='\n')) LIN++;
  386.         if(arg_val)
  387.             {action();
  388.              act2(FALSE);
  389.             }
  390.         else    {inaction();
  391.              act2(TRUE);
  392.             }
  393.         break;
  394.         case LEFT: /*.{ encountered */
  395.         {char dummy[LSZ];
  396.          gwLIN(dummy);
  397.          skip_blanks();
  398.          while ((LIN[0]!='.')||(LIN[1]!='}'))
  399.             {if(!LIN) {conderr("EOF"); return;}
  400.              action();
  401.             }
  402.          gwLIN(dummy);
  403.          skip_blanks();
  404.         } break;
  405.         case RIGHT: LIN--; break;
  406.         case EL:    LIN--; break;
  407.        }
  408.     else
  409.        {char *pc;
  410.         pc=macq1(LIN);
  411.         if(pc)  {ARGs a;
  412.              process(&a);
  413.              pbmac(pc,a);
  414.             }
  415.         else comand();
  416.         LIN=LINE;
  417.         LINE[0]='\0';
  418.        }
  419.        }
  420.   }
  421. }
  422. void inaction()
  423. {if(LIN)    /*not EOF*/
  424.   {if(!(*LIN)) fgets3();
  425.    if(!LIN) return;    /*EOF*/
  426.    if(*LIN != COMMAND) { /*text()*/ LIN=LINE; LINE[0]='\0';}
  427.    else{CMD c_type;
  428.     char arg_typ, *lptr;
  429.     LIN++;
  430.     c_type=comtyp1(LIN);
  431.     if(c_type<UNKNOWN)    /*conditional grammar*/
  432.     switch(c_type)
  433.        {case IF :    /*"if" conditional*/
  434.         get_val2( LIN, &arg_typ, &lptr );
  435.         LIN = lptr;
  436.         while((*LIN==' ')||(*LIN=='\t')||(*LIN=='\n')) LIN++;
  437.         inaction();
  438.         break;
  439.         case IE :    /*"if-else" conditional*/
  440.         get_val2( LIN, &arg_typ, &lptr );
  441.         LIN = lptr;
  442.         while((*LIN==' ')||(*LIN=='\t')||(*LIN=='\n')) LIN++;
  443.         inaction();
  444.         act2(FALSE);
  445.         break;
  446.         case LEFT: /*.{ encountered */
  447.         {char dummy[LSZ];
  448.          gwLIN(dummy);
  449.          skip_blanks();
  450.          while ((LIN[0]!='.')||(LIN[1]!='}'))
  451.             {if(!LIN) {conderr("EOF"); return;}
  452.              inaction();
  453.             }
  454.          gwLIN(dummy);
  455.          skip_blanks();
  456.         } break;
  457.         case RIGHT: LIN--; break;
  458.         case EL:    LIN--; break;
  459.        }
  460.     else
  461.        {LIN=LINE;
  462.         LINE[0]='\0';
  463.        }
  464.        }
  465.   }
  466. }
  467. int act2(int act) /*returns true if no error; act for .el action*/
  468. {char dummy[LSZ];
  469.  if(!LIN[0]) fgets3();
  470.  if(!LIN)
  471.     {fprintf(stderr,"Unexpected EOF encountered\n");
  472.      return(FALSE);
  473.     }
  474.  if((LIN[0]==COMMAND)&&(LIN[1]=='e')&&(LIN[2]=='l')) /*ok*/
  475.     {gwLIN(dummy);
  476.      skip_blanks();
  477.      if(act) action();
  478.      else inaction();
  479.      return(TRUE);
  480.     }
  481.  else return(FALSE);
  482. }
  483. void conderr(char *err)/*non-fatal error reporting for conditional grammar*/
  484. {if(LIN) fprintf(stderr,"Unexpected %s encountered;",err);
  485.  else {fprintf(stderr, "Unexpected EOF encountered.\n"); return;}
  486.  fprintf(stderr,"  ignoring <%s>.\n",(char *)LIN);
  487.  LIN=LINE;
  488.  LINE[0]='\0';
  489. }
  490.