helpgen.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. char *rev = "4.00";
  2. /*+-------------------------------------------------------------------------
  3. helpgen.c -- ecu command help file maker
  4. wht@wht.net
  5. Defined functions:
  6. build_ecudoc()
  7. build_ecuhelp()
  8. build_ecunroff()
  9. main(argc, argv)
  10. search_cmd_list(cmd)
  11. show_cmds()
  12. test_help()
  13. usage()
  14. --------------------------------------------------------------------------*/
  15. /*+:EDITS:*/
  16. /*:01-24-1997-02:37-wht@yuriatin-SOURCE RELEASE 4.00 */
  17. /*:09-16-1996-19:03-wht@yuriatin-add nroff output */
  18. /*:09-11-1996-20:00-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  19. /*:09-06-1996-02:47-wht@kepler-cleanup */
  20. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  21. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  22. /*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  23. /*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  24. /*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  25. /*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  26. /*:07-12-1991-14:50-wht@n4hgf-remove obsolete ecuhelp.txt generator */
  27. /*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  28. #include <stdio.h>
  29. #include <ctype.h>
  30. #include "../ecu_types.h"
  31. #include "../ecutermio.h"
  32. #define DECLARE_P_CMD
  33. #define HELPGEN
  34. typedef int (*PFI) (); /* pointer to function returning integer */
  35. #include "../ecucmd.h"
  36. #include "../esd.h"
  37. #define PSRC "ecuhelp.src"
  38. #define PDAT "ecuhelp.data"
  39. #define PDOC "ecuhelp.doc"
  40. #define PNROFF "ecuhelp.nroff"
  41. long start_pos[TOKEN_QUAN];
  42. int token_line[TOKEN_QUAN];
  43. FILE *fpsrc; /* help source file */
  44. FILE *fpdat; /* help data file */
  45. FILE *fpdoc; /* help doc file */
  46. FILE *fptxt; /* help nroff file */
  47. FILE *fpnroff; /* help nroff file */
  48. P_CMD *pcmd;
  49. int src_line = 0;
  50. char buf[128];
  51. /*+-------------------------------------------------------------------------
  52. usage()
  53. --------------------------------------------------------------------------*/
  54. usage()
  55. {
  56. fprintf(stderr, "usage: helpgen [-b] [-d] [-s] [-t]\n");
  57. fprintf(stderr, " -b build %s from %s\n", PDAT, PSRC);
  58. fprintf(stderr, " -d build %s from %s\n", PDOC, PDAT);
  59. fprintf(stderr, " -n build %s from %s\n",PNROFF,PSRC);
  60. fprintf(stderr, " -s show list of commands\n");
  61. fprintf(stderr, " -t test help\n");
  62. fprintf(stderr, "At least one switch must be issued. They are executed\n");
  63. fprintf(stderr, "in the order shown on the usage line.\n");
  64. exit(1);
  65. } /* end of usage */
  66. /*+-------------------------------------------------------------------------
  67. search_cmd_list(cmd)
  68. --------------------------------------------------------------------------*/
  69. P_CMD *
  70. search_cmd_list(cmd)
  71. register char *cmd;
  72. {
  73. register P_CMD *cmd_list = icmd_cmds;
  74. while (cmd_list->token != -1)
  75. {
  76. if (strcmp(cmd_list->cmd, cmd) == 0)
  77. break;
  78. cmd_list++;
  79. }
  80. if (cmd_list->token == -1)
  81. return ((P_CMD *) 0);
  82. else
  83. return (cmd_list);
  84. } /* end of search_cmd_list */
  85. /*+-------------------------------------------------------------------------
  86. show_cmds()
  87. commands with null descriptions are "undocumented"
  88. --------------------------------------------------------------------------*/
  89. void
  90. show_cmds()
  91. {
  92. register int itmp;
  93. register P_CMD *this = icmd_cmds;
  94. register int longest_cmd = 0;
  95. register int longest_descr = 0;
  96. register int nl_flag = 0;
  97. char s80[80];
  98. P_CMD *longest_cmd_p = 0;
  99. P_CMD *longest_descr_p = 0;
  100. while (this->token != -1)
  101. {
  102. if (!*this->descr)
  103. {
  104. this++;
  105. continue;
  106. }
  107. itmp = strlen(this->cmd);
  108. if (itmp > longest_cmd)
  109. {
  110. longest_cmd = itmp;
  111. longest_cmd_p = this;
  112. }
  113. itmp = strlen(this->descr);
  114. if (itmp > longest_descr)
  115. {
  116. longest_descr = itmp;
  117. longest_descr_p = this;
  118. }
  119. this++;
  120. }
  121. this = icmd_cmds;
  122. while (this->token != -1)
  123. {
  124. if ((!this->min_ch) || (!*this->descr))
  125. {
  126. this++;
  127. continue;
  128. }
  129. strcpy(s80, this->cmd);
  130. pad_zstr_to_len(s80, longest_cmd + 2);
  131. for (itmp = 0; itmp < this->min_ch; itmp++)
  132. s80[itmp] = to_upper(s80[itmp]);
  133. fputs(s80, stderr);
  134. strcpy(s80, this->descr);
  135. pad_zstr_to_len(s80, longest_descr + 1);
  136. fputs(s80, stderr);
  137. if (nl_flag)
  138. fputs("\r\n", stderr);
  139. else
  140. fputs("| ", stderr);
  141. nl_flag = (nl_flag) ? 0 : 1;
  142. this++;
  143. }
  144. if (nl_flag)
  145. fputs("\r\n", stderr);
  146. itmp = longest_cmd + longest_descr + 5;
  147. sprintf(s80, "recwidth = %d\r\n", itmp);
  148. fprintf(stderr, s80);
  149. this = longest_cmd_p;
  150. sprintf(s80, "longest cmd: %s: %s\r\n", this->cmd, this->descr);
  151. fprintf(stderr, s80);
  152. this = longest_descr_p;
  153. sprintf(s80, "longest dsc: %s: %s\r\n", this->cmd, this->descr);
  154. fprintf(stderr, s80);
  155. } /* end of show_cmds */
  156. /*+-------------------------------------------------------------------------
  157. build_ecuhelp()
  158. --------------------------------------------------------------------------*/
  159. void
  160. build_ecuhelp()
  161. {
  162. register int itmp;
  163. register char *cptr;
  164. P_CMD *this;
  165. printf("\nBuilding %s\n", PDAT);
  166. /* use proc cmd entry for flag */
  167. this = icmd_cmds;
  168. while (this->token != -1)
  169. {
  170. this->proc = (PFI) 0;
  171. this++;
  172. }
  173. for (itmp = 0; itmp < TOKEN_QUAN; itmp++)
  174. {
  175. start_pos[itmp] = 0L;
  176. token_line[itmp] = 0;
  177. }
  178. if ((fpsrc = fopen(PSRC, "r")) == NULL)
  179. {
  180. perror(PSRC);
  181. exit(1);
  182. }
  183. if ((fpdat = fopen(PDAT, "w")) == NULL)
  184. {
  185. perror(PDAT);
  186. exit(1);
  187. }
  188. fwrite((char *)start_pos, sizeof(long), /* write null table */
  189. TOKEN_QUAN, fpdat);
  190. while (fgets(buf, sizeof(buf), fpsrc) != NULL)
  191. {
  192. src_line++;
  193. itmp = strlen(buf);
  194. buf[--itmp] = 0; /* kill trailing nl */
  195. if (buf[0] == '#') /* ignore comments */
  196. continue;
  197. if(buf[0] == '.') /* nroff directive */
  198. continue;
  199. if (buf[0] == '%') /* command indication */
  200. {
  201. SEARCH_CMD_LIST:
  202. if (!(this = search_cmd_list(&buf[1])))
  203. {
  204. #if 0 /* primarily because of 'eto' and 'fasi' */
  205. printf("line %d: '%s' not in command table\n",
  206. src_line, &buf[1]);
  207. #endif
  208. while (fgets(buf, sizeof(buf), fpsrc) != NULL)
  209. {
  210. src_line++;
  211. if(buf[0] == '.') /* nroff directive */
  212. continue;
  213. itmp = strlen(buf);
  214. buf[--itmp] = 0; /* kill trailing nl */
  215. if (buf[0] == '%') /* command indication */
  216. goto SEARCH_CMD_LIST;
  217. }
  218. break;
  219. }
  220. if (start_pos[this->token])
  221. {
  222. printf("line %d: '%s' already found on line %d\n",
  223. src_line, &buf[1], token_line[this->token]);
  224. exit(1);
  225. }
  226. fputs("\n", fpdat); /* terminate previous command description */
  227. start_pos[this->token] = ftell(fpdat);
  228. token_line[this->token] = src_line;
  229. fputs(" ", fpdat);
  230. cptr = &buf[1]; /* command text */
  231. itmp = 0;
  232. this->proc = (PFI) 1; /* indicate we save command info */
  233. while (*cptr) /* show cmd and min chars required */
  234. {
  235. if (itmp < this->min_ch)
  236. fputc(to_upper(*cptr++), fpdat);
  237. else
  238. fputc(to_lower(*cptr++), fpdat);
  239. itmp++;
  240. }
  241. if (*this->descr)/* if description present */
  242. fprintf(fpdat, " : %s\n \n", this->descr);
  243. else
  244. fputs("\n \n", fpdat);
  245. continue;
  246. }
  247. fprintf(fpdat, " %s\n", buf);
  248. }
  249. fseek(fpdat, 0L, 0); /* back to position table */
  250. fwrite((char *)start_pos, sizeof(long), /* write actual table */
  251. TOKEN_QUAN, fpdat);
  252. fclose(fpsrc);
  253. fputs("\n", fpdat); /* terminate last command */
  254. fclose(fpdat);
  255. /* say which commands weren't in the help source */
  256. this = icmd_cmds;
  257. while (this->token != -1)
  258. {
  259. if (this->min_ch && !this->proc)
  260. fprintf(stderr, "'%s' not in help source\n", this->cmd);
  261. this++;
  262. }
  263. } /* end of build_ecuhelp */
  264. /*+-------------------------------------------------------------------------
  265. build_ecunroff()
  266. --------------------------------------------------------------------------*/
  267. void
  268. build_ecunroff()
  269. {
  270. register int itmp;
  271. register char *cptr;
  272. P_CMD *this;
  273. printf("\nBuilding %s\n", PNROFF);
  274. /* use proc cmd entry for flag */
  275. this = icmd_cmds;
  276. while (this->token != -1)
  277. {
  278. this->proc = (PFI) 0;
  279. this++;
  280. }
  281. for (itmp = 0; itmp < TOKEN_QUAN; itmp++)
  282. {
  283. start_pos[itmp] = 0L;
  284. token_line[itmp] = 0;
  285. }
  286. if ((fpsrc = fopen(PSRC, "r")) == NULL)
  287. {
  288. perror(PSRC);
  289. exit(1);
  290. }
  291. if ((fpnroff = fopen(PNROFF, "w")) == NULL)
  292. {
  293. perror(PDAT);
  294. exit(1);
  295. }
  296. while (fgets(buf, sizeof(buf), fpsrc) != NULL)
  297. {
  298. src_line++;
  299. itmp = strlen(buf);
  300. buf[--itmp] = 0; /* kill trailing nl */
  301. if (buf[0] == '#') /* ignore comments */
  302. continue;
  303. if (buf[0] == '%') /* command indication */
  304. {
  305. SEARCH_CMD_LIST:
  306. if (!(this = search_cmd_list(&buf[1])))
  307. {
  308. #if 0 /* primarily because of 'eto' and 'fasi' */
  309. printf("line %d: '%s' not in command table\n",
  310. src_line, &buf[1]);
  311. #endif
  312. while (fgets(buf, sizeof(buf), fpsrc) != NULL)
  313. {
  314. src_line++;
  315. itmp = strlen(buf);
  316. buf[--itmp] = 0; /* kill trailing nl */
  317. if (buf[0] == '%') /* command indication */
  318. goto SEARCH_CMD_LIST;
  319. }
  320. break;
  321. }
  322. fputs("\n", fpnroff); /* terminate previous command description */
  323. start_pos[this->token] = ftell(fpnroff);
  324. token_line[this->token] = src_line;
  325. cptr = &buf[1]; /* command text */
  326. itmp = 0;
  327. this->proc = (PFI) 1; /* indicate we save command info */
  328. fputs(".SH ",fpnroff);
  329. while (*cptr) /* show cmd and min chars required */
  330. {
  331. if (itmp < this->min_ch)
  332. fputc(to_upper(*cptr++), fpnroff);
  333. else
  334. fputc(to_lower(*cptr++), fpnroff);
  335. itmp++;
  336. }
  337. if (*this->descr)/* if description present */
  338. fprintf(fpnroff, " : %s\n \n", this->descr);
  339. else
  340. fputs("\n \n", fpnroff);
  341. continue;
  342. }
  343. fprintf(fpnroff, "%s\n", buf);
  344. }
  345. fclose(fpsrc);
  346. fclose(fpnroff);
  347. /* say which commands weren't in the nroff source */
  348. this = icmd_cmds;
  349. while (this->token != -1)
  350. {
  351. if (this->min_ch && !this->proc)
  352. fprintf(stderr, "'%s' not in help source\n", this->cmd);
  353. this++;
  354. }
  355. } /* end of build_ecunroff */
  356. /*+-------------------------------------------------------------------------
  357. build_ecudoc()
  358. --------------------------------------------------------------------------*/
  359. void
  360. build_ecudoc()
  361. {
  362. register int itmp;
  363. printf("\nBuilding %s\n", PDOC);
  364. if ((fpdat = fopen(PDAT, "r")) == NULL)
  365. {
  366. perror(PDAT);
  367. exit(1);
  368. }
  369. if ((fpdoc = fopen(PDOC, "w")) == NULL)
  370. {
  371. perror(PDOC);
  372. exit(1);
  373. }
  374. fprintf(fpdoc,
  375. "\n ECU Command Help Documentation (PRELIMINARY)\n\n");
  376. fprintf(fpdoc,
  377. "Commands are accessed by pressing the HOME key followed by one\n");
  378. fprintf(fpdoc,
  379. "of the following commands (capitalized portions are sufficient\n");
  380. fprintf(fpdoc,
  381. "to invoke the command):\n");
  382. fprintf(fpdoc, "\n");
  383. fprintf(fpdoc,
  384. "---------------------------------------------------------------------\n");
  385. fread((char *)start_pos, sizeof(long), TOKEN_QUAN, fpdat);
  386. pcmd = icmd_cmds;
  387. while (pcmd->token != -1)
  388. {
  389. if (!pcmd->token)
  390. {
  391. pcmd++;
  392. continue;
  393. }
  394. if (pcmd->min_ch && !start_pos[pcmd->token])
  395. {
  396. printf("no help available for '%s'\n", pcmd->cmd);
  397. pcmd++;
  398. continue;
  399. }
  400. fseek(fpdat, start_pos[pcmd->token], 0);
  401. while (fgets(buf, sizeof(buf), fpdat) != NULL)
  402. {
  403. itmp = strlen(buf);
  404. buf[--itmp] = 0;
  405. if (itmp == 0)
  406. break;
  407. fprintf(fpdoc, "%s\n", buf);
  408. }
  409. fprintf(fpdoc,
  410. "---------------------------------------------------------------------\n");
  411. pcmd++;
  412. }
  413. fclose(fpdat);
  414. fclose(fpdoc);
  415. } /* end of build_ecudoc */
  416. /*+-------------------------------------------------------------------------
  417. test_help()
  418. --------------------------------------------------------------------------*/
  419. void
  420. test_help()
  421. {
  422. register int itmp;
  423. /* test code */
  424. printf("\nNow to test\n");
  425. if ((fpdat = fopen(PDAT, "r")) == NULL)
  426. {
  427. perror(PDAT);
  428. exit(1);
  429. }
  430. fread((char *)start_pos, sizeof(long), TOKEN_QUAN, fpdat);
  431. while (1)
  432. {
  433. printf("\ncommand: ");
  434. fgets(buf, sizeof(buf), stdin);
  435. itmp = strlen(buf);
  436. buf[--itmp] = 0;
  437. if (itmp == 0)
  438. break;
  439. if (!(pcmd = search_cmd_list(buf)))
  440. {
  441. printf("'%s' not found in ecu cmd table\n", buf);
  442. continue;
  443. }
  444. if (pcmd->min_ch && !start_pos[pcmd->token])
  445. {
  446. printf("no help available for '%s'\n", buf);
  447. continue;
  448. }
  449. fseek(fpdat, start_pos[pcmd->token], 0);
  450. while (fgets(buf, sizeof(buf), fpdat) != NULL)
  451. {
  452. itmp = strlen(buf);
  453. buf[--itmp] = 0;
  454. if (itmp == 0)
  455. break;
  456. printf("%s\n", buf);
  457. }
  458. }
  459. } /* end of test_help */
  460. /*+-------------------------------------------------------------------------
  461. main(argc,argv)
  462. --------------------------------------------------------------------------*/
  463. main(argc, argv)
  464. int argc;
  465. char **argv;
  466. {
  467. register int itmp;
  468. int iargv;
  469. int b_flag = 0;
  470. int d_flag = 0;
  471. int n_flag = 0;
  472. int s_flag = 0;
  473. int t_flag = 0;
  474. setbuf(stdout, NULL);
  475. setbuf(stderr, NULL);
  476. fprintf(stderr,"helpgen %s\n",rev);
  477. if (argc < 1)
  478. usage();
  479. for (iargv = 1; iargv < argc; iargv++)
  480. {
  481. if (argv[iargv][0] == '-')
  482. {
  483. switch (itmp = (argv[iargv][1]))
  484. {
  485. case 'b':
  486. b_flag = 1;
  487. break;
  488. case 's':
  489. s_flag = 1;
  490. break;
  491. case 'n':
  492. n_flag = 1;
  493. break;
  494. case 't':
  495. t_flag = 1;
  496. break;
  497. case 'd':
  498. d_flag = 1;
  499. break;
  500. default:
  501. usage();
  502. break;
  503. }
  504. }
  505. else
  506. usage();
  507. }
  508. if (!b_flag && !s_flag && !t_flag && !d_flag && !n_flag)
  509. usage();
  510. if (b_flag)
  511. build_ecuhelp();
  512. if (d_flag)
  513. build_ecudoc();
  514. if (n_flag)
  515. build_ecunroff();
  516. if (s_flag)
  517. show_cmds();
  518. if (t_flag)
  519. test_help();
  520. exit(0);
  521. } /* end of main */
  522. /* end of helpgen.c */
  523. /* vi: set tabstop=4 shiftwidth=4: */