home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 304_01 / roff51.c < prev    next >
Text File  |  1990-02-14  |  12KB  |  396 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. #include <mem.h>
  12. #include <ctype.h>
  13. #if (VERSION!=2) || (subVERSION!=00)
  14. #error ***************This is version 2.00******************
  15. #endif
  16. /**********************************************************
  17. Advances LIN in LINE over white-space characters.
  18. "^t","^T" are considered tabs, hence white space.
  19. ***********************************************************/
  20. void skip_blanks ( )
  21. {while (*LIN==BLANK||*LIN==TAB||*LIN==NEWLINE
  22.     ||((*LIN=='^')&&(LIN[1]=='t'))
  23.     ||((*LIN=='^')&&(LIN[1]=='T'))
  24.     )
  25.     {if (*LIN=='^') LIN++;
  26.      LIN++;
  27.     }
  28. }
  29. /*************************************************************/
  30. CMD comtyp1(char *line)
  31. {char let1, let2;
  32. let1 = line[0] ;
  33. let2 = line[1] ;
  34.  
  35. if ( let1==COMMAND )    return( DOTDOT );
  36. if ( let1=='{' )    return( LEFT );
  37. if ( let1=='}' )    return( RIGHT );
  38. if ( let1=='i' && let2=='g')    return( IG );
  39. if ( let1=='f' && let2=='i')    return( FI );
  40. if ( let1=='f' && let2=='o')    return( FO );
  41. if ( let1=='t' && let2=='i')    return( TI );
  42. if ( let1=='b' && let2=='p')    return( BP );
  43. if ( let1=='b' && let2=='r')    return( BR );
  44. if ( let1=='c' && let2=='e')    return( CE );
  45. if ( let1=='h' && let2=='e')    return( HE );
  46. if ( let1=='l' && let2=='s')    return( LS );
  47. if ( let1=='n' && let2=='f')    return( NF );
  48. if ( let1=='p' && let2=='l')    return( PL );
  49. if ( let1=='s' && let2=='p')    return( SP );
  50. if ( let1=='s' && let2=='t')    return( ST );
  51. if ( let1=='n' && let2=='e')    return( NE );
  52. if ( let1=='f' && let2=='f')    return( FF );
  53. if ( let1=='s' && let2=='c')    return( SC );
  54. if ( let1=='o' && let2=='h')    return( OH );
  55. if ( let1=='o' && let2=='f')    return( OF );
  56. if ( let1=='e' && let2=='h')    return( EH );
  57. if ( let1=='e' && let2=='f')    return( EF );
  58. if ( let1=='a' && let2=='b')    return( AB );
  59. if ( let1=='t' && let2=='f')    return( TF );
  60. if ( let1=='c' && let2=='f')    return( CF );
  61. if ( let1=='i' && let2=='c')    return( IC );
  62. if ( let1=='o' && let2=='u')    return( OU );
  63. if ( let1=='a' && let2=='d')    return( AD );
  64. if ( let1=='n' && let2=='a')    return( NA );
  65. if ( let1=='f' && let2=='r')    return( FR );
  66. if ( let1=='d' && let2=='e')    return( DE );
  67. if ( let1=='a' && let2=='m')    return( AM );
  68. if ( let1=='d' && let2=='s')    return( DS );
  69. if ( let1=='n' && let2=='r')    return( NR );
  70. if ( let1=='d' && let2=='i')    return( DI );
  71. if ( let1=='d' && let2=='a')    return( DA );
  72. if ( let1=='s' && let2=='o')    return( SO );
  73. if ( let1=='o' && let2=='t')    return( OT );
  74. if ( let1=='t' && let2=='m')    return( TM );
  75. if ( let1=='b' && let2=='j')    return( BJ );
  76. if ( let1=='a' && let2=='f')    return( AF );
  77. if ( let1=='i' && let2=='f')    return( IF );
  78. if ( let1=='i' && let2=='e')    return( IE );
  79. if ( let1=='e' && let2=='l')    return( EL );
  80. if ( let1=='^' && let2=='z')    return( CZ );
  81. if ( let1=='r' && let2=='l')    return( RL );
  82. if ( let1=='e' && let2=='v')    return( EV );
  83. if ( let1=='r' && let2=='m')    return( RM );
  84. if ( let1=='r' && let2=='n')    return( RN );
  85. if ( let1=='p' && let2=='m')    return( PM );
  86. if ( let1=='p' && let2=='m')    return( PM );
  87. if ( let1=='m' && let2=='c')    return( MC );
  88. if ( let1=='n' && let2=='m')    return( NM );
  89. if ( let1=='n' && let2=='n')    return( NN );
  90. if ( let1=='p' && let2=='c')    return( PC );
  91. if ( let1=='l' && let2=='c')    return( LC );
  92. if ( let1=='t' && let2=='c')    return( TC );
  93. if ( let1=='p' && let2=='o')    return( PO );
  94. if ( let1=='w' && let2=='h')    return( WH );
  95. if ( let1=='c' && let2=='h')    return( CH );
  96. if ( let1=='i' && let2=='t')    return( IT );
  97. if ( let1=='e' && let2=='m')    return( EM );
  98. if ( let1=='d' && let2=='t')    return( DT );
  99. if ( let1=='t' && let2=='l')    return( TL );
  100. if ( let1=='g' && let2=='o')    return( GO );
  101.  
  102. if ( let1=='m')
  103.       { if (let2=='1')        return( M1 );
  104.     if (let2=='2')        return( M2 );
  105.     if (let2=='3')        return( M3 );
  106.     if (let2=='4')        return( M4 );
  107.       }
  108. return( UNKNOWN );        /* no match */
  109. }
  110. /*************************************************************
  111.  sets a global parameter like SPVAL, PAGESTOP, etc.
  112.  Also checks that the new value is within the range of that 
  113.  parameter.  Assigns the default for that parameter if no value
  114.   is specified.
  115. *************************************************************/
  116. void set ( int *param, int val, char arg_typ,
  117.         int defval, int minval, int maxval )
  118. {if(val==NO_VAL) *param = defval;    /* defaulted */
  119. else if(arg_typ == '+') *param += val;    /* relative + */
  120. else if(arg_typ == '-')    *param -= val;    /* relative - */
  121. else    *param = val;            /* absolute */
  122. *param = min (*param,maxval);
  123. *param = max (*param, minval);
  124. }
  125. /*************************************************************
  126.     end current filled line
  127. **************************************************************/
  128. void Brk()
  129. {int l;
  130. if (OUTPOS) put(OUTBUF);
  131. OUTW=OUTPOS=OUTTOP=OUTBOT=OUTWRDS = 0;
  132. OUTBUF[0] = '\0';
  133. }
  134.  
  135. /**************************************************/
  136. void initxu()    /*initialize underline,overstrike variables*/
  137. {    XCOL=UCOL=-1;
  138.     setmem(&XBUF,LSZ,' ');
  139.     setmem(&UBUF,LSZ,' ');
  140. }
  141. /****************************************/
  142. /*test for n line of space before footer*/
  143. /****************************************/
  144. void need(int n)
  145. {if(DIVERTING)
  146.     {if(((DLINES<(Dstats->dt)) && ((DLINES+n)>=(Dstats->dt))))
  147.         {Brk();
  148.          space((Dstats->dt)-DLINES);
  149.          return;
  150.         }
  151.     }
  152.  else if (( VLINENO>=(TRAPLOC-n) ) && (TRAPLOC>=VLINENO) )
  153.         {Brk();
  154.          space(HUGE);
  155.          NEWPAG= ++CURPAG;
  156.         }
  157. }
  158. /****************************************/
  159. int min(int i,int j) {return( (i<j)?i:j);}
  160.  
  161. int max(int i, int j) {return( (i>j)?i:j);}
  162. /*******************************************/
  163. /* process() parses args from LIN in LINE[]*/
  164. /* into entries of the arglist a for macro */
  165. /* processing by dolns(); returns # args.  */
  166. /*******************************************/
  167. int process(ARGs *a)
  168. {int i;
  169. char *pc, c;
  170. strcpy(a->tokens,LIN);
  171. pc=a->tokens;
  172. for(i=0;i<ARGLIM;i++)
  173.     {c=*pc;    /*skip whitespace*/
  174.      while((c==' ')||(c=='\t')||(c=='\n')) c=*(++pc);
  175.      if (c=='\0') a->arg[i]=NULL;
  176.      else if (c=='\"')    /*quoted string*/
  177.         {a->arg[i] = ++pc;
  178.          c=*pc;
  179.          while((c!='\0')&&(c!='\n')&&(c!='\"')) c=*(++pc);
  180.          if (c!='\0') *(pc++)='\0';    /*mark end*/
  181.         }
  182.      else    {a->arg[i]=pc;    /*simple token*/
  183.          while((c!='\0')&&(c!=' ')&&(c!='\t')&&(c!='\n'))
  184.             c = *(++pc);
  185.          if (c!='\0') *(pc++)='\0';    /*mark end*/
  186.         }
  187.     }
  188. for (i=1;(a->arg[i])&&(i<ARGLIM);i++);
  189. i--;
  190. a->dollar = i;
  191. return (i) ;
  192. }
  193. /************************************/
  194. /* pbmac() is more generalized than */
  195. /* pbstr() in that it will expand   */
  196. /* "$n" and "$" found in macro      */
  197. /* expansion string m from a        */
  198. /************************************/
  199. void pbmac(char *m, ARGs a)
  200. {int i;
  201. char c, c2;
  202. if ((i=strlen(m))==0) return;
  203. c = m[--i];
  204. if (c=='$') putback('0'+a.dollar);
  205. else putback(c);
  206. while (i>0)
  207.     {c=m[--i];
  208.      if (c=='$')
  209.         {c = BACKBUF[BINP--];
  210.          if ((c>'0')&&(c<='9')) pbstr(a.arg[c-'0']);
  211.          else    {putback(c); putback('0'+a.dollar);}
  212.         }
  213.      else putback(c);
  214.     }
  215. }
  216. /**************************************/
  217. #include "\turboc\include\setjmp.h"
  218. #define TOKSIZ LSZ
  219. jmp_buf jumper;
  220. char *xptr,*saveptr;
  221. /*****************************************************/
  222. /* get_val2() is more general than the old get_val() */
  223. /* in that it can do arithmetic and a greater range  */
  224. /* of typ (any nonwhite character); and it now       */
  225. /* indicates where on line it has finished parsing.  */
  226. /*****************************************************/
  227. int get_val2(char *line, char *typ, char **end)
  228. {char c; int val;
  229.  saveptr=xptr=line; c=*xptr;
  230.  while ((c!=' ')&&(c!='\t')&&(c!='\n')) c=*(++xptr); /*skip command*/
  231.  while ((c==' ')||(c=='\t')||(c=='\n')) c=*(++xptr); /*skip white*/
  232.  *typ=c;
  233.  if ((c=='+')||(c=='-')||(c=='!')) c=*(++xptr);
  234.  while ((c==' ')||(c=='\t')||(c=='\n')) c=*(++xptr); /*skip white*/
  235.  if ((c=='\0')||(c=='\r')||(c==';'))
  236.     {*end=xptr;
  237.      return (NO_VAL);
  238.     }
  239.  val=expr();
  240.  *end=xptr;
  241.  return ( val );
  242. }
  243. /****************************************************/
  244. /* setnxtval can do arithmetic and a greater range  */
  245. /* of typ (any nonwhite character); and it updates  */
  246. /*  line to where on line it has finished parsing.  */
  247. /****************************************************/
  248. void setnxtval(char **line,int *param,int deflt,int minparam,int maxparam)
  249. {char c,typ; int val;
  250.  saveptr=xptr=*line; c=*xptr;
  251.  if(!c) return;
  252.  while ((c!=' ')&&(c!='\t')&&(c!='\n')) c=*(++xptr); /*skip command*/
  253.  while ((c==' ')||(c=='\t')&&(c=='\n')) c=*(++xptr); /*skip white*/
  254.  typ=c;
  255.  if ((c=='+')||(c=='-')||(c=='!')) c=*(++xptr);
  256.  while ((c==' ')||(c=='\t')||(c=='\n')) c=*(++xptr); /*skip white*/
  257.  if ((c=='\0')||(c=='\r')||(c==';'))
  258.     {*line=xptr;
  259.      return;
  260.     }
  261.  val=expr();
  262.  *line=xptr;
  263.  set(param,val,typ,deflt,minparam,maxparam);
  264. }
  265. int expr()
  266. {if (setjmp(jumper)!=0)
  267.     {fprintf(stderr,"Ignoring expression (with error):\n");
  268.      amat();
  269.      return(NO_VAL);
  270.     }
  271.  return (expr0());
  272. }
  273.  
  274. int expr0()
  275. {int i,j;
  276.  char c;
  277.  j=expr1();
  278.  c=*xptr;
  279.  if (c=='>')
  280.      {c=*(++xptr);
  281.       if (c=='=') {xptr++; if (j>=expr1()) return(TRUE);else return(0);}
  282.       else {if (j>expr1()) return(TRUE);else return(0);}
  283.      }
  284.  else if (c=='<')
  285.      {c=*(++xptr);
  286.       if (c=='=') {xptr++; if (j<=expr1()) return(TRUE);else return(0);}
  287.       else if (c=='>') {xptr++; if (j!=expr1()) return(TRUE);else return(0);}
  288.       else {if (j<expr1()) return(TRUE);else return(0);}
  289.      }
  290.  else if (c=='&') {xptr++; if (j & expr1()) return(TRUE);else return(0);}
  291.  else if (c==':') {xptr++; if (j | expr1()) return(TRUE);else return(0);}
  292.  else if (c=='=') {xptr++; if (j == expr1()) return(TRUE);else return(0);}
  293.  else return(j);
  294. }
  295. int expr1()
  296. {int i;
  297.  if (*xptr=='-')
  298.      {xptr++;
  299.       i = -expr2();
  300.      }
  301.  else if (*xptr=='+')
  302.      {xptr++;
  303.       i = expr2();
  304.      }
  305.  else i = expr2();
  306.  /* now have taken care of optional unary operator and first term */
  307.  /* now for any possible additional terms: */
  308.  while ((*xptr=='-')||(*xptr=='+'))
  309.      {if (*xptr=='-')
  310.          {xptr++; i -= expr2();
  311.          }
  312.       if (*xptr=='+')
  313.          {xptr++; i += expr2();
  314.          }
  315.     }
  316.  return (i);
  317. }
  318. int expr2()
  319. {int val;
  320.  val = expr3();
  321.  /* first factor done; process optionally more: */
  322.  while((*xptr=='*')||(*xptr=='/')||(*xptr=='%'))
  323.      { if (*xptr=='*')
  324.          {xptr++; val *= expr3();
  325.          }
  326.           if (*xptr=='/')
  327.               {xptr++; val = val/expr3();
  328.               }
  329.           if (*xptr=='%')
  330.               {xptr++; val = val % expr3();
  331.               }
  332.     }
  333.  return (val);
  334. }
  335. int expr3()
  336. {int val;
  337.  if (isdigit(*xptr))
  338.      {val=0;
  339.       while (isdigit(*xptr))
  340.          {val=10*val + (*xptr - '0');
  341.           xptr++;
  342.          }
  343.      return(val);
  344.      }
  345.  else if (*xptr=='(')
  346.      {xptr++;
  347.       val = expr0();
  348.       /* amat(); showstk(); */
  349.       if(*xptr==')') xptr++;
  350.       else    longjmp(jumper,1); /*error return*/
  351.      return (val);
  352.     }
  353.  else if((*xptr=='\'')||(*xptr=='"'))
  354.     {char tbuf1[TOKSIZ],tbuf2[TOKSIZ],*ptr1,*ptr2,term;
  355.      term=*xptr++;
  356.      ptr1=xptr;
  357.      ptr2=tbuf1;
  358.      while(*ptr1 && (*ptr1!=term)) *(ptr2++)=*(ptr1++);
  359.      *ptr2='\0';
  360.      if(*ptr1) ptr1++;
  361.      ptr2=tbuf2;
  362.      while(*ptr1 && (*ptr1!=term)) *(ptr2++)=*(ptr1++);
  363.      *ptr2='\0';
  364.      if(*ptr1) ptr1++;
  365.      xptr=ptr1;
  366.      if(strcmp(tbuf1,tbuf2)) return(FALSE);
  367.      else return(TRUE);
  368.     }
  369.  else    {char tbuf[TOKSIZ],c, *ptr1, *ptr2; int *pw;
  370.      ptr1=xptr;
  371.      ptr2=tbuf;
  372.      while (isalnum(*ptr1)||(*ptr1=='#')) *(ptr2++)=*(ptr1++);
  373.      *ptr2='\0';
  374.      if ((tbuf[0]=='#')&&(tbuf[1]=='\0'))
  375.         {xptr= ptr1;
  376.          return(CURPAG);
  377.         }
  378.     else if (NULL!=(pw=(int *)find2(tbuf,&RLINK)))
  379.         {xptr = ptr1;
  380.          return (*pw);
  381.         }
  382.     }
  383.  longjmp(jumper,1); /*error return*/
  384. return(val);/*never reach here but eliminates compiler warning*/
  385. }
  386. void amat()
  387. {char *pc;
  388.  fprintf(stderr,"%s\n",saveptr);
  389.  pc=saveptr;
  390.  while (pc<xptr)
  391.      {printf(" ");
  392.       pc++;
  393.      }
  394.  fprintf(stderr,"^\n");
  395. }
  396.