Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1370 lines
31 KiB

  1. /*
  2. ventura.c - Module to output the data.
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <assert.h>
  9. #include "types.h"
  10. #include "docfmt.h"
  11. #include "text.h"
  12. #include "ventura.h"
  13. #include "process.h"
  14. #include "errstr.h"
  15. int VenLineOut(FILE * fpoutfile, char * pch, int wState);
  16. /* Formatting codes to output for ventura word formatting.
  17. */
  18. char *pchVenparm="<MI>";
  19. char *pchVenfunc="<B>";
  20. char *pchVenelem="<B>";
  21. char *pchVendefault="<D>";
  22. #define NUMFLAGTYPES 8
  23. #define REGISTERS 0
  24. #define REGRETURN 1
  25. #define REGCONDITION 2
  26. #define PARAMETERS 3
  27. #define PARAMRETURN 4
  28. #define FIELD1 5
  29. #define FIELD2 6
  30. #define FIELD3 7
  31. /* "output" modes for the line out routines. These
  32. * signify what sort of formatting should be done.
  33. */
  34. #define TEXT 0x0
  35. #define PARM 0x1
  36. #define FUNC 0x2
  37. #define STRUCT 0x3
  38. #define ELEMENT 0x4
  39. #define OLDSTYLE 0x80
  40. #define NEWSTYLE 0x40
  41. /*
  42. * @doc VENTURA
  43. * @api void | VenturaBlockOut | Central entry point for outputing a
  44. * Ventura format outerlevel block.
  45. *
  46. * @parm aBlock * | pBlock | Pointer to block structure.
  47. * @parm FILE * | ofile | Output file pointer.
  48. *
  49. * @comm Call this to get something output in ventura.
  50. *
  51. */
  52. void VenturaBlockOut( aBlock *pBlock, FILE *ofile)
  53. {
  54. VenfuncOut(pBlock, ofile);
  55. }
  56. /*************************************************************
  57. *
  58. * LINE OUT STUFF
  59. *
  60. *************************************************************/
  61. /* @doc INTERNAL
  62. *
  63. * @func void | VentextOut | This outputs the given text lines. Uses
  64. * <f VenLineOut> to expand formatting codes.
  65. *
  66. * @parm FILE * | file | Specifies the output file.
  67. * @parm aLine * | line | Specifies the text to output.
  68. *
  69. * @xref VenLineOut
  70. *
  71. */
  72. void VentextOut( FILE *file, aLine *line, BOOL fLineSeps )
  73. {
  74. int wMode = TEXT;
  75. for (; line != NULL; line = line->next) {
  76. wMode = VenLineOut( file, line->text, wMode );
  77. if (fLineSeps)
  78. fprintf(file, "\n");
  79. }
  80. if (wMode != TEXT) {
  81. fprintf(errfp, "Warning: Runaway formatting code with no close.\n");
  82. fprintf(file, "<D>"); // is this right?
  83. }
  84. }
  85. /* @doc INTERNAL
  86. *
  87. * @func void | VentextOutLnCol | This outputs the given text lines,
  88. * with each line separated by a newline. If a new paragraph occurs, it is
  89. * prefixed by the column prefix code <p pColHead>.
  90. *
  91. * @parm FILE * | file | Specifies the output file.
  92. * @parm aLine * | line | Specifies the text lines to output.
  93. * @parm char * | pColHead | Column header string to prefix new
  94. * paragraphs with.
  95. *
  96. * @comm Uses <f VenLineOut> to expand formatting codes.
  97. *
  98. * @xref VentextOut, VenLineOut
  99. *
  100. */
  101. void VentextOutLnCol( FILE *file, aLine *line, char *pColHead )
  102. {
  103. int wMode = TEXT;
  104. for (; line != NULL; line = line->next) {
  105. if (*(line->text) == '\0') {
  106. /* Print warning if a formatting code is being
  107. * continued across a para boundry.
  108. */
  109. if (wMode != TEXT) {
  110. fprintf(errfp, "Warning: formatting code"
  111. "crosses paragraph boundry.\n");
  112. }
  113. /* blank line, need new paragraph header */
  114. fprintf(file, "\n%s", pColHead);
  115. }
  116. else {
  117. /* Otherwise, normal line, print the line as usual */
  118. wMode = VenLineOut(file, line->text, wMode);
  119. fprintf(file, "\n");
  120. }
  121. }
  122. if (wMode != TEXT) {
  123. fprintf(errfp, "Warning: Runaway formatting code with no"
  124. "close before para end.\n");
  125. fprintf(file, "<D>\n"); // is this right?
  126. }
  127. }
  128. /*
  129. * @doc INTERNAL
  130. *
  131. * @func int | VenLineOut | Output the given text line, expanding any
  132. * character/word formatting control codes to the appropriate ventura
  133. * control codes.
  134. *
  135. * @parm FILE * | fpoutfile | Output file pointer.
  136. * @parm char * | line | Specifies the text to output.
  137. * @parm int | wState | Specifies the current line output
  138. * state, either TEXT, FUNC, STRUCTURE, or PARM. This value should initially
  139. * be TEXT.
  140. *
  141. * @rdesc Returns the line output state at the end of the text line.
  142. * This value should be passed to <f VenLineOut> on the next iteration
  143. * in order to continue the formatting code across a line break.
  144. *
  145. * @comm Reads and expands both old <p>foobar<d> style function
  146. * parameters and <p foobar> new-style parameters.
  147. *
  148. * This functions sends out character strings. Use <f VentextOut> and
  149. * <f VentextOut> for printing the aLine text storage data structures.
  150. *
  151. */
  152. int VenLineOut(FILE * fpoutfile, char * pch, int wState)
  153. {
  154. /*
  155. * <p> is parm
  156. * <f> is function
  157. * <t> is struct/union reference
  158. * <e> is structure element reference
  159. * <m> is message
  160. * <d> is return to default
  161. * <p foobar> is param
  162. * <f foobar> is function
  163. * <t foobar> is structure/union
  164. */
  165. BOOL iStyle;
  166. char chFormat;
  167. char *pchTemp;
  168. /* Loop over all chars on line */
  169. while(*pch) {
  170. /* Convert tabs into spaces. */
  171. if(*pch == '\t')
  172. *pch=' ';
  173. /* Skip non-printing chars */
  174. if (((*pch) & 0x80) || (*pch < ' ')) {
  175. pch++;
  176. continue;
  177. }
  178. /* Check and see if this is a formatting prefix character.
  179. */
  180. if (*pch == '<') {
  181. pch++;
  182. if (!*pch)
  183. /* Warning! Unexpected EOS */
  184. continue;
  185. chFormat = *pch;
  186. /* Move the character pointer to the characters following
  187. * the formatting, and determine the type of formatting code
  188. * in use, old or new style.
  189. */
  190. pch++; // skip the formatting character
  191. if (*pch == '>') {
  192. pch++;
  193. iStyle = OLDSTYLE;
  194. }
  195. else {
  196. /* For a new style formatting code, there must be
  197. * either a EOL or whitespace following the code
  198. * character. Make sure this is the case. If not,
  199. * then this isn't a formatting code, so
  200. * just print the characters out.
  201. */
  202. if (*pch && !isspace(*pch)) {
  203. fprintf(errfp,"Warning: New-style formatting "
  204. "code without whitespace.\nCode ignored but text printed.\n");
  205. /* Write out the characters, but
  206. * don't enter a formatting state.
  207. */
  208. putc('<', fpoutfile);
  209. putc(chFormat, fpoutfile);
  210. continue; // the while (*pch)
  211. }
  212. /* Otherwise, this a new style def. Suck
  213. * up any whitespace present.
  214. */
  215. iStyle = NEWSTYLE;
  216. /* Chew up whitespace */
  217. while (*pch && isspace(*pch))
  218. pch++;
  219. }
  220. /* Now I'm pointing to the start of the string
  221. * that the formatting should be applied to.
  222. * Check that a formatting code is not already
  223. * in effect, cancel it if so.
  224. */
  225. if (!(chFormat == 'd' || chFormat == 'D') && wState != TEXT) {
  226. fprintf(errfp, "Error: Nested formatting codes.\n");
  227. fprintf(fpoutfile, "<D>"); // HACK HACK!
  228. wState = TEXT;
  229. }
  230. /* Now setup the output state as appropriate, setting
  231. * the wState variable and outputting any leader chars
  232. * required.
  233. */
  234. switch (chFormat) {
  235. case 'P':
  236. case 'p':
  237. /* Parameter formatting. Output the
  238. * leader codes and setup wState.
  239. */
  240. wState = iStyle | PARM;
  241. fprintf(fpoutfile, pchVenparm);
  242. break;
  243. case 'E':
  244. case 'e':
  245. /* Data structure element formatting. Output the
  246. * leader codes and setup wState.
  247. */
  248. wState = iStyle | ELEMENT;
  249. fprintf(fpoutfile, pchVenelem);
  250. /* Skip over the structure notation (struct.element).
  251. */
  252. pchTemp = pch;
  253. while (*pchTemp++ != '>') {
  254. if (*pchTemp == '.')
  255. pch = ++pchTemp;
  256. }
  257. break;
  258. case 'F':
  259. case 'f':
  260. /* Function formatting. Output & setup state */
  261. wState = iStyle | FUNC;
  262. fprintf(fpoutfile, pchVenfunc);
  263. break;
  264. case 'D':
  265. case 'd':
  266. if (iStyle == NEWSTYLE) {
  267. fprintf(errfp,"Error: <d foobar> encountered."
  268. " <d> is the only valid use for <d>.\n");
  269. /* Here, just print the <d_ anyway. Then
  270. * set no mode, continue.
  271. */
  272. fprintf(fpoutfile, "<d ");
  273. }
  274. else {
  275. /* Oldstyle end of formatting encountered.
  276. * Cancel the current mode, output
  277. * a return-to-normal code (ventura is nice
  278. * for this one thing, being consistent in
  279. * what constitues return-to-normal!)
  280. */
  281. wState = TEXT; // reset mode
  282. fprintf(fpoutfile, "<D>");
  283. }
  284. break;
  285. case 'T':
  286. case 't':
  287. case 'M':
  288. case 'm':
  289. /* Structure definition */
  290. wState = iStyle | STRUCT;
  291. fprintf(fpoutfile, pchVenfunc);
  292. break;
  293. default:
  294. /* Unrecognized code. Barf.
  295. */
  296. fprintf(errfp, "Error: unrecognized"
  297. " formatting code.\n");
  298. /* Simulate the output and set no mode */
  299. if (iStyle == NEWSTYLE)
  300. fprintf(fpoutfile, "<%c ", chFormat);
  301. else
  302. fprintf(fpoutfile, "<%c>", chFormat);
  303. break;
  304. } // switch for '<' formating codes
  305. } // if *pch == '<'
  306. /* If the character is a new-style close end formatting
  307. * indicator, clear the current mode to text and send out the
  308. * the ventura return-to-default code.
  309. *
  310. * If there is no current mode, then just output the chracter?
  311. */
  312. else if (*pch == '>') {
  313. if (wState != TEXT) {
  314. if (wState & OLDSTYLE) {
  315. fprintf(errfp, "Warning: new style close in "
  316. "oldstyle formatting.\nIgnoring close, writing char.\n");
  317. putc(*pch, fpoutfile);
  318. }
  319. else {
  320. /* Cancel the current mode */
  321. fprintf(fpoutfile, "<D>");
  322. wState = TEXT;
  323. }
  324. }
  325. else {
  326. fprintf(errfp, "Warning: Standalone '>' "
  327. "encountered.\n");
  328. putc(*pch, fpoutfile);
  329. }
  330. pch++; // skip the '>'
  331. }
  332. else {
  333. /* Just print the character */
  334. putc(*pch, fpoutfile);
  335. pch++;
  336. }
  337. } // while (*pch);
  338. /* We're done! Return the current output state */
  339. return wState;
  340. }
  341. /****************************************************
  342. *
  343. * XREFS
  344. *
  345. ****************************************************/
  346. /*
  347. * @doc INTERNAL
  348. * @func void | VenDoXrefs | Process and print the cross reference
  349. * list for a function or message block.
  350. *
  351. * @parm FILE * | file | Specifies the output file.
  352. * @parm aLine * | line | The line of cross references to print.
  353. *
  354. */
  355. void VenDoXrefs( FILE *file, aLine *line)
  356. {
  357. char ach[80];
  358. int i;
  359. char *p;
  360. if (line == NULL) {
  361. fprintf(errfp, "NULL line passed to VenDoXrefs\n");
  362. return;
  363. }
  364. /* Header line */
  365. fprintf( file, "@HO = See Also\n\n" );
  366. while (line != NULL) {
  367. /* skip whitespace */
  368. for (p = line->text; isspace(*p); p++);
  369. while (*p) {
  370. i = 0;
  371. while (*p && !(*p == ',' || isspace(*p)))
  372. ach[i++] = *p++;
  373. if (i > 0) {
  374. ach[i] = '\0';
  375. fprintf(file, "%s", ach);
  376. }
  377. while (*p && (*p == ',' || isspace(*p)))
  378. p++;
  379. if (*p)
  380. fprintf(file, ", ");
  381. } /* while *p */
  382. fprintf(file, "\n");
  383. line = line->next;
  384. if (line)
  385. fprintf(file, " ");
  386. } /* while line != NULL */
  387. fprintf(file, "\n");
  388. }
  389. /****************************************************
  390. *
  391. * FLAGS
  392. *
  393. ****************************************************/
  394. /*
  395. * @doc INTERNAL
  396. *
  397. * @func void | VenDoFlagList | Print the flag list of a parameter,
  398. * register, or return description.
  399. *
  400. * @parm aFlag * | flag | Pointer to flag list to be printed.
  401. *
  402. * @parm FILE * | file | Specifies the file to print to.
  403. *
  404. * @parm WORD | wType | This parameter may be one of the following,
  405. * depending on the type of flag list being produced:
  406. *
  407. * @flag REGISTERS | This is a normal input register declaration, below
  408. * a ASM or ASM callback function declaration.
  409. * @flag REGRETURN | This is a register return declaration beneath
  410. * a return description. This is not part of a conditional
  411. * block.
  412. * @flag REGCONDITION | This is a register return declaration beneath
  413. * a return conditional block.
  414. * @flag PARAMETERS | This is a normal parameter declaration beneath
  415. * an API, or API Callback function or Message declaration.
  416. * @flag PARAMRETURN | This is a return flag list declaration beneath
  417. * a return block in an API or API callback, or a Message return.
  418. */
  419. void VenDoFlagList( aFlag *flag, FILE *file, int wType )
  420. {
  421. static char *aszFlagNameOut[NUMFLAGTYPES] = {
  422. "@RFLAG = ", // registers
  423. "@RFLAG = ", // reg return
  424. "@RFLAG = ", // reg condition return
  425. "@FLAG = ", // param flag
  426. "@PARM = ", // param return
  427. "@FLAG = ", // level 1 field
  428. "@L2FLAG = ", // level 2 field
  429. "@L3FLAG = ", // level 3 field
  430. };
  431. static char *aszFlagDescOut[NUMFLAGTYPES] = {
  432. "@RFLDESC = ", // registers
  433. "@RFLDESC = ", // reg return
  434. "@RFLDESC = ", // reg condition return
  435. "@FLDESC = ", // param flag
  436. "@PDESC = ", // param return
  437. "@FLDESC = ", // level 1 field
  438. "@L2FLDESC = ", // level 2 field
  439. "@L3FLDESC = ", // level 3 field
  440. };
  441. if (!flag) {
  442. fprintf(errfp, "Warning: NULL Flag sent to VenDoFlaglist\n");
  443. return;
  444. }
  445. assert(wType < NUMFLAGTYPES);
  446. /* loop over the flag list */
  447. for ( ; flag != NULL; flag = flag->next) {
  448. /* Do flag name */
  449. fprintf(file, aszFlagNameOut[wType]);
  450. VentextOut( file, flag->name, FALSE );
  451. fprintf( file, "\n\n" );
  452. /* Do the description */
  453. fprintf(file, aszFlagDescOut[wType]);
  454. VentextOutLnCol(file, flag->desc, aszFlagNameOut[wType]);
  455. fprintf( file, "\n" );
  456. } // for flag list
  457. }
  458. /****************************************************
  459. *
  460. * PARMS
  461. *
  462. ****************************************************/
  463. /*
  464. * @doc INTERNAL
  465. * @func void | VenDoParmList | Print the parameter list of a function
  466. * block.
  467. *
  468. * @parm aBlock * | pBlock | Specifies the enclosing block of the
  469. * parameter list.
  470. * @parm aParm * | parm | The parameter list to print.
  471. * @parm FILE * | file | Specifies the file to use for output.
  472. *
  473. * @comm Prints the given parameter list. If parameters within the
  474. * list contain a flag list, the flag list is printed using
  475. * <f VenDoFlagList>.
  476. *
  477. * @xref VenDoFlagList
  478. *
  479. */
  480. void VenDoParmList( aBlock *pBlock, aParm *parm, FILE *file )
  481. {
  482. if (!parm) {
  483. fprintf(file, "None\n\n");
  484. }
  485. else {
  486. /* Loop over the parameter list of the message */
  487. for (; parm != NULL; parm = parm->next) {
  488. /* Print first col, param type and name */
  489. fprintf( file, "@PARM = " );
  490. VentextOut( file, parm->type, FALSE );
  491. fprintf( file, "<_><MI>");
  492. VentextOut( file, parm->name, FALSE );
  493. fprintf( file, "<D>\n\n" );
  494. /* Do second column, the description */
  495. fprintf( file, "@PDESC = " );
  496. VentextOutLnCol( file, parm->desc, "@PDESC = ");
  497. // VentextOutLnCol( file, parm->desc, "@PDESC");
  498. fprintf( file, "\n" );
  499. /* Print the parameter's flags, if any */
  500. if (parm->flag != NULL) {
  501. VenDoFlagList(parm->flag, file, PARAMETERS);
  502. }
  503. } // for parm list
  504. }
  505. /* Close off the parameter list */
  506. fprintf(file, "@LE = \n\n");
  507. }
  508. /****************************************************
  509. *
  510. * REGS AND CONDITIONALS
  511. *
  512. ****************************************************/
  513. /*
  514. * @doc INTERNAL
  515. * @func void | VenDoRegList | Print a register list.
  516. *
  517. * @parm aBlock * | pBlock | Specifies the enclosing block of the
  518. * parameter list.
  519. * @parm aReg * | reg | The register list to print.
  520. * @parm FILE * | file | Specifies the file to use for output.
  521. *
  522. * @parm WORD | wType | This parameter may be one of the following,
  523. * depending on the type of register list being produced:
  524. *
  525. * @flag REGISTERS | This is a normal input register declaration, below
  526. * a ASM or ASM callback function declaration.
  527. * @flag REGRETURN | This is a register return declaration beneath
  528. * a return description. This is not part of a conditional
  529. * block.
  530. * @flag REGCONDITION | This is a register return declaration beneath
  531. * a return conditional block.
  532. *
  533. * @comm Prints the given register list. If registers within the
  534. * list contain a flag list, the flag list is printed using
  535. * <f VenDoFlagList>.
  536. *
  537. * @xref VenDoFlagList
  538. *
  539. */
  540. void VenDoRegList( aBlock *pBlock, aReg *reg, FILE *file, int wType)
  541. {
  542. static char *aszRegNameOut[] = {
  543. "@RNAME = ", // registers
  544. "@RNAME = ", // reg return
  545. "@RNAME = ", // reg condition return
  546. };
  547. static char *aszRegDescOut[] = {
  548. "@RDESC = ", // registers
  549. "@RDESC = ", // reg return
  550. "@RDESC = ", // reg condition return
  551. };
  552. assert(wType == REGISTERS || wType == REGRETURN || wType == REGCONDITION);
  553. if (reg == NULL) {
  554. fprintf(file, "None\n\n");
  555. }
  556. else {
  557. /* Loop over the register list of the message */
  558. for (; reg != NULL; reg = reg->next) {
  559. /* Print first col, reg name */
  560. fprintf( file, aszRegNameOut[wType]);
  561. /* Print the register name */
  562. fprintf( file, "<B>" );
  563. VentextOut( file, reg->name, FALSE );
  564. fprintf( file, "<D>\n\n" );
  565. /* Do second column, the description */
  566. fprintf( file, aszRegDescOut[wType] );
  567. VentextOutLnCol( file, reg->desc, aszRegDescOut[wType] );
  568. fprintf( file, "\n" );
  569. /* Print the parameter's flags, if any */
  570. if (reg->flag != NULL) {
  571. VenDoFlagList(reg->flag, file, wType);
  572. }
  573. } // for reg list
  574. }
  575. fprintf(file, "@LE = \n\n");
  576. }
  577. /*
  578. * @doc INTERNAL
  579. *
  580. * @func void | VenDoCondList | Print a conditional register list.
  581. *
  582. * @parm aBlock * | pBlock | Specifies the enclosing block of the
  583. * register list.
  584. *
  585. * @parm aCond * | cond | The conditional list to print.
  586. *
  587. * @parm FILE * | file | Specifies the file to use for output.
  588. *
  589. * @comm Prints the given conditional list. For each conditional
  590. * block, the text is printed, followed by the the list of registers
  591. * (and their associated tags) for the conditional block.
  592. *
  593. * @xref VenDoRegList, VenDoFlagList
  594. *
  595. */
  596. void VenDoCondList( aBlock *pBlock, aCond *cond, FILE *file)
  597. {
  598. assert(cond != NULL);
  599. /* Loop over the register list of the message */
  600. for (; cond != NULL; cond = cond->next) {
  601. /* Print out the conditional tag text.. */
  602. fprintf( file, "@COND = ");
  603. VentextOutLnCol(file, cond->desc, "@COND = ");
  604. fprintf( file, "\n");
  605. /* Now print the conditional's registers (and subseqent flags) */
  606. VenDoRegList(pBlock, cond->regs, file, REGCONDITION);
  607. } // for conditional list
  608. fprintf(file, "@LE = \n\n");
  609. }
  610. /*******************************************************
  611. *
  612. * STRUCTS
  613. *
  614. *******************************************************/
  615. /*
  616. * VenPrintFieldText(aType *type, FILE *file)
  617. *
  618. * Prints the text of a field for a structure courier dump. This proc
  619. * only prints the name and type of structure fields at the appropriate
  620. * indent levels.
  621. *
  622. */
  623. void VenPrintFieldText(aType *type, FILE *file)
  624. {
  625. int i;
  626. for (i = type->level + 1; i > 0; i--)
  627. fprintf(file, " ");
  628. VentextOut(file, type->type, FALSE);
  629. fprintf(file, " ");
  630. VentextOut(file, type->name, FALSE);
  631. fprintf(file, ";<R>\n");
  632. /* Flags? */
  633. }
  634. /*
  635. * VenPrintSubstructText(aSU *su, file, wType)
  636. *
  637. * Prints a courier dump of a sub-structure or sub-union at the
  638. * appropriate indent level. Does not print any description text.
  639. *
  640. * wType must indicate whether this is a union or structure, being
  641. * either FIELD_STRUCT or FIELD_UNION.
  642. *
  643. */
  644. void VenPrintSubstructText(aSU *su, FILE *file, int wType)
  645. {
  646. int i;
  647. aField *field;
  648. /* Do struct/union and brace of sub-structure */
  649. for (i = su->level; i > 0; i--)
  650. fprintf(file, " ");
  651. fprintf(file, "%s {<R>\n", wType == FIELD_STRUCT ? "struct" : "union");
  652. field = su->field;
  653. if (field) {
  654. while (field) {
  655. switch (field->wType) {
  656. case FIELD_TYPE:
  657. VenPrintFieldText((aType *) field->ptr, file);
  658. break;
  659. case FIELD_STRUCT:
  660. case FIELD_UNION:
  661. VenPrintSubstructText((aSU *) field->ptr,
  662. file, field->wType);
  663. break;
  664. }
  665. field = field->next;
  666. }
  667. }
  668. /* Do closing brace and title of sub-structure */
  669. for (i = su->level; i > 0; i--)
  670. fprintf(file, " ");
  671. fprintf(file, "} %s;<R>\n", su->name->text);
  672. }
  673. /*
  674. * VenPrintStructText(pBlock, file, wType)
  675. *
  676. * Prints a courier dump of the text of a structure/union outerlevel
  677. * block. Does not print any description fields or flags.
  678. *
  679. * wType indicates whether the block is a structure or union, either
  680. * FIELD_STRUCT or FIELD_UNION.
  681. *
  682. */
  683. void VenPrintStructText(aBlock *pBlock, FILE *file)
  684. {
  685. aField *curf;
  686. aLine *tag;
  687. curf = pBlock->field;
  688. tag = pBlock->tagname;
  689. fprintf(file, "@EX = typedef %s ",
  690. pBlock->blockType == STRUCTBLOCK ? "struct" : "union");
  691. if (tag)
  692. fprintf(file, "%s ", tag->text);
  693. fprintf(file, "{<R>\n");
  694. while (curf) {
  695. switch (curf->wType) {
  696. case FIELD_TYPE:
  697. VenPrintFieldText((aType *) curf->ptr, file);
  698. break;
  699. case FIELD_STRUCT:
  700. case FIELD_UNION:
  701. VenPrintSubstructText((aSU *) curf->ptr, file, curf->wType);
  702. break;
  703. default:
  704. assert(FALSE);
  705. break;
  706. }
  707. curf = curf->next;
  708. }
  709. fprintf(file, "} %s;\n\n", pBlock->name->text);
  710. /* Now print out the othernames? */
  711. }
  712. /********* DESCRIPTION DUMPS ************/
  713. #define NUMFIELDLEVELS 3
  714. char *aachFieldNameTags[NUMFIELDLEVELS] = {
  715. "@PARM = ", "@L2PARM = ", "@L3PARM = "
  716. };
  717. char *aachFieldDescTags[NUMFIELDLEVELS] = {
  718. "@PDESC = ", "@L2PDESC = ", "@L3PDESC = "
  719. };
  720. int aiFlagTypes[NUMFIELDLEVELS] = { FIELD1, FIELD2, FIELD3 };
  721. /*
  722. * @doc INTERNAL
  723. *
  724. * @api void | VenPrintFieldDesc | This function prints the
  725. * descriptions of a field entry in a structure. The printout is done
  726. * using the standard @parm tags (and associated flag tags).
  727. *
  728. * @parm aType * | type | Points to a type structure which contains
  729. * the field information.
  730. *
  731. * @parm FILE * | file | Specifies the output file.
  732. *
  733. * @comm Use this function to output the names/descriptions of fields.
  734. * Use <f VenPrintFieldText> to output a similated text dump of the
  735. * structure definition.
  736. *
  737. * Note that the use of this function requires an @LE tag be output when
  738. * the list of parameters has been ended.
  739. *
  740. */
  741. void VenPrintFieldDesc(aType *type, FILE *file)
  742. {
  743. int level;
  744. level = type->level;
  745. if (level >= NUMFIELDLEVELS)
  746. level = NUMFIELDLEVELS - 1;
  747. /* Print the field type and name in the first column, formatted */
  748. fprintf(file, "%s<B>", aachFieldNameTags[level]);
  749. VentextOut(file, type->name, FALSE);
  750. fprintf(file, "<D>\n\n");
  751. #if 0
  752. /* Print parameter type above? */
  753. fprintf(file, "<_><MI>");
  754. VentextOut(file, type->name, FALSE);
  755. fprintf(file, "\n\n");
  756. #endif
  757. /* Do the second column, description text */
  758. fprintf(file, aachFieldDescTags[level]);
  759. VentextOutLnCol(file, type->desc, aachFieldDescTags[level]);
  760. putc('\n', file);
  761. /* Do the flag list, if any */
  762. if (type->flag != NULL) {
  763. VenDoFlagList(type->flag, file, aiFlagTypes[level]);
  764. }
  765. /* Now, somewhere, a @LE = needs to be output! */
  766. }
  767. void VenPrintSubstructDesc(aSU *su, FILE *file, int wType)
  768. {
  769. aField *field;
  770. int level;
  771. int levelStruct;
  772. /* Limit level to the number of nesting levels supported by Ventura */
  773. level = min(NUMFIELDLEVELS - 1, su->level);
  774. levelStruct = level - 1;
  775. /* For the sub-structure, print out a little blurb for
  776. * the sub-structure/union itself, as well as the optional
  777. * description text that may come with a sub-structure.
  778. */
  779. fprintf(file, aachFieldNameTags[levelStruct]);
  780. fprintf(file, "<B>%s<D>\n\n", su->name->text);
  781. if (su->desc) {
  782. fprintf(file, aachFieldDescTags[levelStruct]);
  783. VentextOutLnCol(file, su->desc, aachFieldDescTags[levelStruct]);
  784. putc('\n', file);
  785. }
  786. /* Now print the sub-fields */
  787. fprintf(file, aachFieldDescTags[levelStruct]);
  788. fprintf(file, "The following sub-fields are contained in %s <B>%s<D>:\n\n",
  789. wType == FIELD_STRUCT ? "structure" : "union",
  790. su->name->text);
  791. /* Now do each field of the sub-structure */
  792. field = su->field;
  793. if (field) {
  794. while (field) {
  795. switch (field->wType) {
  796. case FIELD_TYPE:
  797. VenPrintFieldDesc((aType *) field->ptr, file);
  798. break;
  799. case FIELD_STRUCT:
  800. case FIELD_UNION:
  801. VenPrintSubstructDesc((aSU *) field->ptr,
  802. file, field->wType);
  803. break;
  804. }
  805. field = field->next;
  806. }
  807. }
  808. /* Print a closing blurb */
  809. fprintf(file, aachFieldNameTags[levelStruct]);
  810. fprintf(file, "End of sub-fields for %s %s.\n\n",
  811. wType == FIELD_STRUCT ? "structure" : "union", su->name->text);
  812. }
  813. void VenDoStructDescriptions(aBlock *pBlock, FILE *file)
  814. {
  815. aField *cur;
  816. /* Look through the field list, printing each field as it is
  817. * encountered using @parm tags...
  818. */
  819. fprintf(file, "@HO = Fields\n\n");
  820. fprintf(file, "The <b>%s<d> %s has the following fields:\n\n",
  821. pBlock->name->text,
  822. pBlock->blockType == STRUCTBLOCK ? "structure" : "union");
  823. /* Dump the structure */
  824. cur = pBlock->field;
  825. if (cur == NULL) {
  826. fprintf(file, "None\n\n");
  827. return;
  828. }
  829. while (cur) {
  830. switch (cur->wType) {
  831. case FIELD_TYPE:
  832. VenPrintFieldDesc((aType *) cur->ptr, file);
  833. break;
  834. case FIELD_STRUCT:
  835. case FIELD_UNION:
  836. VenPrintSubstructDesc((aSU *) cur->ptr, file, cur->wType);
  837. break;
  838. default:
  839. assert(FALSE);
  840. break;
  841. }
  842. cur = cur->next;
  843. }
  844. /* Close off the param list */
  845. fprintf(file, "@LE = \n\n");
  846. /* Print out othertypes? */
  847. }
  848. /*********************************************************
  849. *
  850. * DOC BLOCK
  851. *
  852. *********************************************************/
  853. /*
  854. * @doc INTERNAL
  855. * @func void | VenfuncOut | This outputs the function information.
  856. *
  857. * @parm aBlock * | func | Specifies a pointer to the function
  858. * information. The type of the block is determined by looking at the
  859. * blocktype field.
  860. *
  861. * @parm FILE * | file | Specifies the output file.
  862. *
  863. * @comm This function may be called recursively to deal with callback
  864. * procedures. It handles most anything.
  865. *
  866. */
  867. void VenfuncOut( aBlock *func, FILE *file )
  868. {
  869. aParm *parm;
  870. aBlock *pCb;
  871. int type;
  872. /* Pointer to tag header type - depends on block type */
  873. char *pIntHeader;
  874. static char achCbHeader[] = "@HU =";
  875. static char achFuncHeader[] = "@HO =";
  876. if( func == NULL || file == NULL) {
  877. fprintf(errfp, "Bogus params to VenFuncOut!\n");
  878. return;
  879. }
  880. /* Get the blocktype for this block, do different things according to
  881. * type.
  882. */
  883. type = func->blockType;
  884. /*
  885. * DO THE BLOCK HEADER
  886. */
  887. switch (type) {
  888. case FUNCTION:
  889. /* use interior headers of normal level */
  890. pIntHeader = achFuncHeader;
  891. /* Block header */
  892. fprintf(file, "@HR = ");
  893. VentextOut(file, func->name, FALSE);
  894. fprintf(file, "\n\n");
  895. /* Setup API description */
  896. fprintf( file, "@HO = Syntax\n\n" );
  897. VentextOut( file, func->type, FALSE );
  898. fprintf( file, "<_><B>" );
  899. VentextOut( file, func->name, FALSE );
  900. fprintf( file, "<D>" );
  901. DoFunctionBlockHeader:
  902. /* Print the function header line, with parameters */
  903. fprintf(file, "(");
  904. for (parm = func->parm; parm != NULL; ) {
  905. fprintf(file, "<MI>");
  906. VentextOut(file, parm->name, FALSE);
  907. fprintf(file, "<D>");
  908. /* Advance */
  909. parm = parm->next;
  910. if (parm != NULL)
  911. fprintf(file, ", ");
  912. }
  913. fprintf(file, ")\n\n");
  914. // fprintf(file, "\n\n");
  915. break;
  916. case CALLBACK:
  917. /* Use callback interior header styles */
  918. pIntHeader = achCbHeader;
  919. /* Print function header setup */
  920. fprintf(file, "@HO = Callback\n\n");
  921. VentextOut(file, func->type, FALSE);
  922. fprintf(file, "<_><B>");
  923. VentextOut(file, func->name, FALSE);
  924. fprintf(file, "<D>");
  925. /* Get the parameter list done the same way as with a normal
  926. * function. Cheat by using a goto to the above code.
  927. */
  928. goto DoFunctionBlockHeader;
  929. break;
  930. case MESSAGE:
  931. pIntHeader = achFuncHeader;
  932. /* Print message header setup */
  933. fprintf(file, "@HR = ");
  934. VentextOut(file, func->name, FALSE);
  935. fprintf(file, "\n\n");
  936. // fprintf(file, "@HO = Description\n\n");
  937. break;
  938. case MASMBLOCK:
  939. pIntHeader = achFuncHeader;
  940. /* Print MASM block header setup */
  941. fprintf(file, "@HR = ");
  942. VentextOut(file, func->name, FALSE);
  943. fprintf(file, "\n\n");
  944. break;
  945. case MASMCBBLOCK:
  946. pIntHeader = achCbHeader;
  947. /* Print MASM block header setup */
  948. fprintf(file, "@HO = Callback\n\n");
  949. /* BOLD THE CALLBACK NAME? */
  950. fprintf(file, "<B>");
  951. VentextOut(file, func->name, FALSE);
  952. fprintf(file, "<D>\n\n");
  953. break;
  954. case STRUCTBLOCK:
  955. case UNIONBLOCK:
  956. pIntHeader = achFuncHeader;
  957. /* Print message header setup */
  958. fprintf(file, "@HR = ");
  959. VentextOut(file, func->name, FALSE);
  960. fprintf(file, "\n\n");
  961. // fprintf(file, "@HO = Description\n\n");
  962. break;
  963. // case UNIONBLOCK:
  964. // break;
  965. default:
  966. fprintf(errfp, "Ventura: Unknown block type\n");
  967. return;
  968. } // switch type
  969. /*
  970. * DO DESCRIPTION
  971. */
  972. if (func->desc != NULL) {
  973. VentextOut( file, func->desc, TRUE );
  974. fprintf( file, "\n" );
  975. }
  976. /*
  977. * DO STRUCTURE/UNION FIELDS
  978. */
  979. if (func->field != NULL) {
  980. /* Print structure dump in courier */
  981. VenPrintStructText(func, file);
  982. /* Print out the fields with descriptions & flags in table
  983. * format.
  984. */
  985. VenDoStructDescriptions(func, file);
  986. }
  987. if (func->other) {
  988. /* RTFOtherOut(file, func->other);
  989. */
  990. }
  991. /*
  992. * DO PARAMETER OR REGISTER LISTS
  993. */
  994. switch (type) {
  995. case FUNCTION:
  996. case CALLBACK:
  997. case MESSAGE:
  998. fprintf(file, "%s Parameters\n\n", pIntHeader);
  999. VenDoParmList(func, func->parm, file);
  1000. assert(func->reg == NULL);
  1001. break;
  1002. case MASMBLOCK:
  1003. case MASMCBBLOCK:
  1004. fprintf(file, "%s Registers\n\n", pIntHeader);
  1005. /* Print the register list in input register declaration format */
  1006. VenDoRegList(func, func->reg, file, REGISTERS);
  1007. assert(func->parm == NULL);
  1008. break;
  1009. }
  1010. /*
  1011. * DO RETURN DESCRIPTION
  1012. */
  1013. if( func->rtndesc != NULL ) {
  1014. fprintf( file, "%s Return Value\n\n", pIntHeader );
  1015. /* Print the return description text */
  1016. VentextOut(file, func->rtndesc, TRUE);
  1017. fprintf(file, "\n");
  1018. switch (type) {
  1019. case MESSAGE:
  1020. case FUNCTION:
  1021. case CALLBACK:
  1022. if (func->rtnflag != NULL) {
  1023. VenDoFlagList(func->rtnflag, file, PARAMRETURN);
  1024. fprintf(file, "@LE = \n\n");
  1025. }
  1026. break;
  1027. case MASMBLOCK:
  1028. case MASMCBBLOCK:
  1029. /* Process any available register tags */
  1030. if (func->rtnreg != NULL) {
  1031. VenDoRegList(func, func->rtnreg, file, REGRETURN);
  1032. }
  1033. /* Now do the conditional list */
  1034. if (func->cond != NULL) {
  1035. VenDoCondList(func, func->cond, file);
  1036. }
  1037. break;
  1038. default:
  1039. assert(0);
  1040. break;
  1041. } // switch
  1042. }
  1043. /*
  1044. * DO USES TAG
  1045. */
  1046. if (func->uses != NULL) {
  1047. fprintf(file, "%s Uses\n\n", pIntHeader);
  1048. VentextOut(file, func->uses, TRUE);
  1049. fprintf(file, "\n@LE = \n\n");
  1050. }
  1051. /*
  1052. * DO COMMENT BLOCK
  1053. */
  1054. if( func->comment != NULL ) {
  1055. fprintf( file, "%s Comments\n\n", pIntHeader );
  1056. VentextOut( file, func->comment, TRUE );
  1057. fprintf( file, "\n" );
  1058. }
  1059. /*
  1060. * DO ANY CALLBACKS
  1061. */
  1062. for (pCb = func->cb; pCb != NULL; pCb = pCb->next) {
  1063. VenfuncOut( pCb, file );
  1064. }
  1065. /*
  1066. * DO CROSS REFERENCES
  1067. */
  1068. if (func->xref != NULL) {
  1069. VenDoXrefs(file, func->xref);
  1070. }
  1071. /* Done. Whew! */
  1072. }
  1073. /****************************************************
  1074. *
  1075. * RANDOM STUFF TO SUPPORT RTF FILES
  1076. *
  1077. ****************************************************/
  1078. void
  1079. VenFileInit(FILE * phoutfile, logentry *curlog)
  1080. {
  1081. return;
  1082. }
  1083. void
  1084. VenFileProcess(FILE * phoutfile, files curfile)
  1085. {
  1086. copyfile(phoutfile,curfile->filename);
  1087. return;
  1088. }
  1089. void
  1090. VenFileDone(FILE * phoutfile, files headfile)
  1091. {
  1092. return;
  1093. }
  1094. void
  1095. VenLogInit(FILE * phoutfile, logentry * * pheadlog)
  1096. {
  1097. return;
  1098. }
  1099. void
  1100. VenLogProcess(FILE * phoutfile, logentry * curlog)
  1101. {
  1102. return;
  1103. }
  1104. void
  1105. VenLogDone(FILE * phoutfile, logentry * headlog)
  1106. {
  1107. return;
  1108. }