home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / fweb153.zip / fweb-1.53 / web / style.c < prev    next >
C/C++ Source or Header  |  1995-09-23  |  25KB  |  1,436 lines

  1. #if(0)
  2.   FTANGLE v1.53, created with UNIX on "Thursday, September 21, 1995 at 15:06."  \
  3.   COMMAND LINE: "web/ftangle web/style -A -# --F -= 1.53/web/style.c" \
  4.   RUN TIME: "Saturday, September 23, 1995 at 16:17." \
  5.   WEB FILE:    "web/style.web" \
  6.   CHANGE FILE: (none)
  7. #endif
  8. #define _STYLE_h   \
  9.  
  10. #define CMNT_CHAR  '%'/* The comment character in the style file. */ \
  11.  \
  12.  
  13. #define isodigit(c)(isdigit(c)&&(c)!='8'&&(c)!='9') \
  14. /* An |outer_char| octal digit? */ \
  15.  
  16. #define Ctoi(c)ctoi(XCHR(c))/* For |ASCII|. */ \
  17.  
  18. #define ENV_FWEB_STY  "FWEB_STYLE_DIR"/* Environment variable that defines \
  19.         directory of style file.  */ \
  20.  
  21. #define ignore  0 \
  22.  
  23. #define SET_ACOLOR(field,clr)wt_style.color.field.value= clr \
  24.  
  25. #define ENV_TERM  "TERM"/* Unix environment variable for terminal type. */ \
  26.  
  27. #define NUM_TEMP_PTRS  20 \
  28.  
  29.  
  30.  
  31. #include "typedefs.h"
  32.  
  33.  
  34.  
  35.  
  36.  
  37. #include "map.h"
  38.  
  39.  
  40.  
  41.  
  42. typedef struct
  43. {
  44. CONST char*name;
  45. COLOR value;
  46. }CLR_MATCH;
  47.  
  48. CLR_MATCH clr_match[]= {
  49. {"blue",BLUE},
  50. {"default",NORMAL},
  51. {"green",GREEN},
  52. {"normal",NORMAL},
  53. {"orange",ORANGE},
  54. {"red",RED},
  55. {"yellow",YELLOW},
  56. {"",NORMAL}
  57. };
  58.  
  59.  
  60.  
  61.  
  62. /* The shorter length here is primarily to keep the stack under control. \
  63. Now that |N_MSGBUF| is used  dynamically, maybe this statement isn't \
  64. necessary. */
  65. #ifdef SMALL_MEMORY
  66. #define N_MSGBUF 2000
  67. #else
  68. #define N_MSGBUF 10000
  69. #endif
  70.  
  71.  
  72.  
  73.  
  74.  
  75. #ifndef C_TYPES
  76. #include SFILE(y_type.h)
  77. #endif /* |C_TYPES| */
  78.  
  79.  
  80.  
  81. outer_char HUGE*sprm_buf,HUGE*sprm_ptr,HUGE*sprm_end;/* For \.{-p} option. */
  82. outer_char HUGE*sprm_ptr0;/* Marks beginning of command-line \.{-p} options. */
  83.  
  84. boolean from_sprm;
  85. static BUF_SIZE sbuf_len;/* Length of line buffer. */
  86. static outer_char HUGE*stemp,HUGE*stemp_end,HUGE*tloc;/* Temporary \
  87.     hold for the argument, and position in it. */
  88. static outer_char cur_char;/* Current character after possible escape \
  89.                 translation. */
  90. extern ASCII xord[];
  91. extern outer_char xchr[];
  92.  
  93.  
  94.  
  95. static CONST outer_char*sty_file_name;
  96. static boolean warn_if_absent;
  97. static FILE*sty_file;
  98. static S_MAP HUGE*map_array= fweb_map;/* Points to the common map \
  99.     array for both \FWEAVE\ and \FTANGLE. */
  100. jmp_buf top_of_style;/* Environment for the |setjmp|--|longjmp|. */
  101.  
  102.  
  103.  
  104. eight_bits ccode[128];/* Meaning of a character following '\.{@}'. */
  105. CONST outer_char*cname[128];/* Associated names of control codes. */
  106. CONST ASCII HUGE*at_codes;
  107.  
  108.  
  109.  
  110. static CC_BUF HUGE*cc_buf;
  111.  
  112.  
  113. static outer_char HUGE*termcap;/* Name of termcap file. */
  114. static outer_char HUGE*tcap_buffer;/* Allocated dynamically. */
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122. outer_char esc_char FCN((ppc))
  123. CONST outer_char HUGE*HUGE*ppc C1("")
  124. {
  125. int k;
  126. unsigned n;
  127. CONST outer_char HUGE*pc= *ppc;/* Pointer to first character after~'\.\\'. */
  128.  
  129. if(isodigit(*pc))
  130.  
  131. {
  132. n= ctoi(*pc++);
  133. for(k= 0;k<2;k++)
  134. {
  135. if(!isodigit(*pc))break;
  136. n= 8*n+ctoi(*pc++);
  137. }
  138. }
  139.  
  140.  
  141. else if(*pc=='x'&&isxdigit(*(pc+1)))
  142.  
  143. {
  144. pc++;/* Position after \.{'x'}. */
  145. n= ctoi(*pc++);
  146. if(isxdigit(*pc))n= 16*n+ctoi(*pc++);
  147. }
  148.  
  149.  
  150. else
  151. {/* Handle ordinary escaped character. */
  152. switch(*pc)
  153. {
  154. case 'a':n= '\007';break;
  155. case 'b':n= '\b';break;
  156. case 'f':n= '\f';break;
  157. case 'n':n= '\n';break;
  158. case 'r':n= '\r';break;
  159. case 't':n= '\t';break;
  160. case 'v':n= '\v';break;
  161. default:
  162. n= (unsigned)(*pc);/* Unknowns, like '\.{\\m}' $\to$~'\.m'. */
  163. break;
  164. }
  165. pc++;
  166. }
  167.  
  168. *ppc= pc;
  169. return(outer_char)n;
  170. }
  171.  
  172.  
  173. ASCII esc_achar FCN((ppc))
  174. CONST ASCII HUGE*HUGE*ppc C1("")
  175. {
  176. int k;
  177. unsigned n;
  178. CONST ASCII HUGE*pc= *ppc;/* Pointer to first character after~'\.\\'. */
  179.  
  180. if(isOdigit(*pc))
  181.  
  182. {
  183. n= Ctoi(*pc++);
  184. for(k= 0;k<2;k++)
  185. {
  186. if(!isOdigit(*pc))break;
  187. n= 8*n+Ctoi(*pc++);
  188. }
  189. }
  190.  
  191.  
  192. else if(*pc==0170&&isXdigit(*(pc+1)))
  193.  
  194. {
  195. pc++;/* Position after \.{'x'}. */
  196. n= Ctoi(*pc++);
  197. if(isXdigit(*pc))n= 16*n+Ctoi(*pc++);
  198. }
  199.  
  200.  
  201. else
  202. {
  203. switch(*pc)
  204. {
  205. case 0141:n= 07;break;
  206. case 0142:n= 010;break;
  207. case 0146:n= 014;break;
  208. case 0156:n= 012;break;
  209. case 0162:n= 015;break;
  210. case 0164:n= 011;break;
  211. case 0166:n= 013;break;
  212. default:n= *pc;break;/* Unknowns, like '\.{\\m}' $\to$~'\.m'. */
  213. }
  214.  
  215. #if(DEBUG_XCHR)
  216. n= XCHR(n);
  217. #endif
  218. pc++;
  219. }
  220.  
  221. *ppc= pc;/* Advance the pointer to point beyond the end of the constant. */
  222.  
  223. #if(DEBUG_XCHR)
  224. n= xord[n];
  225. #endif
  226.  
  227. return(ASCII)n;/* Return the value. */
  228. }
  229.  
  230.  
  231. int ctoi FCN((c))
  232. outer_char c C1("")
  233. {
  234. switch(c)
  235. {
  236. case '0':return 0x0;case '1':return 0x1;case '2':return 0x2;case '3':return 0x3;case '4':return 0x4;case '5':return 0x5;
  237. case '6':return 0x6;case '7':return 0x7;case '8':return 0x8;case '9':return 0x9;
  238. case 'a':return 0xa;case 'A':return 0xA;
  239. case 'b':return 0xb;case 'B':return 0xB;
  240. case 'c':return 0xc;case 'C':return 0xC;
  241. case 'd':return 0xd;case 'D':return 0xD;
  242. case 'e':return 0xe;case 'E':return 0xE;
  243. case 'f':return 0xf;case 'F':return 0xF;
  244. default:return 0;
  245. }
  246. }
  247.  
  248.  
  249. S_MAP HUGE*find_sty FCN((m,keyword))
  250. S_MAP HUGE*m C0("Array of map variables")
  251. CONST outer_char HUGE*keyword C1("Search for this keyword")
  252. {
  253. for(;*(m->keyword);m++)
  254. if(STRCMP(keyword,m->keyword)==0)return m;
  255.  
  256. return NULL;
  257. }
  258.  
  259.  
  260. boolean sty_line(VOID)
  261. {
  262. typedef enum{FROM_INI,FROM_LOCAL,FROM_CMD_LINE}STYLE_MODE;
  263.  
  264. static STYLE_MODE mode= FROM_INI;
  265.  
  266. from_sprm= BOOLEAN(mode==FROM_INI||mode==FROM_CMD_LINE);
  267.  
  268. switch(mode)
  269. {
  270. case FROM_INI:
  271. if(!sty0_line(sprm_ptr0))
  272. mode++;
  273. else
  274. return YES;
  275.  
  276. case FROM_LOCAL:
  277. if(!sty0_line(NULL))
  278. mode++;
  279. else
  280. return YES;
  281.  
  282. case FROM_CMD_LINE:
  283. return sty0_line(sprm_end);
  284. }
  285.  
  286. return YES;/* Dummy. */
  287. }
  288.  
  289. boolean sty0_line FCN((last_sprm))
  290. outer_char HUGE*last_sprm C1("")
  291. {
  292. int c;/* Single character read from style file. |int| rather than |char| \
  293.         because that's what |getc| returns. */
  294.  
  295. sloc= slimit= sbuf;/* Position to beginning of line. */
  296.  
  297. if(last_sprm)
  298. {/* Read from the \.{-p} buffer. */
  299. if(sprm_ptr>=last_sprm)
  300. {/* Nothing more in the \.{-p} buffer. */
  301. s_line= 0;
  302. return NO;
  303. }
  304. else
  305. {/* Copy line from \.{-p} buffer. */
  306. int n;
  307. outer_char HUGE*p;
  308.  
  309. if((p= (outer_char HUGE*)STRCHR(sprm_ptr,'\n'))==NULL)
  310. {
  311.  
  312. err0_print(ERR_S,OC("Trouble in sty_line"),0);
  313. return NO;
  314. }
  315. else n= PTR_DIFF(int,p,sprm_ptr);
  316.  
  317. STRNCPY(sloc,sprm_ptr,n);
  318. sprm_ptr+= n+1;
  319. slimit+= n;
  320. s_line++;
  321. }
  322. }
  323. else
  324. {/* Read from the local style file. */
  325. if(!sty_file)
  326.  
  327. {
  328. outer_char full_sty_name[MAX_FILE_NAME_LENGTH];
  329.  
  330. /* If there's no style file, do nothing. */
  331. if(!*sty_file_name)return NO;
  332.  
  333. if(warn_if_absent)
  334. {
  335. STRCPY(full_sty_name,sty_file_name);
  336. add_prefix(full_sty_name);
  337. }
  338. else mk_fname(full_sty_name,MAX_FILE_NAME_LENGTH,
  339. OC(ENV_FWEB_STY),NO,sty_file_name);
  340.  
  341. if((sty_file= fopen((char*)full_sty_name,"r"))==NULL)
  342. {
  343. if(warn_if_absent)
  344. {
  345.  
  346. err0_print(ERR_C,OC("Can't open style file \"%s\""),1,full_sty_name);
  347. }
  348. return NO;
  349. }
  350.  
  351. reading(full_sty_name,YES);
  352. }
  353.  
  354.  
  355.  
  356.  
  357. {
  358. if(feof(sty_file))
  359. return NO;
  360.  
  361. s_line++;
  362.  
  363. while((c= getc(sty_file))!=EOF&&c!='\n')
  364. {
  365. if(slimit==sbuf_end)
  366. {
  367.  
  368. err0_print(ERR_S,OC("Input line too long; max is %lu characters"),1,sbuf_len);
  369. ungetc(c,sty_file);
  370. break;
  371. }
  372.  
  373. *slimit++= (outer_char)c;/* Put character into buffer. */
  374. }
  375. }
  376.  
  377.  
  378. }
  379.  
  380. return YES;
  381. }
  382.  
  383.  
  384. STY_TYPE next_sty(VOID)
  385. {
  386. outer_char c;/* Single character from the buffer. */
  387.  
  388. WHILE()
  389. {
  390. /* If we get to the end of the line or recognize a comment, read the next \
  391. line. */
  392. if(sloc==slimit||(c= *sloc++)==CMNT_CHAR)
  393. {
  394. if(!sty_line())return S_DONE;/* Get more. */
  395. continue;
  396. }
  397.  
  398. if(isalpha(c)||c=='_')
  399. {
  400. sloc--;
  401. tloc= stemp;
  402. while(isalpha(*sloc)||isdigit(*sloc)||*sloc=='_'||*sloc=='.')
  403. {
  404. cur_char= *sloc++;
  405.  
  406. {
  407. if(tloc<stemp_end)
  408. *tloc++= (outer_char)CHOICE(cur_char=='.','_',cur_char);
  409. else
  410. {
  411.  
  412. err0_print(ERR_S,OC("Buffer overflow"),0);
  413. break;
  414. }
  415. }
  416.  
  417.  
  418. }
  419.  
  420. *tloc= '\0';return S_KEYWORD;
  421. }
  422.  
  423.  
  424. else if(isdigit(c)||c=='-'||c=='+')
  425. {
  426. sloc--;
  427. tloc= stemp;
  428. if(*sloc=='+'||*sloc=='-'){cur_char= *sloc++;
  429. {
  430. if(tloc<stemp_end)*tloc++= cur_char;
  431. else
  432. {
  433.  
  434. err0_print(ERR_S,OC("Buffer overflow"),0);
  435. break;
  436. }
  437. }
  438.  
  439. }
  440.  
  441. while(isdigit(*sloc)){cur_char= *sloc++;
  442. {
  443. if(tloc<stemp_end)*tloc++= cur_char;
  444. else
  445. {
  446.  
  447. err0_print(ERR_S,OC("Buffer overflow"),0);
  448. break;
  449. }
  450. }
  451.  
  452. }
  453.  
  454. /* We allow the possibility of long integers. */
  455. if(*sloc=='l'||*sloc=='L')
  456. {
  457. sloc++;/* Skip over '\.L'. */
  458. *tloc= '\0';return S_LONG;
  459. }
  460.  
  461. *tloc= '\0';return S_INT;
  462. }
  463.  
  464.  
  465. else if(c=='"')
  466. {
  467. tloc= stemp;/* Start of buffer. */
  468.  
  469. while(*sloc!='"')
  470. {
  471. if(*sloc=='\\')
  472. if(++sloc==slimit)
  473. {
  474. sty_line();/* String is continued. */
  475. continue;
  476. }
  477. else cur_char= esc_char(&sloc);
  478. else cur_char= *sloc++;
  479.  
  480.  
  481. {
  482. if(tloc<stemp_end)*tloc++= cur_char;
  483. else
  484. {
  485.  
  486. err0_print(ERR_S,OC("Buffer overflow"),0);
  487. break;
  488. }
  489. }
  490.  
  491.  
  492. }
  493.  
  494. sloc++;/* Skip over terminating quote. */
  495.  
  496. *tloc= '\0';return S_STRING;
  497. }
  498.  
  499.  
  500. else if(c=='\'')
  501. {
  502. tloc= stemp;
  503.  
  504. /* If the character is escaped, turn the next character into the actual \
  505. byte. */
  506. if(*sloc=='\\'){sloc++;cur_char= esc_char(&sloc);}
  507. else cur_char= *sloc++;
  508.  
  509.  
  510. {
  511. if(tloc<stemp_end)*tloc++= cur_char;
  512. else
  513. {
  514.  
  515. err0_print(ERR_S,OC("Buffer overflow"),0);
  516. break;
  517. }
  518. }
  519.  
  520.  
  521. sloc++;/* Skip over closing quote. */
  522.  
  523. *tloc= '\0';return S_CHAR;
  524. }
  525.  
  526.  
  527. else if(c==' '||c=='\t'||c=='=')continue;
  528. else
  529. {
  530.  
  531. err0_print(ERR_S,OC("Invalid style-file field; \
  532. skipping remainder of file"),0);
  533. longjmp(top_of_style,1);
  534. }
  535. }
  536.  
  537. DUMMY_RETURN(S_DONE);
  538. }
  539.  
  540.  
  541. SRTN read_sty FCN((sty_file_name0,warn_if_absent0))
  542. CONST outer_char sty_file_name0[]C0("")
  543. boolean warn_if_absent0 C1("")
  544. {
  545. sty_file_name= sty_file_name0;
  546. warn_if_absent= warn_if_absent0;
  547.  
  548.  
  549. {
  550. IN_COMMON outer_char HUGE*style_args;
  551.  
  552. if(TeX_processor==LaTeX_p)
  553. {
  554. W_META HUGE*m= &w_style.misc.meta;
  555. INDEX HUGE*i= &w_style.indx;
  556.  
  557. pfmt->id= pfmt->id_outer= pfmt->id_inner= OC("\\>");
  558. pfmt->ID= pfmt->ID_OUTER= pfmt->ID_INNER= OC("\\WUC");
  559. pfmt->RESERVED= OC("\\WRS");
  560.  
  561. m->TeX.begin= OC("\\begin{verbatim}");
  562. m->TeX.end= OC("\\end{verbatim}");
  563. m->code.begin= OC("\\WBM ");
  564. m->code.end= OC("\\WEM ");
  565.  
  566. i->encap_prefix= OC("\\M");
  567. i->encap_infix= OC("{");
  568. i->encap_suffix= OC("}");
  569. }
  570.  
  571. if(prn_style_defaults)
  572. see_style(style_args,YES);
  573. }
  574.  
  575.  
  576.  
  577.  
  578. {
  579. ALLOC(outer_char,sbuf,"sb",sbuf_len,0);
  580. sbuf_end= sbuf+sbuf_len;
  581.  
  582. stemp= GET_MEM("stemp",sbuf_len,outer_char);
  583. stemp_end= stemp+sbuf_len;
  584.  
  585. /* Reset the \.{-p} buffer. */
  586. sprm_end= sprm_ptr;/* Actual end of material in buffer. */
  587. sprm_ptr= sprm_buf;/* Start at beginning. */
  588. }
  589.  
  590.  
  591.  
  592. if(setjmp(top_of_style)!=0)goto done_sty;
  593.  
  594. /* Read the first line of style file. If the file's empty, do nothing. */
  595. if(!sty_line())goto done_sty;
  596.  
  597. /* Parse the file. */
  598. WHILE()
  599. switch(next_sty())
  600. {
  601. case S_CMNT:break;
  602.  
  603. case S_KEYWORD:
  604.  
  605. {
  606. S_MAP HUGE*ps;/* Returned from |find_sty|. */
  607. STY_TYPE type;
  608.  
  609. /* Is it a valid keyword? */
  610. if((ps= find_sty(map_array,stemp))==NULL)
  611. {
  612.  
  613. err0_print(ERR_S,OC("Invalid style-file keyword; skipping remainder of line"),0);
  614. sty_line();
  615. break;
  616. }
  617.  
  618. /* Get the next argument. Is its type correct? */
  619. type= ps->type&~S_MODIFIED;
  620.  
  621. if(type!=next_sty())
  622. {
  623.  
  624. err0_print(ERR_S,OC("Argument of keyword \"%s\" has wrong type; \
  625. conversion attempted"),1,ps->keyword);
  626. }
  627.  
  628. switch(type)
  629. {
  630. case S_INT:
  631. case S_LONG:
  632. case S_STRING:
  633. case S_CHAR:
  634. break;
  635.  
  636. default:
  637.  
  638. err0_print(ERR_S,OC("Was expecting integer, double-quoted string, \
  639. or single-quoted character here; argument not processed"),0);
  640. goto processed;
  641. }
  642.  
  643. /* Store the argument, check for validity, or process the result in some \
  644. way. */
  645. if(ps->init)
  646. (*ps->init)(ps);
  647. else
  648. CONFUSION("style keyword","NULL ini fcn");
  649.  
  650. /* Flag it as modified. */
  651. ps->type|= S_MODIFIED;
  652.  
  653. processed:;
  654. }
  655.  
  656.  
  657.  
  658. break;
  659.  
  660. default:
  661.  
  662. err0_print(ERR_S,OC("Was expecting keyword or comment here; \
  663. skipping remainder of file"),0);/* Falls through to |case S_DONE. */
  664.  
  665. case S_DONE:
  666. done_sty:
  667. if(sty_file)fclose(sty_file);
  668. if(sprm_buf)FREE(sprm_buf);
  669. FREE_MEM(stemp,"stemp",sbuf_len,outer_char);
  670. FREE_MEM(sbuf,"sb",sbuf_len,outer_char);
  671. return;
  672. }
  673. }
  674.  
  675.  
  676. SRTN ini_style(VOID)
  677. {
  678. ini_colors(NO_COLOR);
  679.  
  680.  
  681. {
  682. link0(&wt_style.input_ext.web,OC("web"),ext_set);
  683. link0(&wt_style.input_ext.change,OC("ch"),ext_set);
  684. link0(&wt_style.input_ext.hweb,OC("hweb"),ext_set);
  685. link0(&wt_style.input_ext.hchange,OC("hch"),ext_set);
  686. }
  687.  
  688.  
  689. }
  690.  
  691.  
  692. SRTN set_str FCN((ps))
  693. S_MAP HUGE*ps C1("")
  694. {
  695. a_str(ps->ptr,(CONST outer_char HUGE*)stemp);
  696. }
  697.  
  698.  
  699. SRTN add_str FCN((ps))
  700. S_MAP HUGE*ps C1("")
  701. {
  702. outer_char HUGE*pa= *(outer_char HUGE**)ps->ptr,HUGE*pb;
  703.  
  704. if(*pa)
  705. {
  706. pb= GET_MEM("add_str",STRLEN(pa)+STRLEN(stemp)+2,outer_char);
  707. STRCPY(pb,pa);
  708. STRCAT(pb,"\n");
  709. STRCAT(pb,stemp);
  710. *(outer_char HUGE**)ps->ptr= pb;
  711. }
  712. else set_str(ps);
  713. }
  714.  
  715.  
  716. SRTN set_int FCN((ps))
  717. S_MAP HUGE*ps C1("")
  718. {
  719. *((int*)ps->ptr)= ATOI(stemp);
  720. }
  721.  
  722.  
  723. SRTN set_long FCN((ps))
  724. S_MAP HUGE*ps C1("")
  725. {
  726. *((long*)ps->ptr)= ATOL(stemp);
  727. }
  728.  
  729.  
  730. SRTN set_char FCN((ps))
  731. S_MAP HUGE*ps C1("")
  732. {
  733. *((outer_char*)ps->ptr)= *stemp;
  734. }
  735.  
  736.  
  737. SRTN ini_aclr FCN((ps))
  738. S_MAP HUGE*ps C1("")
  739. {
  740. CLR_MATCH HUGE*c;
  741.  
  742. set_str(ps);
  743.  
  744. for(c= clr_match;STRCMP(c->name,"")!=0;c++)
  745. if(STRCMP(c->name,*(outer_char HUGE**)ps->ptr)==0)
  746. {
  747. *(COLOR*)ps->ptr= c->value;
  748. return;
  749. }
  750.  
  751. CLR_PRINTF(warning,("! Color name \"%s\" is invalid; \
  752. replaced by \"default\"\n",(char*)ps->ptr));
  753. mark_harmless;
  754.  
  755. *(COLOR*)ps->ptr= NORMAL;
  756. }
  757.  
  758.  
  759. SRTN ini_clr FCN((ps))
  760. S_MAP HUGE*ps C1("")
  761. {
  762. set_int(ps);
  763. ini_colors((COLOR_MODE)(*(int*)ps->ptr));
  764. }
  765.  
  766.  
  767. SRTN ini_ext FCN((ps))
  768. S_MAP HUGE*ps C1("")
  769. {
  770. set_str(ps);
  771. ext_set((CONST outer_char HUGE**)ps->ptr);
  772. }
  773.  
  774.  
  775. SRTN ini_dot FCN((ps))
  776. S_MAP HUGE*ps C1("")
  777. {
  778. set_char(ps);
  779. *(ASCII*)ps->ptr= XORD(*(outer_char*)ps->ptr);
  780. }
  781.  
  782.  
  783. SRTN ini_cchar FCN((ps))
  784. S_MAP HUGE*ps C1("")
  785. {
  786. outer_char c;
  787.  
  788. set_char(ps);
  789. c= *(outer_char*)ps->ptr;
  790.  
  791. if(!(c&&isprint(c)&&c!=' '&&c!='0'))
  792. {
  793. *(outer_char*)ps->ptr= CCHAR;
  794.  
  795. err0_print(ERR_S,OC("Invalid continuation character '%c'; '%c' assumed"),2,c,CCHAR);
  796. }
  797. }
  798.  
  799.  
  800. SRTN ini_output_line_length FCN((ps))
  801. S_MAP HUGE*ps C1("")
  802. {
  803. int output_line_length;
  804.  
  805. set_int(ps);
  806. output_line_length= *(int*)ps->ptr;
  807.  
  808. if(output_line_length<MIN_OUTPUT_LINE_LENGTH||
  809. output_line_length>MAX_OUTPUT_LINE_LENGTH)
  810. {
  811. *(int*)ps->ptr= STANDARD_OUTPUT_LINE_LENGTH;
  812.  
  813. err0_print(ERR_S,OC("Invalid line length; %d assumed"),1,STANDARD_OUTPUT_LINE_LENGTH);
  814. }
  815. }
  816.  
  817.  
  818. SRTN zero_ccodes(VOID)
  819. {
  820. int c;/* Must be |int|, not |eight_bits|, so the |for| loop will end. */
  821.  
  822.  
  823. /* Start out by initializing the array to a special flag. */
  824. for(c= 0;c<=127;c++)
  825. {
  826. ccode[c]= USED_BY_NEITHER;
  827. cname[c]= OC("?");
  828. }
  829.  
  830.  
  831. {
  832. ccode[0100]= 0100;/* `quoted' at sign. This is so fundamental that it \
  833.             isn't allowed to be changed by the style file. */
  834.  
  835. ccode[0173]= 0173;/* Since this is related to the C or \Ratfor\ languages, \
  836.             it shouldn't be changed. */
  837. ccode[0175]= 0175;/* As above. */
  838.  
  839. ccode[076]= ignore;/* This is historical, and probably dangerous.  But \
  840.             it can't be |USED_BY_NEITHER|! */
  841. }
  842.  
  843.  
  844. }
  845.  
  846.  
  847. SRTN ini_ccode FCN((keyword,defaults,code))
  848. CONST outer_char*keyword C0("The desired keyword.")
  849. CONST outer_char*defaults C0("String of default characters.")
  850. eight_bits code C1("Assign this \FWEB\ universal code")
  851. {
  852. CONST outer_char*pc;/* Pointer to the default characters to initialize. */
  853. CONST S_MAP HUGE*m;/* Points to map entry for requested keyword. */
  854. boolean bad_code= NO;
  855. eight_bits cval;
  856. boolean override;/* Are the default values overridden by the style file? */
  857. IN_COMMON outer_char style_file_name[];
  858. ASCII a;/* Position in |ccode|. */
  859.  
  860. /* Search for the keyword in the map array. */
  861. if((m= find_sty(map_array,keyword))==NULL)
  862. override= NO;/* The keyword isn't even in the table. */
  863. else
  864. /* If the style file has set some values for this keyword, and the default \
  865.   values for this code are non-zero, then use the values from the style file. \
  866.   Otherwise, use the defaults. */
  867. override= BOOLEAN(*(outer_char**)m->ptr!=NULL);
  868. /* The style file is overriding. */
  869.  
  870. pc= (override&&code)?*(outer_char**)m->ptr:defaults;
  871.  
  872. /* If we're not ignoring this code completely, assign it to the relevant \
  873. values. */
  874. if(code!=USED_BY_NEITHER)
  875. while(*pc)
  876. {
  877. if(override&&((cval= ccode[XORD(*pc)])!=USED_BY_NEITHER))
  878. {
  879. printf("! ccode['%c'] already filled with \"%s\"; \
  880. not filled with \"%s\" = \"%s\".\n",
  881. *pc,(char*)ccode_name(cval),(char*)keyword,
  882. (char*)ccode_name(code));
  883. bad_code= YES;
  884. }
  885.  
  886. a= XORD(*pc++);
  887. ccode[a]= code;
  888. cname[a]= keyword;
  889. }
  890.  
  891. if(bad_code)
  892. FATAL(S,"!! Invalid control code mapping; check the style file ",
  893. style_file_name);
  894. }
  895.  
  896.  
  897. SRTN reassign FCN((old_code,new_code))
  898. eight_bits old_code C0("")
  899. eight_bits new_code C1("")
  900. {
  901. int c;
  902.  
  903. for(c= 0;c<128;c++)
  904. if(ccode[c]==old_code)
  905. ccode[c]= new_code;
  906. }
  907.  
  908.  
  909. SRTN prn_codes(VOID)
  910. {
  911. IN_COMMON boolean found_web;
  912. int HUGE*cc_indices;
  913. boolean prn_all= NO;
  914.  
  915. int k;
  916. int n= 0;/* Number of codes to print. */
  917.  
  918. if(!at_codes)
  919. return;
  920.  
  921. puts("Control-code assignments \
  922. ([S,D,C]==`Begins [section,definition,code])':");
  923.  
  924. cc_buf= GET_MEM("cc_buf",128,CC_BUF);
  925. cc_indices= GET_MEM("cc_indices",128,int);
  926.  
  927. if(*at_codes&&at_codes[0]==052&&at_codes[1]==052)
  928. prn_all= YES;
  929.  
  930. if(*at_codes&&!prn_all)
  931. {/* A specific list was given on command line. */
  932. CONST ASCII*p;
  933.  
  934. for(p= at_codes;*p;p++)
  935. prn0_code(*p,cc_buf,&n);
  936. }
  937. else
  938. {/* Do all of them. */
  939. ASCII a;
  940.  
  941. for(a= 0;a<128;a++)
  942. {
  943. if(ccode[a]==USED_BY_NEITHER&&!prn_all)
  944. continue;
  945.  
  946. prn0_code(a,cc_buf,&n);
  947. }
  948. }
  949.  
  950. FREE_MEM(at_codes,"at_codes",200,ASCII);
  951.  
  952. for(k= 0;k<n;k++)
  953. cc_indices[k]= k;
  954.  
  955. QSORT(cc_indices,n,sizeof(int),cc_cmp);
  956.  
  957. for(k= 0;k<n;k++)
  958. STRCPY(cc_buf[k][1],cc_buf[cc_indices[k]][0]);
  959.  
  960. for(k= 0;k<n;k++)
  961. printf("%-40s%-40s\n",cc_buf[k][0],cc_buf[k][1]);
  962.  
  963. FREE_MEM(cc_buf,"cc_buf",128,CC_BUF);
  964. FREE_MEM(cc_indices,"cc_indices",128,int);
  965.  
  966. if(!found_web)
  967. wrap_up();
  968. }
  969.  
  970.  
  971. int cc_cmp FCN((k0,k1))
  972. CONST VOID*pk0 C0("")
  973. CONST VOID*pk1 C1("")
  974. {
  975. char*s0,*s1;
  976.  
  977. s0= strrchr(cc_buf[*(int*)pk0][0],'-');
  978. s1= strrchr(cc_buf[*(int*)pk1][0],'-');
  979.  
  980. return STRCMP(s0,s1);
  981. }
  982.  
  983.  
  984. SRTN prn0_code FCN((a,cc_buf,pk))
  985. ASCII a C0("")
  986. CC_BUF HUGE*cc_buf C0("")
  987. int*pk C1("")
  988. {
  989. ASCII new_module,begin_code,formatt;
  990. ASCII cc= ccode[a];
  991. outer_char c;
  992. int n;
  993. outer_char*letter;
  994.  
  995. /* The following assumes that these particular codes never change.  This \
  996. was easier than including the header files. */
  997. new_module= ccode[052];
  998. begin_code= ccode[0141];
  999. formatt= ccode[0146];
  1000.  
  1001. c= XCHR(a);
  1002.  
  1003. if(cc==USED_BY_NEITHER)
  1004. letter= OC("   ");
  1005. else if(cc>=new_module)
  1006. letter= OC("[S]");
  1007. else if(cc>=begin_code)
  1008. letter= OC("[C]");
  1009. else if(cc>=formatt)
  1010. letter= OC("[D]");
  1011. else
  1012. letter= OC("   ");
  1013.  
  1014. n= 
  1015. nsprintf((outer_char*)&cc_buf[*pk][0][0],OC(isprint(c)?"  %s @%c":" %s@'0x%02x'"),2,isprint(c)?letter:OC(""),c);
  1016.  
  1017. switch(c)
  1018. {
  1019. case '/':
  1020. cname[c]= OC("(verbatim comment)");
  1021. break;
  1022.  
  1023. case '>':
  1024. cname[c]= OC("(end of module name)");
  1025. break;
  1026.  
  1027. case '@':
  1028. cname[c]= OC("(literal '@')");
  1029. break;
  1030. }
  1031.  
  1032. sprintf(&cc_buf[*pk][0][n]," --- %s",(char*)cname[c]);
  1033. (*pk)++;/* Increment array index. */
  1034. }
  1035.  
  1036.  
  1037. SRTN ini_colors FCN((color_mode))
  1038. COLOR_MODE color_mode C1("")
  1039. {
  1040.  
  1041. {
  1042. SET_ACOLOR(ordinary,NORMAL);
  1043. SET_ACOLOR(program_name,YELLOW);
  1044. SET_ACOLOR(info,GREEN);
  1045. SET_ACOLOR(warning,ORANGE);
  1046. SET_ACOLOR(error,RED);
  1047. SET_ACOLOR(fatal,RED);
  1048. SET_ACOLOR(module_num,ORANGE);
  1049. SET_ACOLOR(line_num,ORANGE);
  1050. SET_ACOLOR(in_file,YELLOW);
  1051. SET_ACOLOR(include_file,BLUE);
  1052. SET_ACOLOR(out_file,YELLOW);
  1053. SET_ACOLOR(timing,ORANGE);
  1054. }
  1055.  
  1056. /* Attach colors to fields. */
  1057.  
  1058. if(!(termcap= get_termcap()))wt_style.color_mode= color_mode= NO_COLOR;
  1059.  
  1060.  
  1061.  
  1062. link0(&wt_style.color._NORMAL,OC("me"),termset);
  1063. link0(&wt_style.color._YELLOW,OC("md"),termset);
  1064. link0(&wt_style.color._GREEN,OC("me"),termset);
  1065. link0(&wt_style.color._ORANGE,OC("me"),termset);
  1066. link0(&wt_style.color._RED,OC("mdmr"),termset);
  1067. link0(&wt_style.color._BLUE,OC("me"),termset);
  1068.  
  1069.  
  1070.  
  1071. switch(color_mode)
  1072. {
  1073. case NO_COLOR:
  1074. break;
  1075.  
  1076. case BILEVEL:
  1077. link0(&wt_style.color._YELLOW,OC("md"),termset);
  1078. link0(&wt_style.color._GREEN,OC("md"),termset);
  1079. link0(&wt_style.color._RED,OC("mdmr"),termset);
  1080. break;
  1081.  
  1082. case TRUE_COLOR:
  1083. link0(&wt_style.color._YELLOW,OC("md"),termset);
  1084. link0(&wt_style.color._GREEN,OC("us"),termset);
  1085. link0(&wt_style.color._BLUE,OC("md"),termset);
  1086. link0(&wt_style.color._ORANGE,OC("md"),termset);
  1087. link0(&wt_style.color._RED,OC("mdmr"),termset);
  1088. break;
  1089. }
  1090. }
  1091.  
  1092.  
  1093. SRTN ini_bilevel FCN((ps))
  1094. S_MAP HUGE*ps C1("")
  1095. {
  1096. set_str(ps);
  1097.  
  1098. if(termcap==NULL)return;
  1099.  
  1100. termset(ps->ptr);
  1101. }
  1102.  
  1103.  
  1104. SRTN link0 FCN((pp,id,fcn))
  1105. outer_char HUGE**pp C0("")
  1106. CONST outer_char HUGE*id C0("")
  1107. SRTN(HUGE_FCN_PTR*fcn)PROTO((CONST outer_char HUGE**))C1("")
  1108. {
  1109. a_str(pp,id);/* Allocate space, and store abbreviation string. */
  1110. (*fcn)((CONST outer_char HUGE**)pp);/* Replace that string by actual escape \
  1111.                     sequences. */
  1112. }
  1113.  
  1114.  
  1115. SRTN a_str FCN((pp,id))
  1116. outer_char HUGE**pp C0("")
  1117. CONST outer_char HUGE*id C1("")
  1118. {
  1119. *((outer_char HUGE**)pp)= GET_MEM("map_string",STRLEN(id)+1,outer_char);
  1120. STRCPY(*((outer_char HUGE**)pp),id);
  1121. }
  1122.  
  1123.  
  1124. outer_char*get_termcap(VOID)
  1125. {
  1126. #if !HAVE_GETENV
  1127. return NULL;
  1128. #else
  1129. if((termcap= GETENV(ENV_TERM))==NULL)return NULL;
  1130.  
  1131. tcap_buffer= GET_MEM("tcap_buffer",1024,outer_char);
  1132.  
  1133. switch(tgetent(tcap_buffer,termcap))
  1134. {
  1135. case-1:
  1136. printf("! Can't open termcap file \"%s\"\n",(char*)termcap);
  1137.  
  1138. case 0:
  1139. return NULL;
  1140. }
  1141.  
  1142. return termcap;
  1143. #endif /* |HAVE_GETENV| */
  1144. }
  1145.  
  1146.  
  1147. SRTN termset FCN((pid))
  1148. CONST outer_char HUGE**pid C1("")
  1149. {
  1150. outer_char value_buf[500],*area= value_buf;/* For |tgetstr|. */
  1151. outer_char*s;
  1152. CONST outer_char HUGE*t;
  1153. outer_char id[3];
  1154. int k,n;
  1155. SEQUENCES HUGE*ps= GET_MEM("termcap struct",1,SEQUENCES);
  1156. outer_char*string[NUM_TEMP_PTRS];
  1157.  
  1158. if(!termcap)return;
  1159.  
  1160. for(t= *pid,n= 0;*t;t+= 2)
  1161. {
  1162. if(n==NUM_TEMP_PTRS)break;
  1163. while(*t==' ')t++;
  1164.  
  1165. /* Put the abbreviation for escape sequence into |id|. */
  1166. STRNCPY(id,t,2);
  1167. TERMINATE(id,2);
  1168.  
  1169. /* Get the actual escape sequence from termcap file. */
  1170. if((s= tgetstr(id,&area))==NULL)
  1171. printf("! Termcap entry \"%s\" not found \
  1172. for terminal type \"%s\".\n",(char*)id,(char*)termcap);
  1173. else string[n++]= s;
  1174. }
  1175.  
  1176.  
  1177. {
  1178. ps->n= (short)n;
  1179. ps->string= GET_MEM("termcap strings",n,outer_char*);
  1180.  
  1181. for(k= 0;k<n;k++)
  1182. {
  1183. ps->string[k]= GET_MEM("termcap string",
  1184. STRLEN(string[k])+1,outer_char);
  1185. STRCPY(ps->string[k],string[k]);
  1186. }
  1187.  
  1188. FREE((void*)(*pid));
  1189. *pid= (CONST outer_char HUGE*)ps;
  1190. }
  1191.  
  1192.  
  1193. }
  1194.  
  1195.  
  1196. SRTN ext_set FCN((pid))
  1197. CONST outer_char HUGE**pid C1("")
  1198. {
  1199. outer_char id[1000],*p,*p0;
  1200. CONST outer_char HUGE*t;
  1201. outer_char*string[NUM_TEMP_PTRS];
  1202. int k,n;
  1203. SEQUENCES HUGE*ps= GET_MEM("termcap struct",1,SEQUENCES);
  1204.  
  1205. t= *pid;/* Beginning of blank-separated list. */
  1206. n= 0;/* Number of fields found. */
  1207. p= id;/* Start of storage area */
  1208.  
  1209. while(*t)
  1210. {
  1211. if(n==NUM_TEMP_PTRS)break;
  1212. while(*t==' ')t++;/* Skip initial white space. */
  1213.  
  1214. p0= p;
  1215. while(*t!=' '&&*t)*p++= *t++;
  1216. TERMINATE(p,0);
  1217. p++;
  1218. string[n++]= p0;/* Remember where string is. */
  1219. }
  1220.  
  1221.  
  1222. {
  1223. ps->n= (short)n;
  1224. ps->string= GET_MEM("termcap strings",n,outer_char*);
  1225.  
  1226. for(k= 0;k<n;k++)
  1227. {
  1228. ps->string[k]= GET_MEM("termcap string",
  1229. STRLEN(string[k])+1,outer_char);
  1230. STRCPY(ps->string[k],string[k]);
  1231. }
  1232.  
  1233. FREE((void*)(*pid));
  1234. *pid= (CONST outer_char HUGE*)ps;
  1235. }
  1236.  
  1237.  
  1238. }
  1239.  
  1240.  
  1241. int put_out FCN((c))
  1242. int c C1("")
  1243. {
  1244. return putchar(c);
  1245. }
  1246.  
  1247.  
  1248. SRTN set_color FCN((clr))
  1249. COLOR clr C1("")
  1250. {
  1251. color0.last= color0.present;/* Save the incoming color, for later restore. */
  1252.  
  1253. if(wt_style.color_mode!=NO_COLOR)
  1254. switch(clr)
  1255. {
  1256.  
  1257. case NORMAL:
  1258. tput((SEQUENCES*)wt_style.color._NORMAL);
  1259. break;
  1260.  
  1261. case GREEN:
  1262. tput((SEQUENCES*)wt_style.color._GREEN);
  1263. break;
  1264.  
  1265. case RED:
  1266. tput((SEQUENCES*)wt_style.color._RED);
  1267. break;
  1268.  
  1269. case BLUE:
  1270. tput((SEQUENCES*)wt_style.color._BLUE);
  1271. break;
  1272.  
  1273. case ORANGE:
  1274. tput((SEQUENCES*)wt_style.color._ORANGE);
  1275. break;
  1276.  
  1277. case YELLOW:
  1278. tput((SEQUENCES*)wt_style.color._YELLOW);
  1279. break;
  1280.  
  1281. default:
  1282. tput((SEQUENCES*)wt_style.color._NORMAL);
  1283. break;
  1284. }
  1285.  
  1286. color0.present= clr;
  1287. }
  1288.  
  1289.  
  1290. SRTN tput FCN((ps))
  1291. SEQUENCES*ps C1("")
  1292. {
  1293. int k;
  1294.  
  1295. for(k= 0;k<ps->n;k++)
  1296. tputs(ps->string[k],1,put_out);
  1297. }
  1298.  
  1299.  
  1300. SRTN see_style FCN((pa,see_all))
  1301. CONST outer_char HUGE*pa C0("")
  1302. boolean see_all C1("")
  1303. {
  1304. S_MAP HUGE**s0,HUGE**s,HUGE**s1,HUGE*m;
  1305.  
  1306. s0= GET_MEM("s0",sizeof(fweb_map)/sizeof(S_MAP),S_MAP HUGE*);
  1307.  
  1308. /* Fill an array of pointers. */
  1309. for(s= s0,m= fweb_map;*(m->keyword);s++,m++)
  1310. *s= m;
  1311.  
  1312. /* Sort the array. */
  1313. QSORT(s0,s-s0,sizeof(S_MAP HUGE*),cmpr_s_map);
  1314.  
  1315. /* Print out the values. */
  1316. printf("%s style-file parameters%s%s%s%s:\n",
  1317. see_all?"Default":"Modified",
  1318. *pa?" beginning with \"":"",(char*)pa,*pa?"\"":"",
  1319. see_all?"\n (null or empty values for colors and \
  1320. @ command codes are misleading)":"");
  1321.  
  1322. if(*pa)
  1323. {/* Convert \.{'.'} to \.{'\_'}. */
  1324. outer_char HUGE*p;
  1325.  
  1326. for(p= (outer_char HUGE*)pa;*p;p++)
  1327. if(*p=='.')
  1328. *p= '_';
  1329. }
  1330.  
  1331. for(s1= s0;s1<s;s1++)
  1332. see_map(*s1,pa,see_all);
  1333.  
  1334. FREE_MEM(s0,"s0",sizeof(fweb_map)/sizeof(S_MAP),S_MAP);
  1335. }
  1336.  
  1337.  
  1338. int cmpr_s_map FCN((s0,s1))
  1339. S_MAP HUGE**s0 C0("")
  1340. S_MAP HUGE**s1 C1("")
  1341. {
  1342. return STRCMP((*s0)->keyword,(*s1)->keyword);
  1343. }
  1344.  
  1345.  
  1346. SRTN see_map FCN((s,pa,see_all))
  1347. S_MAP HUGE*s C0("")
  1348. CONST outer_char HUGE*pa C0("")
  1349. boolean see_all C1("")
  1350. {
  1351. if(*pa&&STRNCMP(pa,s->keyword,STRLEN(pa))!=0)return;
  1352.  
  1353. if(see_all)
  1354. printf(" ");
  1355. else
  1356. {/* Handled modified parameters. */
  1357. if(s->type&S_MODIFIED)
  1358. {
  1359. printf("*");
  1360. s->type&= ~S_MODIFIED;
  1361. }
  1362.  
  1363. else return;
  1364. }
  1365.  
  1366. printf(" %s = ",(char*)s->keyword);
  1367.  
  1368. switch(s->type)
  1369. {
  1370. case S_STRING:
  1371. see_str(*((outer_char**)s->ptr));
  1372. break;
  1373.  
  1374. case S_CHAR:
  1375. printf("'%c'\n",*(outer_char*)s->ptr);
  1376. break;
  1377.  
  1378. case S_INT:
  1379. printf("%d\n",*(int*)s->ptr);
  1380. break;
  1381.  
  1382. case S_LONG:
  1383. printf("%ld\n",*(long*)s->ptr);
  1384. break;
  1385.  
  1386. default:
  1387. break;
  1388. }
  1389. }
  1390.  
  1391.  
  1392. SRTN see_str FCN((s))
  1393. CONST outer_char HUGE*s C1("")
  1394. {
  1395. outer_char c;
  1396.  
  1397. if(s==NULL)
  1398. {
  1399. printf("NULL\n");
  1400. return;
  1401. }
  1402. else if(s<(outer_char HUGE*)100)
  1403. {/* Horrible kludge to handle stupid color processing. */
  1404. printf("\n");
  1405. return;
  1406. }
  1407.  
  1408. printf("\"");
  1409.  
  1410. while((c= *s++))
  1411. print_it:
  1412. if(c=='\\')printf("\\\\");
  1413. else if(isprint(c))printf("%c",c);
  1414. else
  1415. {
  1416. printf("\\");
  1417. switch(c)
  1418. {
  1419. case '\a':c= 'a';goto print_it;
  1420. case '\b':c= 'b';goto print_it;
  1421. case '\f':c= 'f';goto print_it;
  1422. case '\n':c= 'n';goto print_it;
  1423. case '\r':c= 'r';goto print_it;
  1424. case '\t':c= 't';goto print_it;
  1425. case '\v':c= 'v';goto print_it;
  1426. default:
  1427. printf("%o",c);
  1428. break;
  1429. }
  1430. }
  1431.  
  1432. printf("\"\n");
  1433. }
  1434.  
  1435.  
  1436.