home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 304_01 / roff56.c < prev    next >
Text File  |  1990-02-14  |  10KB  |  365 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. int value(base,string)    /*unsigned conversion*/
  16. int base;        /*radix for conversion*/
  17. char *string;        /*no leading blanks please!*/
  18.             /*trailing whitespace or '\0'*/
  19. {int val,d;
  20. char c;
  21.     val=0;
  22.     for(d=digit(*string);d>=0 && d<base ; d=digit(*string))
  23.         {val = val*base + d;
  24.         string++;
  25.         }
  26.     c=*string;
  27.     if(!c || c==' ' || c==TAB || c=='\n') return(val);
  28.     else return(-1);    /*error return is -1*/
  29. }
  30. /**************************************************/
  31. int digit(d)
  32. char d;
  33. {    d=toupper(d);
  34.     if(d<='9') return(d-'0');
  35.     if(d<'A') return(-1); /*error return is negative val*/
  36.     if(d<='Z') return(10-'A'+d);
  37.     return(-1);    /*error*/
  38. }
  39. /**************************************************/
  40. int strln4(s,word,num,fmt)
  41.  /*returns printed string length; checks legality of
  42.         word function;keeps track of vertical
  43.         excursions; records them in globals*/
  44. char *s;
  45. int word;    /* boolean, if true, check is made for none
  46.         black characters in the string*/
  47. int num;    /* for expansion of NUMSIGN;set negative to ignore*/
  48. FORMAT fmt;    /* format for NUMSIGN */
  49. {int i,i2,p1,p2,p3;
  50. int t,b,h;    /*vertical vars*/
  51. char c, *ss;
  52. ss=s;
  53. t=b=h=0;
  54. p3=p2=p1=-LSZ;
  55. for(c=*s,i2=i=0;c;c=*(++s))
  56.     {if(c==NUMSIGN)
  57.         if (num<0) i++;
  58.         else
  59.         {char temp[LSZ];
  60.          i += itoC(num, temp, fmt);
  61.         }
  62.     else if((c!=TFVAL[0])&&(c!=CFVAL[0]))
  63.         {if((c<=' ')&&(word)) goto error;
  64.         else i++;
  65.         }
  66.     else if(c==CFVAL[0])
  67.         {c=*(++s);
  68.         if(c==TFVAL[0]) goto error;/*both CFVAL,TFVAL*/
  69.         switch(c)
  70.         {case 'h':
  71.         case 'H':if(i>i2) i2=i;
  72.              if(i) i--;
  73.             else goto error;/*before start*/
  74.             break;
  75.         case '+': h--; if(h<t) t=h; break;
  76.         case '-': h++; if(h>b) b=h; break;
  77.         case 'B':
  78.         case 'b':
  79.         case 'D':
  80.         case 'd':
  81.         case 'u':
  82.         case 'U':
  83.         case 'X':
  84.         case 'x': break;
  85.         case '(': p1=i; break;
  86.         case '[': p2=i; break;
  87.         case '{': p3=i; break;
  88.         case ')': if(i>i2) i2=i; i=p1; break;
  89.         case ']': if(i>i2) i2=i; i=p2; break;
  90.         case '}': if(i>i2) i2=i; i=p3; break;
  91.         default: if(CPTR[c-' ']) break;
  92.         goto error;    /*undecipherable*/
  93.         }}
  94.     else/*c==TFVAL[0]*/
  95.         {if(class(*(s+1))!=BLACK)
  96.         goto error;    /*illegal translation*/
  97.         }
  98.     }
  99. if(h) goto error;
  100. if(word){WTOP=t;
  101.     WBOT=b;
  102.     }
  103. else    {LTOP=t;
  104.     LBOT=b;
  105.     }
  106. if(i>=i2)return(i);
  107. /* else prints beyond last character: */
  108. error:
  109.     /*should be fprint -> stderr*/
  110.     fprintf(stderr,"STRLN4:<%s> is illegally formed\n",
  111.                 ss);
  112.     return(strlen(ss));
  113. }
  114. /* A properly formed token string has its first printable
  115. character indicating the lefthand edge and the last printable
  116. character at the right hand edge.  Only legal control pairs
  117. accepted.  It must consist of printable symbols. */
  118. /************************************
  119. set stack like set() sets a variable
  120. *************************************/
  121. void setS(param,val,arg_typ,defval,minval,maxval)
  122. int param[STKSIZ+1],val,defval,minval,maxval;
  123. char arg_typ;
  124. {int i;
  125.     if(val==NO_VAL)
  126.         {for(i=0;i<STKSIZ;i++)    /*pop*/
  127.         param[i]=param[i+1];
  128.         param[STKSIZ]=defval;
  129.         }
  130.     else    {for(i=STKSIZ;i;i--)    /*push*/
  131.         param[i]=param[i-1];
  132.         if (arg_typ=='+') *param+=val;
  133.         else if (arg_typ=='-') *param-=val;
  134.         else *param=val;
  135.         }
  136.     *param=min(max(*param,minval),maxval);
  137. }
  138. /******************************************
  139. initialize stack type variable, st, with v
  140. *******************************************/
  141. void initsk(int st[STKSIZ+1],int v)
  142. {int i;
  143.     for(i=STKSIZ+1;i;st[--i]=v);
  144. }
  145. /*********************************************
  146. sets the value of a character in .sc,.tc, etc.
  147. **********************************************/
  148. void setchar(int *param,int stack,int defval,int minval,int maxval)
  149. {char *lin,c;
  150.  int val;
  151.  lin=LIN;
  152.  c=*lin;
  153.  while((c!=' ')&&(c!='\t')&&(c!='\n')) c=*(++lin);/*skip command*/
  154.  while((c==' ')||(c=='\t')||(c=='\n')) c=*(++lin);/*skip white*/
  155.  if(c) val=c;
  156.  else val=NO_VAL;
  157.  if(stack) setS(param,val,'0',defval,minval,maxval);
  158.  else set(param,val,'0',defval,minval,maxval);
  159. }
  160. /**************************************************/
  161. void getot()    /*process .ot, output translation*/
  162. {char typ,chr,*pchr;
  163. char wrdbuf[MAXLINE], buff[128];
  164.     gwLIN(wrdbuf);    /*remove .pc*/
  165.     if(gwLIN(wrdbuf)==WE_HAVE_A_WORD)
  166.         {typ=*wrdbuf;
  167.          if ((typ!=TFVAL[0])&&(typ!=CFVAL[0])) return;
  168.          chr=wrdbuf[1];
  169.          if (chr<=' ') return;
  170.         }
  171.     else return;    /*error: missing args*/
  172.     if('.'==getcode(buff) )    /*record pointer*/
  173.         {if (NULL==(pchr=(char *)malloc(1+buff[0])))
  174.             exitm("getot(): cannot malloc\n");
  175.          if (typ==TFVAL[0])
  176.             TPTR[chr-' ']=(char *)memcpy(pchr,buff,1+buff[0]);
  177.          else    CPTR[chr-' ']=(char *)memcpy(pchr,buff,1+buff[0]);
  178.         }
  179.     else fprintf(stderr,"\n.OT: error in line: %s\n",
  180.                         LINE);
  181. }
  182. /************************************************/
  183. /* getcode(char buff[128]) returns '.' if o.k.  */
  184. /* resultant collected codes will be placed in  */
  185. /* buff[128] with buff[0] containing the count. */
  186. /* LINE must contain the radix as the first     */
  187. /* token and it and the following lines then    */
  188. /* contain code values finally delimited by a   */
  189. /* token that starts with a '.' ; comments can  */
  190. /* be at the end of any of these lines,         */
  191. /* set off by " ;"                */
  192. /************************************************/
  193. char getcode(char *buff)    
  194. {int base,code;    /*conversion radix, value*/
  195. char *pcode,ncode;
  196. char wrdbuf[MAXLINE];
  197.     if(gwLIN(wrdbuf)==WE_HAVE_A_WORD)
  198.        {switch(toupper(*wrdbuf))
  199.         {case 'B': base=2;break;
  200.         case 'O':
  201.         case 'Q': base=8;break;
  202.         case 'D': base=10;break;
  203.         case 'H': base=16;break;
  204.         default: return(FALSE);    /*error*/
  205.         }
  206.        }
  207.     else return(FALSE);    /*error: missing arg*/
  208.     pcode = buff++;
  209.     *pcode=ncode = 0;
  210.     while(ncode<127)
  211.     {while(gwLIN(wrdbuf)!=WE_HAVE_A_WORD)
  212.         fgets3();
  213.      if(';'==*wrdbuf) fgets3();/*comment*/
  214.      else if('.'==*wrdbuf)
  215.         {*pcode = ncode;        /*save #*/
  216.         return(*wrdbuf);
  217.         }
  218.      else    {
  219.         if((code=value(base,wrdbuf)) > -1)
  220.             {*buff = code;
  221.              buff++;
  222.              ncode++ ;
  223.             }
  224.         else return(*wrdbuf);    /*conversion error*/
  225.         }
  226.     }
  227.     fprintf(stderr,"\nGETCODE: code sequence too long");
  228.     return(FALSE);
  229. }
  230. /**************************************************/
  231. void ocode()    /*process .ou*/
  232. {char wrdbuf[MAXLINE], buff[128];
  233.     gwLIN(wrdbuf);    /*remove .ou*/
  234.     if('.'==getcode(buff)) outstr(buff);
  235.     else fprintf(stderr,"\nOCODE: error in:\n%s",LINE);
  236. }
  237. /**************************************************/
  238. void outstr(char *p)    /*print string whose bytecount is *p */
  239. {int i;
  240. for(i=*(p++); i; i--) cputc(*(p++),ofp);
  241. }
  242. /**************************************************/
  243. void getfr()    /*process .FR ;cf. ocode() */
  244. {char *pchr,wrdbuf[MAXLINE], buff[128];
  245.     gwLIN(wrdbuf);
  246.     if(gwLIN(wrdbuf)==WE_HAVE_A_WORD)
  247.         FRVAL = atoi(wrdbuf);
  248.     else return;
  249.     FRVAL=max(1,FRVAL); FRVAL=min(FRVAL,4);
  250.     if('.'==getcode(buff) )    /*record pointer*/
  251.         {if (NULL==(pchr=(char *)malloc(1+buff[0])))
  252.             exitm("getfr(): cannot malloc\n");
  253.          if (FRVAL!=1)
  254.             FRSTRING=(char *)memcpy(pchr,buff,1+buff[0]);
  255.          else
  256.             WHSTRING=(char *)memcpy(pchr,buff,1+buff[0]);
  257.         }
  258.     else fprintf(stderr,"\n.FR: error in line:\n%s",
  259.                         LINE);
  260. }
  261. /******************* page traps! *************/
  262. #define MAXINT    32767
  263. #define NTRAPS    10
  264. #define NMSIZ    10
  265. typedef struct
  266.     {int loc;
  267.      char nam[NMSIZ];
  268.     } tentry;
  269. tentry Ttable[NTRAPS];
  270. char *TRAPNAM;
  271. void when()
  272. {char c,*lptr;
  273.  int i,j,save;
  274.  i=get_val2(LIN,&c,&lptr);
  275.  if(i==NO_VAL) return;
  276.  if(c=='-') i=-i;
  277.  for(j=0;j<NTRAPS;j++)
  278.    if(Ttable[j].loc==i) goto storename;
  279.  /* else not an occupied position */
  280.  for(j=0;j<NTRAPS;j++)
  281.    if(Ttable[j].nam[0]=='\0')
  282.     {Ttable[j].loc=i;
  283. storename:
  284.      save=SENTENCE;
  285.      if(!getwrd(lptr,Ttable[j].nam))
  286.         Ttable[j].nam[0]='\0';
  287.      SENTENCE=save;
  288.      return;
  289.     }
  290. /* here only if no place to put trap */
  291.  exitm(".wh: used up entire trap table\n");
  292. }
  293. /******************************/
  294. void changetrap()
  295. {char c,wbuf[NMSIZ],*lptr;
  296.  int i,j,save;
  297.  save=SENTENCE;
  298.  gwLIN(wbuf); /*remove command*/
  299.  if(!getwrd(LIN,wbuf))
  300.     {SENTENCE=save; return;} /*if no name*/
  301.  i=get_val2(LIN,&c,&lptr);
  302.  SENTENCE=save;
  303.  for(j=0;j<NTRAPS;j++)
  304.    if(strcmp(wbuf,Ttable[j].nam)==0)
  305.     {if(i==NO_VAL)
  306.         {Ttable[j].nam[0]='\0';
  307.          return;
  308.         }
  309.      if(c=='-') i=-i;
  310.      Ttable[j].loc=i;
  311.      return;
  312.     }
  313. /* reaches here if no name match */
  314. }
  315. /****************************************/
  316. void itset()
  317. {char c,*lptr;
  318.  int save;
  319.  INTRAP=get_val2(LIN,&c,&lptr);
  320.  if((INTRAP==NO_VAL)||(c=='-'))
  321.     {INTRAP=0;
  322.      ITstring[0]='\0';
  323.      return;
  324.     }
  325.  save=SENTENCE;
  326.  if(!getwrd(lptr,ITstring))
  327.     ITstring[0]='\0';
  328.  SENTENCE=save;
  329.  return;
  330. }
  331. /****************************************/
  332. void EMset()
  333. {char *lptr,c;
  334.  int save;
  335.  for(lptr=LIN;(*lptr!=' ') && (*lptr!='\t') && *lptr ; lptr++) ;
  336.  save=SENTENCE;
  337.  if(!getwrd(lptr,EMstring))
  338.     EMstring[0]='\0';
  339.  SENTENCE=save;
  340. }
  341. /****************************************/
  342. /* dotT() returns distance to the next  */
  343. /* page trap from ln or BIG#; as a side */
  344. /* effect, it updates TRAPNAM.          */
  345. /****************************************/
  346. int dotT(int ln)
  347. {int i,j,dist;
  348.  dist=MAXINT-1000;
  349.  for(i=0;i<NTRAPS;i++)    /*search list of traps*/
  350.   if(Ttable[i].nam[0]!='\0')
  351.     {if((j=Ttable[i].loc)<0) j+=PLVAL[0];
  352.      if( ((j-=ln)>0) && (j<dist) )
  353.         {dist=j;
  354.          TRAPNAM=Ttable[i].nam;
  355.         }
  356.     }
  357.   return(dist);
  358. }
  359. /************************************/
  360. void setTRAP() /*used to recalculate FOOTLOC,TRAPLOC*/
  361. { FOOTLOC = PLVAL[0] - M3VAL[0] - M4VAL[0];
  362.   TRAPLOC = VLINENO + dotT(VLINENO);
  363.   if (TRAPLOC>FOOTLOC) TRAPLOC=FOOTLOC;
  364. }
  365.