Print this page
new smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/ctags.c
+++ new/usr/src/tools/smatch/src/ctags.c
1 1 /*
2 2 * Sparse Ctags
3 3 *
4 4 * Ctags generates tags from preprocessing results.
5 5 *
6 6 * Copyright (C) 2006 Christopher Li
7 7 *
8 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 9 * of this software and associated documentation files (the "Software"), to deal
10 10 * in the Software without restriction, including without limitation the rights
11 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 12 * copies of the Software, and to permit persons to whom the Software is
13 13 * furnished to do so, subject to the following conditions:
14 14 *
15 15 * The above copyright notice and this permission notice shall be included in
16 16 * all copies or substantial portions of the Software.
17 17 *
18 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 24 * THE SOFTWARE.
25 25 */
26 26 #include <stdlib.h>
27 27 #include <stdio.h>
28 28 #include <string.h>
29 29 #include <unistd.h>
30 30 #include <fcntl.h>
31 31
32 32 #include "parse.h"
33 33 #include "scope.h"
34 34
35 35 static struct symbol_list *taglist = NULL;
36 36
37 37 static void examine_symbol(struct symbol *sym);
38 38
39 39 #define MAX(_x,_y) ((_x) > (_y) ? (_x) : (_y))
40 40
41 41 static int cmp_sym(const void *m, const void *n)
42 42 {
43 43 const struct ident *a = ((const struct symbol *)m)->ident;
44 44 const struct ident *b = ((const struct symbol *)n)->ident;
45 45 int ret = strncmp(a->name, b->name, MAX(a->len, b->len));
46 46 if (!ret) {
47 47 const struct position a_pos = ((const struct symbol *)m)->pos;
48 48 const struct position b_pos = ((const struct symbol *)n)->pos;
49 49
50 50 ret = strcmp(stream_name(a_pos.stream),
51 51 stream_name(b_pos.stream));
52 52 if (!ret)
53 53 return a_pos.line < b_pos.line;
54 54 }
55 55 return ret;
56 56 }
57 57
58 58 static void show_tag_header(FILE *fp)
59 59 {
60 60 fprintf(fp, "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n");
61 61 fprintf(fp, "!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n");
62 62 fprintf(fp, "!_TAG_PROGRAM_AUTHOR\tChristopher Li\t/sparse@chrisli.org/\n");
63 63 fprintf(fp, "!_TAG_PROGRAM_NAME\tSparse Ctags\t//\n");
64 64 fprintf(fp, "!_TAG_PROGRAM_URL\thttp://www.kernel.org/pub/software/devel/sparse/\t/official site/\n");
65 65 fprintf(fp, "!_TAG_PROGRAM_VERSION\t0.01\t//\n");
66 66 }
67 67
68 68 static inline void show_symbol_tag(FILE *fp, struct symbol *sym)
69 69 {
70 70 fprintf(fp, "%s\t%s\t%d;\"\t%c\tfile:\n", show_ident(sym->ident),
71 71 stream_name(sym->pos.stream), sym->pos.line, (int)sym->kind);
72 72 }
73 73
74 74 static void show_tags(struct symbol_list *list)
75 75 {
76 76 struct symbol *sym;
77 77 struct ident *ident = NULL;
78 78 struct position pos = {};
79 79 static const char *filename;
80 80 FILE *fp;
81 81
82 82 if (!list)
83 83 return;
84 84
85 85 fp = fopen("tags", "w");
86 86 if (!fp) {
87 87 perror("open tags file");
88 88 return;
89 89 }
90 90 show_tag_header(fp);
91 91 FOR_EACH_PTR(list, sym) {
92 92 if (ident == sym->ident && pos.line == sym->pos.line &&
93 93 !strcmp(filename, stream_name(sym->pos.stream)))
94 94 continue;
95 95
96 96 show_symbol_tag(fp, sym);
97 97 ident = sym->ident;
98 98 pos = sym->pos;
99 99 filename = stream_name(sym->pos.stream);
100 100 } END_FOR_EACH_PTR(sym);
101 101 fclose(fp);
102 102 }
103 103
104 104 static inline void add_tag(struct symbol *sym)
105 105 {
106 106 if (sym->ident && !sym->visited) {
107 107 sym->visited = 1;
108 108 add_symbol(&taglist, sym);
109 109 }
110 110 }
111 111
112 112 static inline void examine_members(struct symbol_list *list)
113 113 {
114 114 struct symbol *sym;
115 115
116 116 FOR_EACH_PTR(list, sym) {
117 117 sym->kind = 'm';
118 118 examine_symbol(sym);
119 119 } END_FOR_EACH_PTR(sym);
120 120 }
121 121
122 122 static void examine_symbol(struct symbol *sym)
123 123 {
124 124 struct symbol *base = sym;
125 125
126 126 if (!sym || sym->visited)
127 127 return;
↓ open down ↓ |
127 lines elided |
↑ open up ↑ |
128 128 if (sym->ident && sym->ident->reserved)
129 129 return;
130 130 if (sym->type == SYM_KEYWORD || sym->type == SYM_PREPROCESSOR)
131 131 return;
132 132
133 133 add_tag(sym);
134 134 base = sym->ctype.base_type;
135 135
136 136 switch (sym->type) {
137 137 case SYM_NODE:
138 - if (base->type == SYM_FN)
138 + if (base && base->type == SYM_FN)
139 139 sym->kind = 'f';
140 140 examine_symbol(base);
141 141 break;
142 142 case SYM_STRUCT:
143 143 sym->kind = 's';
144 144 examine_members(sym->symbol_list);
145 145 break;
146 146 case SYM_UNION:
147 147 sym->kind = 'u';
148 148 examine_members(sym->symbol_list);
149 149 break;
150 150 case SYM_ENUM:
151 151 sym->kind = 'e';
152 152 case SYM_PTR:
153 153 case SYM_TYPEOF:
154 154 case SYM_BITFIELD:
155 155 case SYM_FN:
156 156 case SYM_ARRAY:
157 157 examine_symbol(sym->ctype.base_type);
158 158 break;
159 159 case SYM_BASETYPE:
160 160 break;
161 161
162 162 default:
163 163 die("unknown symbol %s namespace:%d type:%d\n", show_ident(sym->ident),
164 164 sym->namespace, sym->type);
165 165 }
166 166 if (!sym->kind)
167 167 sym->kind = 'v';
168 168 return;
169 169 }
170 170
171 171 static void examine_namespace(struct symbol *sym)
172 172 {
173 173 if (sym->visited)
174 174 return;
175 175 if (sym->ident && sym->ident->reserved)
176 176 return;
177 177
178 178 switch(sym->namespace) {
179 179 case NS_KEYWORD:
180 180 case NS_PREPROCESSOR:
181 181 return;
182 182 case NS_LABEL:
183 183 sym->kind = 'l';
184 184 break;
185 185 case NS_MACRO:
186 186 case NS_UNDEF:
187 187 sym->kind = 'd';
188 188 break;
189 189 case NS_TYPEDEF:
190 190 sym->kind = 't';
191 191 case NS_SYMBOL:
192 192 case NS_STRUCT:
193 193 examine_symbol(sym);
194 194 break;
195 195 default:
196 196 die("unknown namespace %d symbol:%s type:%d\n", sym->namespace,
197 197 show_ident(sym->ident), sym->type);
198 198 }
199 199 add_tag(sym);
200 200 }
201 201
202 202 static inline void examine_symbol_list(struct symbol_list *list)
203 203 {
204 204 struct symbol *sym;
205 205
206 206 if (!list)
207 207 return;
208 208 FOR_EACH_PTR(list, sym) {
↓ open down ↓ |
60 lines elided |
↑ open up ↑ |
209 209 examine_namespace(sym);
210 210 } END_FOR_EACH_PTR(sym);
211 211 }
212 212
213 213 int main(int argc, char **argv)
214 214 {
215 215 struct string_list *filelist = NULL;
216 216 char *file;
217 217
218 218 examine_symbol_list(sparse_initialize(argc, argv, &filelist));
219 - FOR_EACH_PTR_NOTAG(filelist, file) {
219 + FOR_EACH_PTR(filelist, file) {
220 220 sparse(file);
221 221 examine_symbol_list(file_scope->symbols);
222 - } END_FOR_EACH_PTR_NOTAG(file);
222 + } END_FOR_EACH_PTR(file);
223 223 examine_symbol_list(global_scope->symbols);
224 224 sort_list((struct ptr_list **)&taglist, cmp_sym);
225 225 show_tags(taglist);
226 226 return 0;
227 227 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX