1 | /* |
2 | * |
3 | * Copyright (c) 1996-2003, Darren Hiebert <dhiebert at users dot sourceforge dot net> |
4 | * |
5 | * This source code is released for the public domain. |
6 | * |
7 | * This file defines the public interface for looking up tag entries in tag |
8 | * files. |
9 | * |
10 | * The functions defined in this interface are intended to provide tag file |
11 | * support to a software tool. The tag lookups provided are sufficiently fast |
12 | * enough to permit opening a sorted tag file, searching for a matching tag, |
13 | * then closing the tag file each time a tag is looked up (search times are |
14 | * on the order of hundreths of a second, even for huge tag files). This is |
15 | * the recommended use of this library for most tool applications. Adhering |
16 | * to this approach permits a user to regenerate a tag file at will without |
17 | * the tool needing to detect and resynchronize with changes to the tag file. |
18 | * Even for an unsorted 24MB tag file, tag searches take about one second. |
19 | */ |
20 | #ifndef READTAGS_H |
21 | #define READTAGS_H |
22 | |
23 | #ifdef __cplusplus |
24 | extern "C" { |
25 | #endif |
26 | |
27 | /* |
28 | * MACROS |
29 | */ |
30 | |
31 | /* Options for tagsSetSortType() */ |
32 | typedef enum { |
33 | TAG_UNSORTED, TAG_SORTED, TAG_FOLDSORTED |
34 | } sortType ; |
35 | |
36 | /* Options for tagsFind() */ |
37 | #define TAG_FULLMATCH 0x0 |
38 | #define TAG_PARTIALMATCH 0x1 |
39 | |
40 | #define TAG_OBSERVECASE 0x0 |
41 | #define TAG_IGNORECASE 0x2 |
42 | |
43 | /* |
44 | * DATA DECLARATIONS |
45 | */ |
46 | |
47 | typedef enum { TagFailure = 0, TagSuccess = 1 } tagResult; |
48 | |
49 | struct sTagFile; |
50 | |
51 | typedef struct sTagFile tagFile; |
52 | |
53 | /* This structure contains information about the tag file. */ |
54 | typedef struct { |
55 | |
56 | struct { |
57 | /* was the tag file successfully opened? */ |
58 | int opened; |
59 | |
60 | /* errno value when 'opened' is false */ |
61 | int error_number; |
62 | } status; |
63 | |
64 | /* information about the structure of the tag file */ |
65 | struct { |
66 | /* format of tag file (1 = original, 2 = extended) */ |
67 | short format; |
68 | |
69 | /* how is the tag file sorted? */ |
70 | sortType sort; |
71 | } file; |
72 | |
73 | |
74 | /* information about the program which created this tag file */ |
75 | struct { |
76 | /* name of author of generating program (may be null) */ |
77 | const char *author; |
78 | |
79 | /* name of program (may be null) */ |
80 | const char *name; |
81 | |
82 | /* URL of distribution (may be null) */ |
83 | const char *url; |
84 | |
85 | /* program version (may be null) */ |
86 | const char *version; |
87 | } program; |
88 | |
89 | } tagFileInfo; |
90 | |
91 | /* This structure contains information about an extension field for a tag. |
92 | * These exist at the end of the tag in the form "key:value"). |
93 | */ |
94 | typedef struct { |
95 | |
96 | /* the key of the extension field */ |
97 | const char *key; |
98 | |
99 | /* the value of the extension field (may be an empty string) */ |
100 | const char *value; |
101 | |
102 | } tagExtensionField; |
103 | |
104 | /* This structure contains information about a specific tag. */ |
105 | typedef struct { |
106 | |
107 | /* name of tag */ |
108 | const char *name; |
109 | |
110 | /* path of source file containing definition of tag */ |
111 | const char *file; |
112 | |
113 | /* address for locating tag in source file */ |
114 | struct { |
115 | /* pattern for locating source line |
116 | * (may be NULL if not present) */ |
117 | const char *pattern; |
118 | |
119 | /* line number in source file of tag definition |
120 | * (may be zero if not known) */ |
121 | unsigned long lineNumber; |
122 | } address; |
123 | |
124 | /* kind of tag (may by name, character, or NULL if not known) */ |
125 | const char *kind; |
126 | |
127 | /* is tag of file-limited scope? */ |
128 | short fileScope; |
129 | |
130 | /* miscellaneous extension fields */ |
131 | struct { |
132 | /* number of entries in `list' */ |
133 | unsigned short count; |
134 | |
135 | /* list of key value pairs */ |
136 | tagExtensionField *list; |
137 | } fields; |
138 | |
139 | } tagEntry; |
140 | |
141 | |
142 | /* |
143 | * FUNCTION PROTOTYPES |
144 | */ |
145 | |
146 | /* |
147 | * This function must be called before calling other functions in this |
148 | * library. It is passed the path to the tag file to read and a (possibly |
149 | * null) pointer to a structure which, if not null, will be populated with |
150 | * information about the tag file. If successful, the function will return a |
151 | * handle which must be supplied to other calls to read information from the |
152 | * tag file, and info.status.opened will be set to true. If unsuccessful, |
153 | * info.status.opened will be set to false and info.status.error_number will |
154 | * be set to the errno value representing the system error preventing the tag |
155 | * file from being successfully opened. |
156 | */ |
157 | extern tagFile *tagsOpen (const char *const filePath, tagFileInfo *const info); |
158 | |
159 | /* |
160 | * This function allows the client to override the normal automatic detection |
161 | * of how a tag file is sorted. Permissible values for `type' are |
162 | * TAG_UNSORTED, TAG_SORTED, TAG_FOLDSORTED. Tag files in the new extended |
163 | * format contain a key indicating whether or not they are sorted. However, |
164 | * tag files in the original format do not contain such a key even when |
165 | * sorted, preventing this library from taking advantage of fast binary |
166 | * lookups. If the client knows that such an unmarked tag file is indeed |
167 | * sorted (or not), it can override the automatic detection. Note that |
168 | * incorrect lookup results will result if a tag file is marked as sorted when |
169 | * it actually is not. The function will return TagSuccess if called on an |
170 | * open tag file or TagFailure if not. |
171 | */ |
172 | extern tagResult tagsSetSortType (tagFile *const file, const sortType type); |
173 | |
174 | /* |
175 | * Reads the first tag in the file, if any. It is passed the handle to an |
176 | * opened tag file and a (possibly null) pointer to a structure which, if not |
177 | * null, will be populated with information about the first tag file entry. |
178 | * The function will return TagSuccess another tag entry is found, or |
179 | * TagFailure if not (i.e. it reached end of file). |
180 | */ |
181 | extern tagResult tagsFirst (tagFile *const file, tagEntry *const entry); |
182 | |
183 | /* |
184 | * Step to the next tag in the file, if any. It is passed the handle to an |
185 | * opened tag file and a (possibly null) pointer to a structure which, if not |
186 | * null, will be populated with information about the next tag file entry. The |
187 | * function will return TagSuccess another tag entry is found, or TagFailure |
188 | * if not (i.e. it reached end of file). It will always read the first tag in |
189 | * the file immediately after calling tagsOpen(). |
190 | */ |
191 | extern tagResult tagsNext (tagFile *const file, tagEntry *const entry); |
192 | |
193 | /* |
194 | * Retrieve the value associated with the extension field for a specified key. |
195 | * It is passed a pointer to a structure already populated with values by a |
196 | * previous call to tagsNext(), tagsFind(), or tagsFindNext(), and a string |
197 | * containing the key of the desired extension field. If no such field of the |
198 | * specified key exists, the function will return null. |
199 | */ |
200 | extern const char *tagsField (const tagEntry *const entry, const char *const key); |
201 | |
202 | /* |
203 | * Find the first tag matching `name'. The structure pointed to by `entry' |
204 | * will be populated with information about the tag file entry. If a tag file |
205 | * is sorted using the C locale, a binary search algorithm is used to search |
206 | * the tag file, resulting in very fast tag lookups, even in huge tag files. |
207 | * Various options controlling the matches can be combined by bit-wise or-ing |
208 | * certain values together. The available values are: |
209 | * |
210 | * TAG_PARTIALMATCH |
211 | * Tags whose leading characters match `name' will qualify. |
212 | * |
213 | * TAG_FULLMATCH |
214 | * Only tags whose full lengths match `name' will qualify. |
215 | * |
216 | * TAG_IGNORECASE |
217 | * Matching will be performed in a case-insenstive manner. Note that |
218 | * this disables binary searches of the tag file. |
219 | * |
220 | * TAG_OBSERVECASE |
221 | * Matching will be performed in a case-senstive manner. Note that |
222 | * this enables binary searches of the tag file. |
223 | * |
224 | * The function will return TagSuccess if a tag matching the name is found, or |
225 | * TagFailure if not. |
226 | */ |
227 | extern tagResult tagsFind (tagFile *const file, tagEntry *const entry, const char *const name, const int options); |
228 | |
229 | /* |
230 | * Find the next tag matching the name and options supplied to the most recent |
231 | * call to tagsFind() for the same tag file. The structure pointed to by |
232 | * `entry' will be populated with information about the tag file entry. The |
233 | * function will return TagSuccess if another tag matching the name is found, |
234 | * or TagFailure if not. |
235 | */ |
236 | extern tagResult tagsFindNext (tagFile *const file, tagEntry *const entry); |
237 | |
238 | /* |
239 | * Call tagsTerminate() at completion of reading the tag file, which will |
240 | * close the file and free any internal memory allocated. The function will |
241 | * return TagFailure is no file is currently open, TagSuccess otherwise. |
242 | */ |
243 | extern tagResult tagsClose (tagFile *const file); |
244 | |
245 | #ifdef __cplusplus |
246 | } |
247 | #endif |
248 | |
249 | #endif |
250 | |
251 | /* vi:set tabstop=8 shiftwidth=4: */ |
252 | |