VirtualBox

source: kBuild/trunk/doc/docdesign.c@ 14

Last change on this file since 14 was 14, checked in by bird, 23 years ago

Initial coding.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/* $Id: docdesign.c 14 2002-10-16 22:22:21Z bird $
2 *
3 * Documentation generator.
4 *
5 * Copyright (c) 2002 knut st. osmundsen <bird@anduin.net>
6 *
7 *
8 * This file is part of kBuild.
9 *
10 * kBuild is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * kBuild is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with kBuild; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <string.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <errno.h>
34
35
36/*******************************************************************************
37* Structures and Typedefs *
38*******************************************************************************/
39typedef struct _Section
40{
41 struct _Section *pNext; /* Next Section. */
42 int iLevel; /* 0 is @design, 1 is @subsection and so on. */
43 char *pszHeader;
44 char *pszText; /* Content of the section. */
45 int cchText;
46} SECTION, *PSECTION;
47
48
49/*******************************************************************************
50* Global Variables *
51*******************************************************************************/
52PSECTION pSections = NULL;
53PSECTION pSectionsTail = NULL;
54
55
56/**
57 * Reads the file parsing out the @design and @sub[..]section
58 * parts putting them into the pSections list.
59 */
60int ParseFile(const char *pszFilename)
61{
62 int rc = 0;
63 FILE * phFile;
64
65 /*
66 * Open the file.
67 */
68 phFile = fopen(pszFilename, "r");
69 if (phFile)
70 {
71 static char szLine[0x10000];
72 enum {enmUnknown, enmSection, enmSectionClosing}
73 enmState = enmUnknown;
74 PSECTION pCurSection = NULL;
75
76 /*
77 * Read the file line by line. looking for @design and @sub[..]section.
78 */
79 while (fgets(szLine, sizeof(szLine), phFile))
80 {
81 int fNew = 0;
82 int iLevel = 0;
83 char *psz = szLine;
84 char *pszEnd = &szLine[strlen(szLine) - 1];
85 /*
86 * Strip off any ' ', '\t', '\/\*', '*' and '//' from start.
87 * Strip off any ' ', '\t', '\n', '\r', '\*\/' and '*' from end
88 * Need to check for closing comment too.
89 */
90 while ( *psz == '*'
91 || *psz == ' '
92 || *psz == '\t'
93 || (*psz == '/' && (psz[1] == '*' || psz[1] == '/')))
94 {
95 if (*psz++ == '/')
96 psz++;
97 }
98
99 while ( pszEnd >= psz
100 && ( *pszEnd == '*'
101 || *pszEnd == ' '
102 || *pszEnd == '\t'
103 || *pszEnd == '\r'
104 || *pszEnd == '\n'
105 )
106 )
107 {
108 *pszEnd-- = '\0';
109 }
110 if (pszEnd > psz && !strcmp(&pszEnd[-1], "*/") && enmState == enmSection)
111 enmState = enmSectionClosing;
112 while ( pszEnd >= psz
113 && ( *pszEnd == '*'
114 || *pszEnd == ' '
115 || *pszEnd == '\t'
116 || *pszEnd == '\n'
117 || *pszEnd == '\r'
118 || (*pszEnd == '/' && pszEnd > psz && pszEnd[-1] == '*')
119 )
120 )
121 {
122 if (*pszEnd != '/')
123 pszEnd--;
124 *pszEnd-- = '\0';
125 }
126
127
128 /*
129 * Look for tag.
130 */
131 if (!strncmp(psz, "@design", 7))
132 {
133 fNew = 1;
134 iLevel = 0;
135 }
136 else if (!strncmp(psz, "@sub", 4))
137 {
138 char *psz2 = psz + 4;
139 fNew = 1;
140 iLevel = 1;
141 while (!strncmp(psz2, "sub", 3))
142 {
143 psz2 += 3;
144 iLevel++;
145 }
146 }
147
148 /*
149 * Action
150 */
151 if (fNew)
152 {
153 char *psz2;
154 /*
155 * New Section.
156 * Change state.
157 * Allocate new section struct, init it and link it into the list.
158 * Get section header.
159 */
160 if (enmState != enmSectionClosing)
161 enmState = enmSection;
162
163 pCurSection = malloc(sizeof(*pCurSection));
164 memset(pCurSection, 0, sizeof(*pCurSection));
165 pCurSection->iLevel = iLevel;
166 if (pSectionsTail)
167 pSectionsTail = pSectionsTail->pNext = pCurSection;
168 else
169 pSections = pSectionsTail = pCurSection;
170
171 psz2 = strpbrk(psz, " \t");
172 if (psz2)
173 {
174 while (*psz2 == ' ' || *psz == '\t')
175 psz2++;
176 if (*psz)
177 pCurSection->pszHeader = strdup(psz2);
178 }
179 }
180 else if (enmState == enmSection || enmState == enmSectionClosing)
181 {
182 /*
183 * Add text to current section
184 */
185 int cch = strlen(psz);
186 if (!cch && pCurSection->cchText)
187 {
188 psz = "<p>";
189 cch = strlen(psz);
190 }
191
192 if (cch)
193 {
194 pCurSection->pszText = realloc(pCurSection->pszText, pCurSection->cchText + cch + 2);
195 pCurSection->pszText[pCurSection->cchText++] = '\n';
196 strcpy(&pCurSection->pszText[pCurSection->cchText], psz);
197 pCurSection->cchText += cch;
198 }
199 }
200
201 /*
202 * State transition.
203 */
204 if (enmState == enmSectionClosing)
205 enmState = enmUnknown;
206
207 } /* while fgets */
208
209 fclose(phFile);
210 }
211 else
212 {
213 fprintf(stderr, "error: failed to open %s. errno=%d\n", pszFilename, errno);
214 rc = errno;
215 }
216
217 return rc;
218}
219
220
221/**
222 * Keep track and formats section level.
223 */
224void SectionNumber(int iLevel, int *paiSections, char *pszSection)
225{
226 int i;
227
228 paiSections[iLevel]++;
229 for (i = iLevel + 1; i < 100; i++)
230 paiSections[i] = 0;
231
232 sprintf(pszSection, "%d", paiSections[0]);
233 if (iLevel == 0)
234 strcat(pszSection, ".0");
235 else
236 {
237 for (i = 1; i <= iLevel; i++)
238 sprintf(&pszSection[strlen(pszSection)], ".%d", paiSections[i]);
239 }
240}
241
242
243/**
244 * Outputs the section stuff to stdout as HTML.
245 */
246int MakeHTML(void)
247{
248 int aiSections[100];
249 char szSection[1024];
250 PSECTION pCurSection;
251
252 #if 0
253 /* debug */
254 for (pCurSection = pSections; pCurSection; pCurSection = pCurSection->pNext)
255 fprintf(stderr, "debug: level=%d cchText=%-4d header=%s \n",
256 pCurSection->iLevel, pCurSection->cchText, pCurSection->pszHeader);
257 #endif
258
259 /*
260 * Header
261 */
262 printf("<!-- Generate by docdesign -->\n"
263 "<head>\n"
264 "<title></title>\n"
265 "\n"
266 "<body>\n"
267 );
268
269 /*
270 * Content
271 */
272 printf("<a name=content><h2>Content</h2></a>\n"
273 "<ul>\n"
274 );
275 memset(&aiSections[0], 0, sizeof(aiSections));
276 for (pCurSection = pSections; pCurSection; pCurSection = pCurSection->pNext)
277 {
278 SectionNumber(pCurSection->iLevel, &aiSections[0], szSection);
279 printf(" <li><a href=\"#%s\">%s %s</a>\n",
280 szSection, szSection, pCurSection->pszHeader);
281 }
282 printf("</ul>\n"
283 "\n");
284
285 /*
286 * Sections.
287 */
288 memset(&aiSections[0], 0, sizeof(aiSections));
289 for (pCurSection = pSections; pCurSection; pCurSection = pCurSection->pNext)
290 {
291 int iHNumber = min(pCurSection->iLevel + 1, 5);
292 SectionNumber(pCurSection->iLevel, &aiSections[0], szSection);
293 printf("<p><br><p>\n"
294 "<a href=#content><a name=%s><h%d>%s %s</h%d></a></a>\n"
295 "\n"
296 "%s",
297 szSection, iHNumber, szSection, pCurSection->pszHeader, iHNumber,
298 pCurSection->pszText);
299 }
300 printf("</ul>\n"
301 "\n");
302
303
304 /* footer */
305 printf("</body>\n"
306 "</head>\n");
307
308 return -1;
309}
310
311
312int main(int argc, char **argv)
313{
314 int rc;
315 int argi;
316
317 /*
318 * Parse arguments.
319 */
320 for (argi = 1, rc = 0; !rc && argi < argc; argi++)
321 {
322 rc = ParseFile(argv[argi]);
323 }
324
325 if (!rc)
326 rc = MakeHTML();
327
328 return rc;
329}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette