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.

2203 lines
47 KiB

  1. /*
  2. RTF.c Output file to generate RTF for Windows 3.0 help system
  3. 10-06-1989 Matt Saettler
  4. ...
  5. 10-11-1989 MHS Block output instead of specific output
  6. ...
  7. 10-15-1989 MHS Autodoc
  8. 10-16-1989 MHS Added support for rtnregs
  9. 01-24-1990 MHS Added support for masm Callbacks
  10. 01-31-1990 MHS Added support for conditionals
  11. 03-12-1990 MHS added support for Structs/Unions
  12. Copyright 1989, 1990 Microsoft Corp. All Rights Reserved.
  13. */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <assert.h>
  19. #include "types.h"
  20. #include "docfmt.h"
  21. #include "process.h"
  22. #include "RTF.h"
  23. #include "errstr.h"
  24. #include "misc.h"
  25. #include "head.h"
  26. #include "tail.h"
  27. #define FUNCHELP 1
  28. #define MSGHELP 2
  29. #define CBHELP 3
  30. #define FUNCDOC 4
  31. #define MSGDOC 5
  32. #define CBDOC 6
  33. #define INTDOC 7
  34. #define INTHELP 8
  35. #define MASMDOC 9
  36. #define MASMHELP 10
  37. #define MASMCBDOC CBDOC // HACK HACK
  38. #define MASMCBHELP CBHELP // PRETEND it is just another CB
  39. #define STRUCTHELP 11
  40. #define STRUCTDOC 12
  41. #define UNIONHELP 13
  42. #define UNIONDOC 14
  43. void RTFLineOut(FILE * fpoutfile, char * pch);
  44. void RTFGenIndex(FILE * file, files curfile);
  45. void RTFParmOut(FILE *file, aParm *pparm, int hselect);
  46. void copylines(FILE * phoutfile, char **lines);
  47. void RTFRegOut(FILE *file, aReg *reg, int hselect);
  48. void RTFFieldOut(FILE *file, aBlock *pBlock, int hselect);
  49. void RTFOtherOut(FILE *file, aOther *other, int hselect);
  50. void RTFCondOut(FILE *file, aCond *cond, int hselect);
  51. void RTFSUOut1(FILE *file, aSU *SU, int hselect, int wType);
  52. void RTFTypeOut1(FILE *file, aType *type, int hselect);
  53. void RTFsubFieldOut1(FILE *file, aField *field , int hselect);
  54. void RTFSUOut2(FILE *file, aSU *SU, int hselect, int wType);
  55. void RTFTypeOut2(FILE *file, aType *type, int hselect);
  56. void RTFsubFieldOut2(FILE *file, aField *field , int hselect);
  57. void RTFDoneText( FILE *fpoutfile );
  58. #define FLAGRTN 1
  59. #define FLAGPARM 2
  60. #define FLAGREG 3
  61. void RTFFlagOut(FILE *file, aFlag *flag, int hselect, int flags);
  62. void RTFDumpParms(FILE *file, aBlock *pBlock, int hselect);
  63. void RTFDumpLevel(FILE *file, aLine *pLine, int hselect);
  64. void RTFDumpX(FILE *file, char *ach);
  65. int fSubBlock=0;
  66. char *pchparm="<p>"; // 'old' style attributes
  67. char *pchfunc="<f>";
  68. char *pchdefault="<d>";
  69. char *pchrtfparm="{\\i "; // attributes for parameter
  70. char *pchrtffunc="{\\b "; // attributes for function
  71. char *pchrtftype="{\\b "; // attributes for type
  72. char *pchrtfmsg ="{ "; // attributes for message
  73. char *pchrtfelem="{\\b "; // attributes for element
  74. char *pchrtfnone ="{ "; // attributes for unknown style
  75. char *pchrtfdefault="}"; // how to restore to default attributes
  76. int blocksprocessed=0;
  77. char *flagdoc ="\\par\n\\pard\\%s\\f26\\fs20\\li%d\\sa60\\sb60\\sl0\\fi%d\\tx5760\\tx6480\n";
  78. char *sepsynhelp="\\tab\n";
  79. char *sepsyndoc ="\\tab\n";
  80. char *synhelp="\\pard\\plain\\f26\\fs20\\fi-1440\\sl0\\li1440\\tx1440\\tx3600\\tx5760\\tx6480\\par\n";
  81. char *syndoc ="\\par\\pard\\plain\\f26\\fs20\\li0000\\sl0\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  82. char *sephohelp="\\tab\n";
  83. char *sephodoc ="\\par\n\\pard\\plain\\f26\\fs20\\li1080\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  84. char *hcbhelp="\\pard\\plain\\f26\\fs20\\fi0000\\li0000\\tx1440\\tx6480\\par\n";
  85. char *hcbdoc ="\\par\\pard\\plain\\f26\\fs20\\fi0000\\li0000\\tx1080\\tx4320\\tx6480\n";
  86. char *ecbhelp="\\par\\pard\n";
  87. char *ecbdoc ="\\par\\pard\n";
  88. char *head0help="\\pard\\f26\\fs28\\fi0000\\li0000\\tx1440\\tx6480{\\b\n";
  89. char *head0doc ="\\par\\pard\\brdrt\\brdrs\\f26\\fs28\\fi0000\\li0000\\tx1080\\tx4320\\tx6480\n\\v\\f26\\fs20 {\\tc \\plain{\\b \\f26\\fs20 ";
  90. char *ehead0help="}";
  91. char *ehead0doc ="}}\\plain\\f26\\fs20\\li0000\\sl0\\fi0000\n";
  92. char *hohelp="\\par\\pard\\plain\\f26\\fs20\\fi-1440\\sl0\\li1440\\tx1440\\tx3600\\tx5760\\tx6480\n";
  93. char *hodoc ="\\par\\pard\\plain\\f26\\fs20\\li0000\\sl0\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  94. char *hparmhelp="\\par\\pard\\plain\\f26\\sl0\\sb60\\sa60\\fs20\\fi-2160\\li3600\\tx1440\\tx3600\\tx5760\\tx6480\n";
  95. char *hparmdoc ="\\par\\pard\\sbys\\f26\\fs20\\ri3200\\li1080\\sl0\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  96. char *sepreghelp="\\tab\n";
  97. char *sepregdoc ="\\par\n\\pard\\sbys\\f26\\fs20\\li3240\\sl0\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  98. char *hreghelp="\\par\\pard\\plain\\f26\\fs20\\fi-1440\\li3600\\tx1440\\tx3600\\tx5760\\tx6480\n";
  99. char *hregdoc ="\\par\\pard\\sbys\\f26\\fs20\\ri3200\\li1080\\sl0\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  100. char *hvalhelp="\\par\\pard\\plain\\f26\\sl0\\sb60\\sa60\\fs20\\fi-2160\\li5760\\tx5760\\tx6480\n";
  101. char *sepvalhelp="\\tab\n";
  102. char *hvaldoc="\\par\\pard\\plain\\f26\\sl0\\sb60\\sa60\\fs20\\fi-2160\\li5760\\tx5760\\tx6480\n";
  103. char *sepvaldoc="\\tab\n";
  104. char *sepparmhelp="\\tab\n";
  105. char *sepparmdoc ="\\par\n\\pard\\sbys\\f26\\fs20\\li3240\\sl0\\fi0000\\tx2160\\tx3240\\tx4320\\tx6480\n";
  106. char *hdeschelp="\\par\\pard\\plain\\f26\\fs20\\fi0000\\li1440\\tx1440\\tx3600\\tx5760\n";
  107. char *hdescdoc ="\\par\\pard\\plain\\f26\\fs20\\fi0000\\li1080\\tx1080\\tx2160\\tx3240\\tx4320\n";
  108. char *SUpar ="\\par\\pard\\plain\\f1\\fs20\\fi-3600\\li5760\\tx5760\n";
  109. char *hSUelements="\\par\\pard\\plain\\f26\\fs20\\fi-3600\\li5760\\tx5760\\tx6480\n";
  110. char *preg2a= "{\\b\\ulw Register}";
  111. char *p2a= "{\\b\\ulw Type/Parameter}";
  112. char *p2ahelp= "{\\b\\ulw Parameter}";
  113. char *p2b= "{\\b\\ulw Description}\\par\n";
  114. char *p2bhelp= "{\\b\\ulw Type/Description}\n";
  115. char *p3a= "{\\b\\ulw Value}";
  116. char *p3b= "{\\b\\ulw Meaning}\n";
  117. ///////////////////////////////////////////////////////////////////////////
  118. char achindex[256];
  119. struct _repl
  120. {
  121. char *from;
  122. char *to;
  123. int state;
  124. int size;
  125. };
  126. char ach2[100];
  127. #define DEFAULT 1
  128. #define TYPE 15
  129. #define ELEMENT 16
  130. #define FUNC 17
  131. #define MSG 18
  132. #define PARM 19
  133. struct _repl reps[]=
  134. {
  135. "<t>", "", TYPE, 0,
  136. "<e>", "", ELEMENT, 0,
  137. "<f>", "", FUNC, 0,
  138. "<m>", "", MSG, 0,
  139. "<p>", "", PARM, 0,
  140. "<d>", "", DEFAULT, 0,
  141. "<t", "", TYPE, 0,
  142. "<e", "", ELEMENT, 0,
  143. "<f", "", FUNC, 0,
  144. "<m", "", MSG, 0,
  145. "<p", "", PARM, 0,
  146. // fence
  147. NULL, NULL, 0, 0
  148. };
  149. static int state=0;
  150. static int i=0;
  151. void RTFtextOut( FILE * file,aLine * line);
  152. /*
  153. * @doc INTERNAL
  154. *
  155. * @func void | RTFtextOut | This outputs the given text lines.
  156. *
  157. * @parm aLine * | line | Specifies the text to output.
  158. */
  159. void RTFtextOut( file, line )
  160. FILE * file;
  161. aLine * line;
  162. {
  163. assert(!state);
  164. i=0;
  165. while( line != NULL )
  166. {
  167. if(!line->next && !line->text[0])
  168. break; // stop at trailing blank lines
  169. RTFLineOut(file, line->text);
  170. //
  171. // Should we put out a trailing space?
  172. //
  173. // if the previous line ends in a word, or a <D> then splat on
  174. // a space so words will not run together.
  175. //
  176. //
  177. if(line->next)
  178. {
  179. int len;
  180. char ch;
  181. len = strlen(line->text);
  182. ch = line->text[len-1];
  183. if ( len>=2 && !state &&
  184. ( isalpha(ch) || isdigit(ch) || ch == '.' ||
  185. (ch == '>' && line->text[len-2] == 'D')
  186. )
  187. )
  188. fprintf( file, " ");
  189. }
  190. fprintf(file,"\n");
  191. line = line->next;
  192. }
  193. RTFDoneText(file);
  194. state=0;
  195. }
  196. void RTFDoneText( FILE *fpoutfile )
  197. {
  198. // IndexTag *pIndex;
  199. // close off any processing that was in progress.
  200. char *pch;
  201. if(state)
  202. {
  203. achindex[i]=0;
  204. // strip leading spaces.
  205. i=0;
  206. while(isspace(achindex[i]))
  207. i++;
  208. if(outputType==RTFHELP && state != PARM)
  209. {
  210. /* output crossreference if in HELP, but not for parameters */
  211. if(state!=ELEMENT)
  212. {
  213. if((state == FUNC) || (state == TYPE))
  214. fprintf( fpoutfile, "{\\b\\uldb\\f26\\fs20 ");
  215. else
  216. fprintf( fpoutfile, "{\\uldb\\f26\\fs20 ");
  217. fprintf( fpoutfile, "%s", achindex + i);
  218. fprintf( fpoutfile, "}{\\v\\f26\\fs20 ");
  219. fprintf( fpoutfile, "%s",achindex + i);
  220. fprintf( fpoutfile, "}\\plain\\f26\\fs20 ");
  221. }
  222. else
  223. {
  224. pch=achindex+i;
  225. while(*pch) // just leave element name
  226. {
  227. if(*pch=='.')
  228. {
  229. pch++;
  230. break;
  231. }
  232. pch++;
  233. }
  234. if(!*pch)
  235. fprintf(errfp,"warning: bad element reference in %s\n",achindex);
  236. fprintf( fpoutfile, "{\\uldb\\b\\f26\\fs20 ");
  237. fprintf( fpoutfile, "%s", pch);
  238. fprintf( fpoutfile, "}{\\v\\f26\\fs20 ");
  239. pch=achindex+i;
  240. while(*pch) // just leave struct name
  241. {
  242. if(*pch=='.')
  243. {
  244. *pch=0;
  245. break;
  246. }
  247. pch++;
  248. }
  249. fprintf( fpoutfile, "%s",achindex + i);
  250. fprintf( fpoutfile, "}\\plain\\f26\\fs20 ");
  251. }
  252. }
  253. else
  254. {
  255. switch (state)
  256. {
  257. case PARM:
  258. fprintf( fpoutfile, pchrtfparm );
  259. break;
  260. case FUNC:
  261. fprintf( fpoutfile, pchrtffunc );
  262. break;
  263. case MSG:
  264. fprintf( fpoutfile, pchrtfmsg );
  265. break;
  266. case TYPE:
  267. fprintf( fpoutfile, pchrtftype );
  268. break;
  269. case ELEMENT:
  270. fprintf( fpoutfile, pchrtfelem );
  271. break;
  272. default:
  273. fprintf( fpoutfile, pchrtfnone );
  274. break;
  275. }
  276. fprintf( fpoutfile,achindex +i);
  277. fprintf( fpoutfile,pchrtfdefault);
  278. }
  279. state=0;
  280. i=0;
  281. }
  282. }
  283. #define ERRORMARK(w) for(j=0;j<w;j++) fprintf(errfp," "); fprintf(errfp,"^\n");
  284. /*
  285. * @doc INTERNAL
  286. *
  287. * @func void | RTFLineOut | This outputs the given text line.
  288. *
  289. * @parm char * | line | Specifies the text to output.
  290. */
  291. void
  292. RTFLineOut(FILE * fpoutfile, char * pch)
  293. {
  294. int j;
  295. int k;
  296. int flag;
  297. char *pchs=pch;
  298. // first time init
  299. if(reps[0].size==0)
  300. for(j=0;reps[j].from; j++)
  301. reps[j].size=strlen(reps[j].from);
  302. /* check for and process blank lines */
  303. if(!*pch)
  304. {
  305. // need to set cur par sep formatting
  306. // HACK. Doing a 'tab' should get us to column indent.
  307. // (assumes fi is set to -x and tx at indent)
  308. //
  309. // the tab puts in a blank line also
  310. if(fSubBlock) // if in sub-block
  311. fprintf(fpoutfile, "\\par\\tab");
  312. else
  313. fprintf(fpoutfile, "\\par\\par\\tab");
  314. }
  315. while(*pch)
  316. {
  317. if(state)
  318. {
  319. // Handles <x>yyy<d> and <x yyy>
  320. if(*pch!='>' && *pch!='<')
  321. {
  322. if(*pch!='\n')
  323. achindex[i++]=*pch;
  324. pch++;
  325. }
  326. else
  327. {
  328. RTFDoneText(fpoutfile);
  329. if(*pch=='<')
  330. { // it was a <
  331. pch++;
  332. if(*pch=='d' || *pch=='D')
  333. {
  334. // it's OK, it's <d
  335. pch++;
  336. if(*pch!='>')
  337. {
  338. fprintf(errfp,
  339. "non-fatal error: Badly formed formatting code in text: %s\n",pchs);
  340. ERRORMARK(pch-pchs);
  341. }
  342. pch++;
  343. }
  344. else
  345. {
  346. // we don't know what it is. Skip it.
  347. fprintf(errfp,
  348. "non-fatal error: Unexpected formatting code in text: %s\n",pchs);
  349. ERRORMARK(pch-pchs);
  350. while(*pch && *pch!='>')
  351. pch++;
  352. if(*pch)
  353. pch++;
  354. }
  355. }
  356. else // it's just >
  357. pch++;
  358. }
  359. continue;
  360. }
  361. if(*pch == '\t')
  362. {
  363. fprintf(fpoutfile," ");
  364. pch++;
  365. continue;
  366. }
  367. if(*pch == '\\')
  368. {
  369. pch++;
  370. if (*pch == '|' || *pch == '@')
  371. fprintf(fpoutfile, "%c", *pch);
  372. else
  373. {
  374. pch--;
  375. fprintf(fpoutfile,"\\%c",*pch); // output '\\'
  376. }
  377. pch++;
  378. continue;
  379. }
  380. if(*pch == '{' || *pch == '}')
  381. {
  382. fprintf(fpoutfile,"\\%c",*pch);
  383. pch++;
  384. continue;
  385. }
  386. if(*pch=='<' && pch[1]!='<')
  387. {
  388. for(j=0; reps[j].from!=NULL; j++)
  389. {
  390. if(!strnicmp(pch,reps[j].from,reps[j].size))
  391. {
  392. if(reps[j].state==DEFAULT )
  393. {
  394. if(!state)
  395. {
  396. fprintf(errfp, "Ending without start. Ignored.\n");
  397. }
  398. else
  399. {
  400. // reset state and take care of business
  401. RTFDoneText(fpoutfile);
  402. }
  403. }
  404. state=reps[j].state;
  405. pch+=reps[j].size;
  406. break; // the for loop
  407. }
  408. }
  409. if(reps[j].from==NULL) // we didn't find it in table
  410. {
  411. fprintf(errfp,
  412. "non-fatal error: Unknown formatting code in text: %s\n",pch);
  413. putc(*pch, fpoutfile);
  414. pch++;
  415. }
  416. }
  417. else
  418. {
  419. putc(*pch, fpoutfile);
  420. pch++;
  421. }
  422. }
  423. RTFDoneText(fpoutfile);
  424. }
  425. ///////////////////////////////////////////////////////////////////////////
  426. /*
  427. * @doc INTERNAL
  428. *
  429. * @func void | RTFXrefOut | This outputs the given Xref lines.
  430. * (lines are seperated by <new-line>)
  431. *
  432. * @parm aLine * | line | Specifies the text to output.
  433. */
  434. void RTFXrefOut(FILE * file,aLine * line);
  435. void RTFXrefOut( file, line )
  436. FILE * file;
  437. aLine * line;
  438. {
  439. char ach[80];
  440. int i;
  441. char *pch;
  442. while( line != NULL )
  443. {
  444. pch=line->text;
  445. while(isspace(*pch))
  446. pch++;
  447. while(*pch)
  448. {
  449. i=0;
  450. while(*pch && !(*pch ==',' || isspace(*pch) ) )
  451. ach[i++]=*pch++;
  452. if(i>0)
  453. {
  454. ach[i]=0;
  455. RTFDumpX(file, ach);
  456. }
  457. while(*pch && (*pch == ',' || isspace(*pch)))
  458. {
  459. pch++;
  460. }
  461. // if(*pch && outputType == RTFDOC )
  462. // put commas between items
  463. fprintf(file, ", ");
  464. }
  465. fprintf( file, "\n" );
  466. line = line->next;
  467. if(line)
  468. fprintf( file, " ");
  469. }
  470. }
  471. /*
  472. * @doc INTERNAL RTF
  473. *
  474. * @func void | RTFDumpX | This function outputs a Crossreference.
  475. *
  476. * @parm FILE * | file | Specifies the output file.
  477. *
  478. * @parm char * | pch | Specifies the name of the Crossreference.
  479. *
  480. */
  481. void
  482. RTFDumpX(FILE *file, char *pch)
  483. {
  484. if(outputType==RTFHELP)
  485. {
  486. fprintf( file, "{\\uldb\\f26\\fs20 ");
  487. fprintf( file, "%s",pch);
  488. fprintf( file, "}{\\v\\f26\\fs20 ");
  489. fprintf( file, "%s",pch);
  490. fprintf( file, "}\n\\plain\\f26\\fs20 ");
  491. }
  492. else
  493. fprintf( file, "%s", pch);
  494. }
  495. /*
  496. * @doc INTERNAL RTF
  497. *
  498. * @func void | RTFtextOutLn | This outputs the given text lines.
  499. * (lines are seperated by <new-line>)
  500. *
  501. * @parm FILE * | file | Specifies the output file.
  502. *
  503. * @parm aLine * | line | Specifies the text to output.
  504. */
  505. void RTFtextOutLn( FILE * file,aLine * line);
  506. void RTFtextOutLn( file, line )
  507. FILE * file;
  508. aLine * line;
  509. {
  510. RTFtextOut(file,line);
  511. }
  512. /*
  513. * @doc INTERNAL
  514. *
  515. * @func void | RTFBlockOut | This outputs the block information in
  516. * RTF Format.
  517. *
  518. * @parm aFuncBlock * | func | Specifies a pointer to the function
  519. * information
  520. *
  521. * @parm FILE * | file | File to send output to.
  522. */
  523. void RTFBlockOut(aBlock * pBlock, FILE * file)
  524. {
  525. aParm * parm;
  526. aFlag * flag;
  527. aBlock *pcurBlock;
  528. aCond *cond;
  529. int iblock ;
  530. int hselect;
  531. blocksprocessed++;
  532. /* add to hselect the block type */
  533. if( !pBlock || !file )
  534. {
  535. fprintf(errfp,"XXX:RTFBlockOut: parameter error\n");
  536. return;
  537. }
  538. if( pBlock->blockType == FUNCTION)
  539. hselect= (outputType == RTFHELP) ? FUNCHELP : FUNCDOC;
  540. else if( pBlock->blockType == MESSAGE )
  541. hselect= (outputType == RTFHELP) ? MSGHELP : MSGDOC;
  542. else if( pBlock->blockType == CALLBACK )
  543. hselect= (outputType == RTFHELP) ? CBHELP : CBDOC;
  544. else if( pBlock->blockType == MASMBLOCK )
  545. hselect= (outputType == RTFHELP) ? MASMHELP : MASMDOC;
  546. else if( pBlock->blockType == MASMCBBLOCK )
  547. hselect= (outputType == RTFHELP) ? MASMCBHELP : MASMCBDOC;
  548. else if( pBlock->blockType == CALLBACK )
  549. hselect= (outputType == RTFHELP) ? INTHELP : INTDOC;
  550. else if( pBlock->blockType == STRUCTBLOCK )
  551. hselect= (outputType == RTFHELP) ? STRUCTHELP : STRUCTDOC;
  552. else if( pBlock->blockType == UNIONBLOCK )
  553. hselect= (outputType == RTFHELP) ? UNIONHELP : UNIONDOC;
  554. else
  555. {
  556. fprintf(errfp,"Unknown block type in RTFBlockOut\n");
  557. return;
  558. }
  559. switch(hselect)
  560. {
  561. case FUNCHELP:
  562. case MASMHELP:
  563. case INTHELP:
  564. case MSGHELP:
  565. case STRUCTHELP:
  566. case UNIONHELP:
  567. fprintf( file, "\\par\\page K{\\footnote{\\up6 K} "); /* keyword */
  568. RTFtextOut( file, pBlock->name );
  569. fprintf( file, "} ${\\footnote{\\up6 $} "); /* section Title */
  570. RTFtextOut( file, pBlock->name );
  571. fprintf( file, "} +{\\footnote{\\up6 +} "); /* order */
  572. fprintf( file, "T");
  573. // RTFtextOut( file, pBlock->name );
  574. fprintf( file, "} #{\\footnote{\\up6 #} "); /* make target */
  575. RTFtextOut( file, pBlock->name );
  576. fprintf( file, "}\n");
  577. break;
  578. }
  579. /* process name */
  580. switch(hselect)
  581. {
  582. case MASMHELP:
  583. case INTHELP:
  584. case FUNCHELP:
  585. case MSGHELP:
  586. case STRUCTHELP:
  587. case UNIONHELP:
  588. fprintf( file, head0help);
  589. RTFtextOut( file, pBlock->name );
  590. fprintf( file, ehead0help);
  591. break;
  592. case CBHELP:
  593. case CBDOC:
  594. /* nothing */
  595. break;
  596. case FUNCDOC:
  597. case MSGDOC:
  598. case INTDOC:
  599. case MASMDOC:
  600. case STRUCTDOC:
  601. case UNIONDOC:
  602. fprintf( file, head0doc);
  603. RTFtextOut( file, pBlock->name );
  604. fprintf( file, ehead0doc);
  605. break;
  606. }
  607. if(pBlock->doclevel && dumplevels)
  608. RTFDumpLevel(file, pBlock->doclevel, hselect);
  609. if(outputType!= RTFHELP)
  610. fprintf(file, "\\par\\pard\n"); // blank line
  611. /* handle outputting syntax */
  612. switch(hselect)
  613. {
  614. case CBHELP:
  615. fprintf( file, synhelp );
  616. fprintf( file, "{\\b %s}\\tab \n","Callback");
  617. fprintf( file, " {\\b ");
  618. RTFtextOut( file, pBlock->type );
  619. fprintf( file, "}");
  620. fprintf( file, " {\\i ");
  621. RTFtextOut( file, pBlock->name );
  622. fprintf( file, "}");
  623. fprintf( file, "\\par\n" );
  624. fprintf( file, sepsynhelp );
  625. if( pBlock->parm )
  626. {
  627. parm = pBlock->parm;
  628. while( parm )
  629. {
  630. fprintf( file, "{\\b ");
  631. RTFtextOut( file, parm->type );
  632. fprintf( file, "} " ); // << note the trailing space
  633. fprintf( file, "{\\i ");
  634. RTFtextOut( file, parm->name );
  635. fprintf( file, ";}" ); // << note the ';'
  636. parm = parm->next;
  637. if( parm )
  638. {
  639. fprintf( file, "\\par\\tab\n" );
  640. }
  641. }
  642. parm=NULL;
  643. }
  644. fprintf( file, "\\par\n" );
  645. break;
  646. case MASMHELP:
  647. case INTHELP:
  648. case FUNCHELP:
  649. fprintf( file, synhelp );
  650. fprintf( file, "{\\b %s}\n","Syntax" );
  651. fprintf( file, sepsynhelp );
  652. RTFDumpParms(file, pBlock, hselect);
  653. fprintf( file, "\\par\n" );
  654. break;
  655. case UNIONHELP:
  656. case STRUCTHELP:
  657. case MSGHELP:
  658. break;
  659. case INTDOC:
  660. case MASMDOC:
  661. case FUNCDOC:
  662. case CBDOC:
  663. fprintf( file, syndoc );
  664. fprintf( file, "{\\b %s}\n",
  665. (hselect==CBDOC) ? "Callback" : "Syntax" );
  666. fprintf( file, sepsyndoc );
  667. RTFDumpParms(file, pBlock, hselect);
  668. fprintf( file, "\\par\n" );
  669. break;
  670. case UNIONDOC:
  671. case STRUCTDOC:
  672. case MSGDOC:
  673. break;
  674. }
  675. /* description block */
  676. switch(hselect)
  677. {
  678. case MASMHELP:
  679. case INTHELP:
  680. case FUNCHELP:
  681. case CBHELP:
  682. case MSGHELP:
  683. case UNIONHELP:
  684. case STRUCTHELP:
  685. fprintf( file, hdeschelp );
  686. RTFtextOutLn( file, pBlock->desc );
  687. fprintf( file, "\\par\n" );
  688. break;
  689. case INTDOC:
  690. case MASMDOC:
  691. case FUNCDOC:
  692. case CBDOC:
  693. case MSGDOC:
  694. case UNIONDOC:
  695. case STRUCTDOC:
  696. fprintf( file, hdescdoc );
  697. RTFtextOutLn( file, pBlock->desc );
  698. fprintf( file, "\\par\n" );
  699. break;
  700. }
  701. if( pBlock->reg )
  702. {
  703. RTFRegOut( file, pBlock->reg, hselect);
  704. if(pBlock->parm)
  705. fprintf(errfp,"Warning: Block contains BOTH Registers and API parms.\n");
  706. }
  707. if( pBlock->parm )
  708. {
  709. RTFParmOut( file, pBlock->parm, hselect);
  710. }
  711. if( pBlock->field )
  712. RTFFieldOut( file, pBlock, hselect);
  713. if( pBlock->other)
  714. RTFOtherOut( file, pBlock->other, hselect);
  715. /* return description */
  716. if( pBlock->rtndesc )
  717. {
  718. switch(hselect)
  719. {
  720. case FUNCHELP:
  721. case MASMHELP:
  722. case INTHELP:
  723. case CBHELP:
  724. case MSGHELP:
  725. // leave extra blank line before return value
  726. fprintf(file,"\n\\par");
  727. fprintf( file, hohelp );
  728. fprintf( file, "{\\b Return Value}" );
  729. fprintf( file, sephohelp);
  730. break;
  731. case INTDOC:
  732. case MASMDOC:
  733. case FUNCDOC:
  734. case CBDOC:
  735. case MSGDOC:
  736. fprintf( file, hodoc );
  737. fprintf( file, "{\\b Return Value}" );
  738. fprintf( file, sephodoc);
  739. break;
  740. } // switch
  741. RTFtextOutLn( file, pBlock->rtndesc );
  742. if(pBlock->rtnflag)
  743. {
  744. RTFFlagOut(file, pBlock->rtnflag, hselect, FLAGRTN);
  745. }
  746. if(pBlock->rtnreg)
  747. {
  748. RTFRegOut(file, pBlock->rtnreg, hselect);
  749. }
  750. fprintf( file, "\\par\n" );
  751. } // if rtndesc
  752. else
  753. if(pBlock->rtnflag)
  754. fprintf(errfp,"XXX: Return flags without return desc\n");
  755. for( cond = pBlock->cond; cond; cond = cond->next )
  756. {
  757. switch(hselect)
  758. {
  759. case MASMHELP:
  760. case INTHELP:
  761. case FUNCHELP:
  762. case CBHELP:
  763. case MSGHELP:
  764. fprintf( file, hohelp );
  765. fprintf( file, "{\\b Conditional}" );
  766. fprintf( file, sephohelp);
  767. break;
  768. case INTDOC:
  769. case MASMDOC:
  770. case FUNCDOC:
  771. case CBDOC:
  772. case MSGDOC:
  773. fprintf( file, hodoc );
  774. fprintf( file, "{\\b Conditional}" );
  775. fprintf( file, sephodoc);
  776. break;
  777. }
  778. RTFCondOut(file, cond, hselect);
  779. fprintf( file, "\\par\n" );
  780. }
  781. if( pBlock->comment )
  782. {
  783. switch(hselect)
  784. {
  785. case MASMHELP:
  786. case INTHELP:
  787. case FUNCHELP:
  788. case CBHELP:
  789. case MSGHELP:
  790. fprintf( file, hohelp );
  791. fprintf( file, "{\\b Comments}" );
  792. fprintf( file, sephohelp);
  793. break;
  794. case INTDOC:
  795. case MASMDOC:
  796. case FUNCDOC:
  797. case CBDOC:
  798. case MSGDOC:
  799. fprintf( file, hodoc );
  800. fprintf( file, "{\\b Comments}" );
  801. fprintf( file, sephodoc);
  802. break;
  803. }
  804. RTFtextOutLn( file, pBlock->comment );
  805. fprintf( file, "\\par\n" );
  806. }
  807. if( pBlock->uses )
  808. {
  809. switch(hselect)
  810. {
  811. case MASMHELP:
  812. case INTHELP:
  813. case FUNCHELP:
  814. case CBHELP:
  815. case MSGHELP:
  816. fprintf( file, hohelp );
  817. fprintf( file, "{\\b Uses}" );
  818. fprintf( file, sephohelp);
  819. break;
  820. case INTDOC:
  821. case MASMDOC:
  822. case FUNCDOC:
  823. case CBDOC:
  824. case MSGDOC:
  825. fprintf( file, hodoc );
  826. fprintf( file, "{\\b Uses}" );
  827. fprintf( file, sephodoc);
  828. break;
  829. }
  830. RTFtextOutLn( file, pBlock->uses );
  831. fprintf( file, "\\par\n" );
  832. }
  833. if( pBlock->cb)
  834. {
  835. pcurBlock=pBlock->cb;
  836. while(pcurBlock)
  837. {
  838. RTFBlockOut(pcurBlock, file );
  839. pcurBlock=pcurBlock->next;
  840. }
  841. }
  842. if( pBlock->xref )
  843. {
  844. switch(hselect)
  845. {
  846. case MASMHELP:
  847. case INTHELP:
  848. case FUNCHELP:
  849. case CBHELP:
  850. case MSGHELP:
  851. fprintf( file, hohelp );
  852. fprintf( file, "{\\b See Also}" );
  853. fprintf( file, sephohelp);
  854. break;
  855. case INTDOC:
  856. case MASMDOC:
  857. case FUNCDOC:
  858. case CBDOC:
  859. case MSGDOC:
  860. fprintf( file, hodoc );
  861. fprintf( file, "{\\b Related Functions}" );
  862. fprintf( file, sephodoc);
  863. break;
  864. }
  865. RTFXrefOut( file, pBlock->xref );
  866. fprintf( file, "\\par\n" );
  867. }
  868. }
  869. /*
  870. * @doc INTERNAL RTF
  871. *
  872. * @func void | RTFDumpLevel | This function outputs the DOC Level.
  873. *
  874. * @parm FILE * | file | Specifies the output file.
  875. *
  876. * @parm aLine * | pLine | Specifies the list of Doc Levels.
  877. *
  878. * @parm int | hselect | Specifies the current mode of output.
  879. *
  880. * @flag FUNCHELP | Specifies the current block is a Function,
  881. * and the mode is RTFHELP.
  882. *
  883. * @flag MSGHELP | Specifies the current block is a Message,
  884. * and the mode is RTFHELP.
  885. *
  886. * @flag CBHELP | Specifies the current block is a Call Back,
  887. * and the mode is RTFHELP.
  888. *
  889. * @flag FUNCDOC | Specifies the current block is a Function,
  890. * and the mode is RTFDOC.
  891. *
  892. * @flag MSGDOC | Specifies the current block is a Message,
  893. * and the mode is RTFDOC.
  894. *
  895. * @flag CBDOC | Specifies the current block is a Call Back,
  896. * and the mode is RTFDOC.
  897. *
  898. * @flag INTDOC | Specifies the current block is an Interrupt,
  899. * and the mode is RTFDOC.
  900. *
  901. * @flag INTHELP | Specifies the current block is an Interrupt,
  902. * and the mode is RTFHELP.
  903. *
  904. * @flag MASMDOC | Specifies the current block is a MASM,
  905. * and the mode is RTFDOC.
  906. *
  907. * @flag MASMHELP | Specifies the current block is a MASM,
  908. * and the mode is RTFHELP.
  909. *
  910. */
  911. void
  912. RTFDumpLevel(FILE *file, aLine *pLine, int hselect)
  913. {
  914. fprintf(file, "\\tab ");
  915. while(pLine)
  916. {
  917. if(pLine->text)
  918. {
  919. fprintf( file, "{\\scaps %s}", pLine->text);
  920. pLine=pLine->next;
  921. if(pLine)
  922. fprintf(file, ", ");
  923. }
  924. }
  925. }
  926. /*
  927. * @doc INTERNAL RTF
  928. *
  929. * @func void | RTFDumpParms | This functions outputs the Parameters
  930. * for a declaration in the specfied mode to the output file.
  931. *
  932. * @parm FILE * | file | Specifies the output file.
  933. *
  934. * @parm aLine * | pLine | Specifies the list of Doc Levels.
  935. *
  936. * @parm int | hselect | Specifies the current mode of output.
  937. *
  938. * @flag FUNCHELP | Specifies the current block is a Function,
  939. * and the mode is RTFHELP.
  940. *
  941. * @flag MSGHELP | Specifies the current block is a Message,
  942. * and the mode is RTFHELP.
  943. *
  944. * @flag CBHELP | Specifies the current block is a Call Back,
  945. * and the mode is RTFHELP.
  946. *
  947. * @flag FUNCDOC | Specifies the current block is a Function,
  948. * and the mode is RTFDOC.
  949. *
  950. * @flag MSGDOC | Specifies the current block is a Message,
  951. * and the mode is RTFDOC.
  952. *
  953. * @flag CBDOC | Specifies the current block is a Call Back,
  954. * and the mode is RTFDOC.
  955. *
  956. * @flag INTDOC | Specifies the current block is an Interrupt,
  957. * and the mode is RTFDOC.
  958. *
  959. * @flag INTHELP | Specifies the current block is an Interrupt,
  960. * and the mode is RTFHELP.
  961. *
  962. * @flag MASMDOC | Specifies the current block is a MASM,
  963. * and the mode is RTFDOC.
  964. *
  965. * @flag MASMHELP | Specifies the current block is a MASM,
  966. * and the mode is RTFHELP.
  967. *
  968. */
  969. void
  970. RTFDumpParms(FILE *file, aBlock *pBlock, int hselect)
  971. {
  972. aParm *parm;
  973. assert(hselect!=CBHELP);
  974. fprintf( file, " {\\b ");
  975. RTFtextOut( file, pBlock->type );
  976. fprintf( file, "}");
  977. fprintf( file, " {\\b ");
  978. RTFtextOut( file, pBlock->name );
  979. fprintf( file, "}");
  980. switch(hselect)
  981. {
  982. case CBDOC:
  983. if( pBlock->blockType == MASMCBBLOCK )
  984. break;
  985. case FUNCHELP:
  986. case FUNCDOC:
  987. fprintf( file, "(" );
  988. break;
  989. case CBHELP:
  990. break;
  991. }
  992. if( pBlock->parm )
  993. {
  994. parm = pBlock->parm;
  995. while( parm )
  996. {
  997. fprintf( file, "{\\i ");
  998. RTFtextOut( file, parm->name );
  999. fprintf( file, "}" );
  1000. parm = parm->next;
  1001. if( parm )
  1002. {
  1003. fprintf( file, ", " );
  1004. }
  1005. }
  1006. }
  1007. switch(hselect)
  1008. {
  1009. case CBDOC:
  1010. case CBHELP:
  1011. if( pBlock->blockType == MASMCBBLOCK )
  1012. break;
  1013. case FUNCHELP:
  1014. case FUNCDOC:
  1015. fprintf( file, ")" );
  1016. break;
  1017. }
  1018. return;
  1019. }
  1020. /*
  1021. * @doc INTERNAL RTF
  1022. *
  1023. * @func void | RTFRegOut | This function outputs the specified Register
  1024. * structure in the specifed mode to the output file.
  1025. *
  1026. * @parm FILE * | file | Specifies the output file.
  1027. *
  1028. * @parm aReg * | reg | Specifies the list of Registers.
  1029. *
  1030. * @parm int | hselect | Specifies the current mode of output.
  1031. *
  1032. * @flag FUNCHELP | Specifies the current block is a Function,
  1033. * and the mode is RTFHELP.
  1034. *
  1035. * @flag MSGHELP | Specifies the current block is a Message,
  1036. * and the mode is RTFHELP.
  1037. *
  1038. * @flag CBHELP | Specifies the current block is a Call Back,
  1039. * and the mode is RTFHELP.
  1040. *
  1041. * @flag FUNCDOC | Specifies the current block is a Function,
  1042. * and the mode is RTFDOC.
  1043. *
  1044. * @flag MSGDOC | Specifies the current block is a Message,
  1045. * and the mode is RTFDOC.
  1046. *
  1047. * @flag CBDOC | Specifies the current block is a Call Back,
  1048. * and the mode is RTFDOC.
  1049. *
  1050. * @flag INTDOC | Specifies the current block is an Interrupt,
  1051. * and the mode is RTFDOC.
  1052. *
  1053. * @flag INTHELP | Specifies the current block is an Interrupt,
  1054. * and the mode is RTFHELP.
  1055. *
  1056. * @flag MASMDOC | Specifies the current block is a MASM,
  1057. * and the mode is RTFDOC.
  1058. *
  1059. * @flag MASMHELP | Specifies the current block is a MASM,
  1060. * and the mode is RTFHELP.
  1061. *
  1062. */
  1063. void
  1064. RTFRegOut(FILE *file, aReg *reg, int hselect)
  1065. {
  1066. switch(hselect)
  1067. {
  1068. case MASMHELP:
  1069. case INTHELP:
  1070. case FUNCHELP:
  1071. case CBHELP:
  1072. case MSGHELP:
  1073. fprintf( file, hreghelp );
  1074. fprintf( file, preg2a );
  1075. fprintf( file, sepreghelp);
  1076. fprintf( file, p2b );
  1077. break;
  1078. case INTDOC:
  1079. case MASMDOC:
  1080. case FUNCDOC:
  1081. case CBDOC:
  1082. case MSGDOC:
  1083. fprintf( file, hregdoc );
  1084. fprintf( file, preg2a );
  1085. fprintf( file, sepregdoc);
  1086. fprintf( file, p2b );
  1087. break;
  1088. }
  1089. while( reg )
  1090. {
  1091. switch(hselect)
  1092. {
  1093. case MASMHELP:
  1094. case INTHELP:
  1095. case FUNCHELP:
  1096. case CBHELP:
  1097. case MSGHELP:
  1098. fprintf( file, hreghelp );
  1099. fprintf( file, "{\\i ");
  1100. RTFtextOut( file, reg->name );
  1101. fprintf( file, "} " );
  1102. fprintf( file, sepreghelp);
  1103. break;
  1104. case INTDOC:
  1105. case MASMDOC:
  1106. case FUNCDOC:
  1107. case CBDOC:
  1108. case MSGDOC:
  1109. fprintf( file, hregdoc );
  1110. fprintf( file, "{\\i ");
  1111. RTFtextOut( file, reg->name );
  1112. fprintf( file, "} " );
  1113. fprintf( file, sepregdoc);
  1114. break;
  1115. }
  1116. RTFtextOutLn( file, reg->desc );
  1117. fprintf( file, "\n" );
  1118. if(reg->flag)
  1119. RTFFlagOut(file, reg->flag, hselect, FLAGREG);
  1120. fprintf( file, "\\par\n");
  1121. reg = reg->next;
  1122. }
  1123. }
  1124. void RTFFieldOut(FILE *file, aBlock *pBlock , int hselect)
  1125. {
  1126. aLine *tag;
  1127. aField *curfield;
  1128. aField *field;
  1129. field=pBlock->field;
  1130. tag=pBlock->tagname;
  1131. // recursively dump fields
  1132. // output structure definition
  1133. fprintf(file, "%stypedef struct %s \\{\n", SUpar, tag ? tag->text : "" );
  1134. fprintf(file, "%s",SUpar);
  1135. curfield=pBlock->field;
  1136. while(curfield)
  1137. {
  1138. switch(curfield->wType)
  1139. {
  1140. case FIELD_TYPE:
  1141. RTFTypeOut1(file, (aType *)curfield->ptr, hselect);
  1142. break;
  1143. case FIELD_STRUCT:
  1144. case FIELD_UNION:
  1145. RTFSUOut1(file, (aSU *)curfield->ptr,
  1146. hselect, curfield->wType);
  1147. break;
  1148. default:
  1149. assert(FALSE);
  1150. break;
  1151. }
  1152. curfield=curfield->next;
  1153. }
  1154. fprintf(file,"\\} %s;\\par",pBlock->name->text);
  1155. fprintf(file,"%s\\par The {\\b %s} structure contains the following fields:\\par\\par",
  1156. hdescdoc, pBlock->name->text);
  1157. fprintf(file,"%s{\\ul Field}\\tab{\\ul Description}\\par\n",hSUelements);
  1158. // output element definitions.
  1159. curfield=pBlock->field;
  1160. while(curfield)
  1161. {
  1162. switch(curfield->wType)
  1163. {
  1164. case FIELD_TYPE:
  1165. RTFTypeOut2(file, (aType *)curfield->ptr, hselect);
  1166. break;
  1167. case FIELD_STRUCT:
  1168. case FIELD_UNION:
  1169. RTFSUOut2(file, (aSU *)curfield->ptr, hselect, curfield->wType);
  1170. break;
  1171. default:
  1172. assert(FALSE);
  1173. break;
  1174. }
  1175. curfield=curfield->next;
  1176. }
  1177. }
  1178. void RTFsubFieldOut1(FILE *file, aField *field , int hselect)
  1179. {
  1180. aLine *tag;
  1181. aField *curfield;
  1182. // recursively dump fields
  1183. curfield=field;
  1184. while(curfield)
  1185. {
  1186. switch(curfield->wType)
  1187. {
  1188. case FIELD_TYPE:
  1189. RTFTypeOut1(file, (aType *)curfield->ptr, hselect);
  1190. break;
  1191. case FIELD_STRUCT:
  1192. case FIELD_UNION:
  1193. RTFSUOut1(file, (aSU *)curfield->ptr,
  1194. hselect, curfield->wType);
  1195. break;
  1196. default:
  1197. assert(FALSE);
  1198. break;
  1199. }
  1200. curfield=curfield->next;
  1201. }
  1202. }
  1203. void RTFSUOut1(FILE *file, aSU *SU, int hselect, int wType)
  1204. {
  1205. aSU *curSU;
  1206. int level;
  1207. for(level=SU->level ; level>0; level--)
  1208. fprintf(file, " "); // four spaces per indent.
  1209. fprintf(file, "%s \\{\\par\n", wType == FIELD_STRUCT ? "struct" : "union");
  1210. if(SU->field)
  1211. RTFsubFieldOut1(file, SU->field, hselect);
  1212. for(level=SU->level ; level>0; level--)
  1213. fprintf(file, " "); // four spaces per indent.
  1214. fprintf(file, "\\} %s;\\par\n",SU->name->text);
  1215. }
  1216. void RTFTypeOut1(FILE *file, aType *type, int hselect)
  1217. {
  1218. int level;
  1219. for(level=type->level +1 ; level>0; level--)
  1220. fprintf(file, " "); // four spaces per indent.
  1221. RTFtextOut(file, type->type);
  1222. fprintf(file,"\\tab ");
  1223. RTFtextOut(file, type->name);
  1224. fprintf( file, ";\\par\n" ); // note the ; <<<<
  1225. if(type->flag)
  1226. {
  1227. RTFFlagOut(file, type->flag, hselect, FLAGPARM);
  1228. fprintf(file, "%s", SUpar);
  1229. }
  1230. }
  1231. void RTFSUOut2(FILE *file, aSU *SU, int hselect, int wType)
  1232. {
  1233. aSU *curSU;
  1234. int level;
  1235. if(SU->field)
  1236. RTFsubFieldOut2(file, SU->field, hselect);
  1237. fprintf( file, "\\par\n" );
  1238. }
  1239. void RTFTypeOut2(FILE *file, aType *type, int hselect)
  1240. {
  1241. RTFtextOut(file, type->name);
  1242. fprintf(file,"\\tab ");
  1243. RTFtextOut(file, type->desc);
  1244. fprintf( file, "\\par\n" );
  1245. }
  1246. void RTFsubFieldOut2(FILE *file, aField *field , int hselect)
  1247. {
  1248. aLine *tag;
  1249. aField *curfield;
  1250. // recursively dump fields
  1251. curfield=field;
  1252. while(curfield)
  1253. {
  1254. switch(curfield->wType)
  1255. {
  1256. case FIELD_TYPE:
  1257. RTFTypeOut2(file, (aType *)curfield->ptr, hselect);
  1258. break;
  1259. case FIELD_STRUCT:
  1260. case FIELD_UNION:
  1261. RTFSUOut2(file, (aSU *)curfield->ptr, hselect, curfield->wType);
  1262. break;
  1263. default:
  1264. assert(FALSE);
  1265. break;
  1266. }
  1267. curfield=curfield->next;
  1268. }
  1269. }
  1270. void RTFOtherOut(FILE *file, aOther *other, int hselect)
  1271. {
  1272. aOther *curo;
  1273. switch(hselect)
  1274. {
  1275. case MASMHELP:
  1276. case INTHELP:
  1277. case FUNCHELP:
  1278. case CBHELP:
  1279. case MSGHELP:
  1280. // what are we doing here?
  1281. break;
  1282. case STRUCTHELP:
  1283. case UNIONHELP:
  1284. fprintf( file, hohelp );
  1285. fprintf( file, "{\\b Synonyms}" );
  1286. fprintf( file, sephohelp);
  1287. break;
  1288. case INTDOC:
  1289. case MASMDOC:
  1290. case FUNCDOC:
  1291. case CBDOC:
  1292. case MSGDOC:
  1293. // what are we doing here?
  1294. break;
  1295. case STRUCTDOC:
  1296. case UNIONDOC:
  1297. fprintf( file, hodoc );
  1298. fprintf( file, "{\\b Other names}" );
  1299. fprintf( file, sephodoc);
  1300. break;
  1301. }
  1302. curo=other;
  1303. while(curo)
  1304. {
  1305. if(hselect == STRUCTHELP || hselect == UNIONHELP)
  1306. {
  1307. fprintf( file, "K{\\footnote{\\up6 K} "); /* make target */
  1308. RTFtextOut( file, curo->name);
  1309. fprintf( file, "}\n");
  1310. }
  1311. RTFtextOut( file, curo->type );
  1312. fprintf(file,"\\tab ");
  1313. RTFtextOut( file, curo->name);
  1314. if(curo->desc)
  1315. RTFtextOut( file, curo->desc);
  1316. fprintf( file, "\\par\n" );
  1317. curo=curo->next;
  1318. }
  1319. fprintf( file, "\\par\n" );
  1320. }
  1321. /*
  1322. * @doc INTERNAL RTF
  1323. *
  1324. * @func void | RTFCondOut | This function outputs the specified Conditional
  1325. * structure in the specifed mode to the output file.
  1326. *
  1327. * @parm FILE * | file | Specifies the output file.
  1328. *
  1329. * @parm aCond * | pCond | Specifies the list of Conditionals.
  1330. *
  1331. * @parm int | hselect | Specifies the current mode of output.
  1332. *
  1333. * @flag FUNCHELP | Specifies the current block is a Function,
  1334. * and the mode is RTFHELP.
  1335. *
  1336. * @flag MSGHELP | Specifies the current block is a Message,
  1337. * and the mode is RTFHELP.
  1338. *
  1339. * @flag CBHELP | Specifies the current block is a Call Back,
  1340. * and the mode is RTFHELP.
  1341. *
  1342. * @flag FUNCDOC | Specifies the current block is a Function,
  1343. * and the mode is RTFDOC.
  1344. *
  1345. * @flag MSGDOC | Specifies the current block is a Message,
  1346. * and the mode is RTFDOC.
  1347. *
  1348. * @flag CBDOC | Specifies the current block is a Call Back,
  1349. * and the mode is RTFDOC.
  1350. *
  1351. * @flag INTDOC | Specifies the current block is an Interrupt,
  1352. * and the mode is RTFDOC.
  1353. *
  1354. * @flag INTHELP | Specifies the current block is an Interrupt,
  1355. * and the mode is RTFHELP.
  1356. *
  1357. * @flag MASMDOC | Specifies the current block is a MASM,
  1358. * and the mode is RTFDOC.
  1359. *
  1360. * @flag MASMHELP | Specifies the current block is a MASM,
  1361. * and the mode is RTFHELP.
  1362. *
  1363. */
  1364. void
  1365. RTFCondOut(FILE *file, aCond *cond, int hselect)
  1366. {
  1367. RTFtextOutLn( file, cond->desc );
  1368. fprintf( file, "\\par\n" );
  1369. RTFRegOut(file, cond->regs,hselect);
  1370. // fprintf( file, "\\par\n" );
  1371. }
  1372. /*
  1373. * @doc INTERNAL RTF
  1374. *
  1375. * @func void | RTFParmOut | This function outputs the Parameters in the
  1376. * mode to the output file.
  1377. *
  1378. * @parm FILE * | file | Specifies the output file.
  1379. *
  1380. * @parm aParm * | parm | Specifies the list of Parameters.
  1381. *
  1382. * @parm int | hselect | Specifies the current mode of output.
  1383. *
  1384. * @flag FUNCHELP | Specifies the current block is a Function,
  1385. * and the mode is RTFHELP.
  1386. *
  1387. * @flag MSGHELP | Specifies the current block is a Message,
  1388. * and the mode is RTFHELP.
  1389. *
  1390. * @flag CBHELP | Specifies the current block is a Call Back,
  1391. * and the mode is RTFHELP.
  1392. *
  1393. * @flag FUNCDOC | Specifies the current block is a Function,
  1394. * and the mode is RTFDOC.
  1395. *
  1396. * @flag MSGDOC | Specifies the current block is a Message,
  1397. * and the mode is RTFDOC.
  1398. *
  1399. * @flag CBDOC | Specifies the current block is a Call Back,
  1400. * and the mode is RTFDOC.
  1401. *
  1402. * @flag INTDOC | Specifies the current block is an Interrupt,
  1403. * and the mode is RTFDOC.
  1404. *
  1405. * @flag INTHELP | Specifies the current block is an Interrupt,
  1406. * and the mode is RTFHELP.
  1407. *
  1408. * @flag MASMDOC | Specifies the current block is a MASM,
  1409. * and the mode is RTFDOC.
  1410. *
  1411. * @flag MASMHELP | Specifies the current block is a MASM,
  1412. * and the mode is RTFHELP.
  1413. *
  1414. */
  1415. void
  1416. RTFParmOut(FILE *file, aParm *parm, int hselect)
  1417. {
  1418. fSubBlock++;
  1419. switch(hselect)
  1420. {
  1421. case CBHELP: case MASMHELP:
  1422. case INTHELP: case FUNCHELP:
  1423. case MSGHELP:
  1424. fprintf( file, hparmhelp );
  1425. fprintf( file, p2ahelp );
  1426. fprintf( file, sepparmhelp);
  1427. fprintf( file, p2bhelp );
  1428. break;
  1429. case INTDOC:
  1430. case MASMDOC:
  1431. case FUNCDOC:
  1432. case CBDOC:
  1433. case MSGDOC:
  1434. fprintf( file, hparmdoc );
  1435. fprintf( file, p2a );
  1436. fprintf( file, sepparmdoc);
  1437. fprintf( file, p2b );
  1438. break;
  1439. }
  1440. while( parm )
  1441. {
  1442. switch(hselect)
  1443. {
  1444. case MASMHELP:
  1445. case INTHELP:
  1446. case FUNCHELP:
  1447. case CBHELP:
  1448. case MSGHELP:
  1449. fprintf( file, hparmhelp );
  1450. fprintf( file, "{\\i ");
  1451. RTFtextOut( file, parm->name );
  1452. fprintf( file, "} " );
  1453. fprintf( file, sepparmhelp);
  1454. fprintf( file, "{\\b ");
  1455. RTFtextOut( file, parm->type );
  1456. fprintf( file, "} "); // << note ' '
  1457. break;
  1458. case INTDOC:
  1459. case MASMDOC:
  1460. case FUNCDOC:
  1461. case CBDOC:
  1462. case MSGDOC:
  1463. fprintf( file, hparmdoc );
  1464. fprintf( file, "{\\b ");
  1465. RTFtextOut( file, parm->type );
  1466. fprintf( file, "} {\\i ");
  1467. RTFtextOut( file, parm->name );
  1468. fprintf( file, "} " );
  1469. fprintf( file, sepparmdoc);
  1470. break;
  1471. }
  1472. fprintf( file, "\n" );
  1473. // RTFtextOutLn( file, parm->desc );
  1474. RTFtextOut( file, parm->desc );
  1475. if(parm->flag)
  1476. {
  1477. // fprintf(file, "\\par\n"); // blank line before flags
  1478. RTFFlagOut(file, parm->flag, hselect, FLAGPARM);
  1479. }
  1480. if(outputType!=RTFHELP)
  1481. fprintf( file, "\\par\n");
  1482. parm = parm->next;
  1483. }
  1484. fSubBlock--;
  1485. }
  1486. /*
  1487. * @doc INTERNAL RTF
  1488. *
  1489. * @func void | RTFFlagOut | This function output a list of flags to
  1490. * the output file based on the current mode of output and where
  1491. * the flags are attached.
  1492. *
  1493. * @parm FILE * | file | Specifies the output file.
  1494. *
  1495. * @parm aFlag * | flag | Specifies the list of flags.
  1496. *
  1497. * @parm int | hselect | Specifies the current mode of output.
  1498. *
  1499. * @flag FUNCHELP | Specifies the current block is a Function,
  1500. * and the mode is RTFHELP.
  1501. *
  1502. * @flag MSGHELP | Specifies the current block is a Message,
  1503. * and the mode is RTFHELP.
  1504. *
  1505. * @flag CBHELP | Specifies the current block is a Call Back,
  1506. * and the mode is RTFHELP.
  1507. *
  1508. * @flag FUNCDOC | Specifies the current block is a Function,
  1509. * and the mode is RTFDOC.
  1510. *
  1511. * @flag MSGDOC | Specifies the current block is a Message,
  1512. * and the mode is RTFDOC.
  1513. *
  1514. * @flag CBDOC | Specifies the current block is a Call Back,
  1515. * and the mode is RTFDOC.
  1516. *
  1517. * @flag INTDOC | Specifies the current block is an Interrupt,
  1518. * and the mode is RTFDOC.
  1519. *
  1520. * @flag INTHELP | Specifies the current block is an Interrupt,
  1521. * and the mode is RTFHELP.
  1522. *
  1523. * @flag MASMDOC | Specifies the current block is a MASM,
  1524. * and the mode is RTFDOC.
  1525. *
  1526. * @flag MASMHELP | Specifies the current block is a MASM,
  1527. * and the mode is RTFHELP.
  1528. *
  1529. * @parm int | flags | Specifies where the flags are attached.
  1530. *
  1531. * @flag FLAGPARM | Flags are attached to Parameters.
  1532. *
  1533. * @flag FLAGRTN | Flags are attached to Return Description.
  1534. *
  1535. * @flag FLAGREG | Flags are attached to Register Description.
  1536. *
  1537. */
  1538. void
  1539. RTFFlagOut(FILE *file, aFlag *flag, int hselect, int flags)
  1540. {
  1541. int lih,lisep,fih,fisep;
  1542. char *parh,*parsep;
  1543. fSubBlock++;
  1544. assert(flag);
  1545. // everything should look more like this....
  1546. switch(hselect)
  1547. {
  1548. case MASMHELP:
  1549. case INTHELP:
  1550. case CBHELP:
  1551. case FUNCHELP:
  1552. case MSGHELP:
  1553. case UNIONHELP:
  1554. case STRUCTHELP:
  1555. if(flags==FLAGRTN)
  1556. {
  1557. fprintf( file, hparmhelp );
  1558. fprintf( file, p3a);
  1559. fprintf( file, sepparmhelp);
  1560. fprintf( file, p3b);
  1561. }
  1562. else
  1563. {
  1564. fprintf( file, hvalhelp );
  1565. fprintf( file, p3a);
  1566. fprintf( file, sepvalhelp);
  1567. fprintf( file, p3b);
  1568. }
  1569. // lih=5760;
  1570. // lisep=5760;
  1571. // fih=-2160;
  1572. // fisep=0;
  1573. // parh="plain";
  1574. // parsep="plain";
  1575. while( flag )
  1576. {
  1577. #if 1
  1578. fprintf(file,"\\par ");
  1579. #else
  1580. if(flags==FLAGRTN)
  1581. fprintf( file, hparmhelp );
  1582. else
  1583. fprintf( file, hvalhelp );
  1584. #endif
  1585. RTFtextOut( file, flag->name );
  1586. if(flags==FLAGRTN)
  1587. fprintf( file, sepparmhelp );
  1588. else
  1589. fprintf( file, sepvalhelp);
  1590. RTFtextOut( file, flag->desc );
  1591. // if(flag)
  1592. // fprintf( file, "\\par " );
  1593. flag = flag->next;
  1594. }
  1595. break;
  1596. case INTDOC:
  1597. case MASMDOC:
  1598. case CBDOC:
  1599. case FUNCDOC:
  1600. case MSGDOC:
  1601. case STRUCTDOC:
  1602. case UNIONDOC:
  1603. fprintf( file, hvaldoc );
  1604. fprintf( file, p3a);
  1605. fprintf( file, sepvaldoc);
  1606. fprintf( file, p3b);
  1607. // lih= (flags==FLAGRTN) ? 1080 : 2160;
  1608. // lisep=(flags==FLAGRTN) ? 3240 : 4320;
  1609. // fih=0;
  1610. // fisep=0;
  1611. // parh=(flags==FLAGRTN) ? "sbys\\ri3200" : "sbys\\ri4280";
  1612. // parsep="sbys";
  1613. while( flag )
  1614. {
  1615. fprintf( file, hvaldoc );
  1616. RTFtextOut( file, flag->name );
  1617. fprintf( file, sepvaldoc);
  1618. RTFtextOutLn( file, flag->desc );
  1619. fprintf( file, "\\par " );
  1620. flag = flag->next;
  1621. }
  1622. break;
  1623. }
  1624. fSubBlock--;
  1625. }
  1626. /*
  1627. * @doc INTERNAL RTF
  1628. *
  1629. * @func void | RTFFileInit | This routine is called before a list of files
  1630. * in a log structure are processed.
  1631. *
  1632. * @parm FILE * | file | Specifies the output file.
  1633. *
  1634. * @parm files | headfile | Specifies the list of files.
  1635. *
  1636. * @xref RTFGenIndex
  1637. */
  1638. void
  1639. RTFFileInit(FILE * phoutfile, logentry *curlog)
  1640. {
  1641. files curfile;
  1642. files headfile;
  1643. copylines(phoutfile,headrtf);
  1644. if(outputType==RTFDOC)
  1645. {
  1646. fprintf(phoutfile,"{\\header \\pard \\qc\\ri-1800\\li-1800\\sl0 ");
  1647. fprintf(phoutfile,"\\plain \\ul\\sl240 \\plain \\f26\\fs20 "
  1648. "Microsoft Confidential\\plain \\par}\n");
  1649. fprintf(phoutfile,"{\\footer \\pard \\qc\\ri-1800\\li-1800\\sl0"
  1650. "\\plain \\f26\\fs20 Page \\chpgn \\par}\n");
  1651. }
  1652. else if(outputType==RTFHELP && !fMMUserEd)
  1653. {
  1654. fprintf(phoutfile,"\\plain\\f26\\fs20\n");
  1655. fprintf(phoutfile,"#{\\footnote \\pard \\sl240 \\plain \\f26 #\\plain \\f26 ");
  1656. fprintf(phoutfile,"%s_index}\n","");
  1657. fprintf(phoutfile,"${\\footnote \\pard \\sl240 \\plain \\f26 $\\plain \\f26 ");
  1658. fprintf(phoutfile,"%s Index}\n","");
  1659. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1660. fprintf(phoutfile,"For information on how to use Help, press F1 or choose\n");
  1661. fprintf(phoutfile," Using Help from the Help menu.\\par\n");
  1662. headfile=curlog->outheadFile;
  1663. if(headfile)
  1664. {
  1665. fprintf(phoutfile,"\\plain\\f26\\fs24\\par\\par\n");
  1666. fprintf(phoutfile,"{\\b Functions Index}\n");
  1667. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1668. curfile=headfile;
  1669. while(curfile)
  1670. {
  1671. if(curfile->name)
  1672. RTFGenIndex(phoutfile, curfile);
  1673. curfile=curfile->next;
  1674. }
  1675. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1676. }
  1677. headfile=curlog->outheadMFile;
  1678. if(headfile)
  1679. {
  1680. fprintf(phoutfile,"\\plain\\f26\\fs24\\par\\par\n");
  1681. fprintf(phoutfile,"{\\b Messages Index}\n");
  1682. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1683. curfile=headfile;
  1684. while(curfile)
  1685. {
  1686. if(curfile->name)
  1687. RTFGenIndex(phoutfile, curfile);
  1688. curfile=curfile->next;
  1689. }
  1690. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1691. }
  1692. headfile=curlog->outheadSUFile;
  1693. if(headfile)
  1694. {
  1695. fprintf(phoutfile,"\\plain\\f26\\fs24\\par\\par\n");
  1696. fprintf(phoutfile,"{\\b Data Structures Index}\n");
  1697. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1698. curfile=headfile;
  1699. while(curfile)
  1700. {
  1701. if(curfile->name)
  1702. RTFGenIndex(phoutfile, curfile);
  1703. curfile=curfile->next;
  1704. }
  1705. fprintf(phoutfile,"\\plain\\f26\\fs20\\par\\par\n");
  1706. }
  1707. fprintf(phoutfile,"\\par Entire contents Copyright 1990, "
  1708. "Microsoft Crop. All rights reserved.\\par\\par\n");
  1709. }
  1710. return;
  1711. }
  1712. /*
  1713. * @doc INTERNAL RTF
  1714. *
  1715. * @func void | RTFGenIndex | This function outputs a reference to a block name.
  1716. *
  1717. * @parm FILE * | file | Specifies the output file.
  1718. *
  1719. * @parm files | curfile | Specifies the file structure with the block name.
  1720. *
  1721. */
  1722. void
  1723. RTFGenIndex(FILE * file, files curfile)
  1724. {
  1725. fprintf( file, "\\tab {\\uldb\\f26\\fs20 ");
  1726. fprintf( file, "%s",curfile->name);
  1727. fprintf( file, "}{\\v\\f26\\fs20 ");
  1728. fprintf( file, "%s",curfile->name);
  1729. fprintf( file, "}\\plain\\f26\\fs20\\par\n");
  1730. }
  1731. /*
  1732. * @doc INTERNAL RTF
  1733. *
  1734. * @func void | RTFFileProcess | This function is called for each file that
  1735. * is being processed.
  1736. *
  1737. * @parm FILE * | file | Specifies the output file.
  1738. *
  1739. * @parm files | curfile | Specifies the file.
  1740. *
  1741. */
  1742. void
  1743. RTFFileProcess(FILE * phoutfile, files curfile)
  1744. {
  1745. copyfile(phoutfile,curfile->filename);
  1746. return;
  1747. }
  1748. /*
  1749. * @doc INTERNAL RTF
  1750. *
  1751. * @func void | RTFFileDone | This function is called when all files in a list
  1752. * of files have been processed.
  1753. *
  1754. * @parm FILE * | file | Specifies the output file.
  1755. *
  1756. * @parm files | headfile | Specifies the file.
  1757. *
  1758. */
  1759. void
  1760. RTFFileDone(FILE * phoutfile, files headfile)
  1761. {
  1762. #if 0
  1763. if(blocksprocessed > 100 && outputType==RTFHELP)
  1764. {
  1765. fprintf( phoutfile, "\\par\\page K{\\footnote{\\up6 K} "); /* keyword */
  1766. fprintf( phoutfile, "mmGetCredits" );
  1767. fprintf( phoutfile, "} ${\\footnote{\\up6 $} "); /* section Title */
  1768. fprintf( phoutfile, "Credits" );
  1769. fprintf( phoutfile, "} +{\\footnote{\\up6 +} "); /* order */
  1770. fprintf( phoutfile, "CREDITS");
  1771. fprintf( phoutfile, "}\n");
  1772. fprintf( phoutfile, head0help);
  1773. fprintf( phoutfile, "Credits");
  1774. fprintf( phoutfile, ehead0help);
  1775. fprintf( phoutfile, "\\parAutomatic documentation Tool by\\par");
  1776. fprintf( phoutfile,
  1777. , " Russell Wiliams, Mark McCulley and Matt Saettler\\par\n");
  1778. fprintf( phoutfile, "\\par Windows SDK and Multimedia MDK documentation and generation program by Matt Saettler\n");
  1779. fprintf( phoutfile, "\\par Windows SDK layout and processing by Todd Laney and Matt Saettler\\par\n");
  1780. }
  1781. #endif
  1782. copylines(phoutfile,tailrtf);
  1783. return;
  1784. }
  1785. /*
  1786. * @doc INTERNAL RTF
  1787. *
  1788. * @func void | RTFLogInit | This function is called before a list of log
  1789. * files are to be processed.
  1790. *
  1791. * @parm FILE * | file | Specifies the output file.
  1792. *
  1793. * @parm logentry ** | pheadlog | Specifies the head of the log list.
  1794. *
  1795. */
  1796. void
  1797. RTFLogInit(FILE * phoutfile, logentry * * pheadlog)
  1798. {
  1799. FILE *fp;
  1800. char achbuf[180];
  1801. int j;
  1802. if(outputType==RTFHELP)
  1803. {
  1804. j=findlshortname(outputFile);
  1805. strncpy(achbuf,outputFile,j);
  1806. achbuf[j]=0;
  1807. strcat(achbuf,".hpj");
  1808. fp=fopen(achbuf,"r");
  1809. if(!fp) // file doesn't exist
  1810. {
  1811. fp=fopen(achbuf,"w");
  1812. assert(fp);
  1813. fprintf(fp,"; HPJ file automagically generated by DOCFMT\n");
  1814. fprintf(fp,"[files]\n");
  1815. fprintf(fp," %s\n",outputFile);
  1816. }
  1817. fclose(fp);
  1818. }
  1819. return;
  1820. }
  1821. /*
  1822. * @doc INTERNAL RTF
  1823. *
  1824. * @func void | RTFLogProcess | This function is called for each log to be processed.
  1825. *
  1826. * @parm FILE * | file | Specifies the output file.
  1827. *
  1828. * @parm logentry * | curlog | Specifies the current log.
  1829. *
  1830. */
  1831. void
  1832. RTFLogProcess(FILE * phoutfile, logentry * curlog)
  1833. {
  1834. return;
  1835. }
  1836. /*
  1837. * @doc INTERNAL RTF
  1838. *
  1839. * @func void | RTFLogDone | This function is called after a list of logs
  1840. * has been processed.
  1841. *
  1842. * @parm FILE * | file | Specifies the output file.
  1843. *
  1844. * @parm logentry * | headlog | Specifies the head of the log list.
  1845. *
  1846. */
  1847. void
  1848. RTFLogDone(FILE * phoutfile, logentry * headlog)
  1849. {
  1850. return;
  1851. }
  1852. /*
  1853. * @doc INTERNAL RTF
  1854. *
  1855. * @func void | copylines | This function appends the array of lines
  1856. * to the output file.
  1857. *
  1858. * @parm FILE * | file | Specifies the output file.
  1859. *
  1860. * @parm char ** | papch | Specifies the array of lines.
  1861. *
  1862. * @comm The list is terminated by a NULL pointer.
  1863. *
  1864. */
  1865. void
  1866. copylines(FILE * phoutfile, char **lines)
  1867. {
  1868. assert(lines);
  1869. while(*lines)
  1870. {
  1871. fprintf(phoutfile, "%s",*lines);
  1872. lines++;
  1873. }
  1874. return;
  1875. }