1 /*
2  *   Copyright (c) 2000-2001, Jérôme Plût
3  *   Copyright (c) 2006, Enrico Tröger
4  *
5  *   This source code is released for free distribution under the terms of the
6  *   GNU General Public License.
7  *
8  *   This module contains functions for generating tags for source files
9  *   for docbook files(based on TeX parser from Jérôme Plût).
10  */
11 
12 /*
13 *   INCLUDE FILES
14 */
15 #include "general.h"	/* must always come first */
16 
17 #include <ctype.h>
18 #include <string.h>
19 
20 #include "parse.h"
21 #include "read.h"
22 #include "vstring.h"
23 #include "routines.h"
24 
25 /*
26 *   DATA DEFINITIONS
27 */
28 typedef enum {
29 	K_CHAPTER,
30 	K_SECTION,
31 	K_SECT1,
32 	K_SECT2,
33 	K_SECT3,
34 	K_APPENDIX
35 } docbookKind;
36 
37 static kindDefinition DocBookKinds [] = {
38 	{ true,  'f', "function",   "chapters"},
39 	{ true,  'c', "class",      "sections"},
40 	{ true,  'm', "member",     "sect1"},
41 	{ true,  'd', "macro",      "sect2"},
42 	{ true,  'v', "variable",   "sect3"},
43 	{ true,  's', "struct",     "appendix"}
44 };
45 
46 /*
47 *   FUNCTION DEFINITIONS
48 */
49 
getWord(const char * ref,const char ** ptr)50 static int getWord(const char *ref, const char **ptr)
51 {
52 	const char *p = *ptr;
53 
54 	while ((*ref != '\0') && (*p != '\0') && (*ref == *p)) ref++, p++;
55 
56 	if (*ref) return false;
57 
58 	*ptr = p;
59 	return true;
60 }
61 
62 
createTag(docbookKind kind,const char * buf)63 static void createTag(docbookKind kind, const char *buf)
64 {
65 	vString *name;
66 
67 	if (*buf == '>') return;
68 
69 	buf = strstr(buf, "id=\"");
70 	if (buf == NULL) return;
71 	buf += 4;
72 	if (*buf == '"') return;
73 	name = vStringNew();
74 
75 	do
76 	{
77 		vStringPut(name, (int) *buf);
78 		++buf;
79 	} while ((*buf != '\0') && (*buf != '"'));
80 	makeSimpleTag(name, kind);
81 }
82 
83 
findDocBookTags(void)84 static void findDocBookTags(void)
85 {
86 	const char *line;
87 
88 	while ((line = (const char*)readLineFromInputFile()) != NULL)
89 	{
90 		const char *cp = line;
91 
92 		for (; *cp != '\0'; cp++)
93 		{
94 			if (*cp == '<')
95 			{
96 				cp++;
97 
98 				/* <section id="..."> */
99 				if (getWord("section", &cp))
100 				{
101 					createTag(K_SECTION, cp);
102 					continue;
103 				}
104 				/* <sect1 id="..."> */
105 				if (getWord("sect1", &cp))
106 				{
107 					createTag(K_SECT1, cp);
108 					continue;
109 				}
110 				/* <sect2 id="..."> */
111 				if (getWord("sect2", &cp))
112 				{
113 					createTag(K_SECT2, cp);
114 					continue;
115 				}
116 				/* <sect3 id="..."> */
117 				if (getWord("sect3", &cp) ||
118 					getWord("sect4", &cp) ||
119 					getWord("sect5", &cp))
120 				{
121 					createTag(K_SECT3, cp);
122 					continue;
123 				}
124 				/* <chapter id="..."> */
125 				if (getWord("chapter", &cp))
126 				{
127 					createTag(K_CHAPTER, cp);
128 					continue;
129 				}
130 				/* <appendix id="..."> */
131 				if (getWord("appendix", &cp))
132 				{
133 					createTag(K_APPENDIX, cp);
134 					continue;
135 				}
136 			}
137 		}
138 	}
139 }
140 
DocBookParser(void)141 extern parserDefinition* DocBookParser (void)
142 {
143 	static const char *const extensions [] = { "sgml", "docbook", NULL };
144 	parserDefinition* def = parserNew ("Docbook");
145 	def->extensions = extensions;
146 	def->kindTable  = DocBookKinds;
147 	def->kindCount  = ARRAY_SIZE (DocBookKinds);
148 	def->parser     = findDocBookTags;
149 	return def;
150 }
151 
152