Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / fscope / fscope.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: fscope.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * @(#)fscope.c 1.1 02/05/02
46 * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved
47 * Use is subject to license terms.
48 */
49#include <stdio.h>
50#include <stdlib.h>
51#include <unistd.h>
52#include <string.h>
53#include <regexpr.h>
54
55#include "fscope.h"
56
57static char *help_msg =
58"fscope -f <index-file> [flags]\n"
59" Flags:\n"
60" -f <file> : source index file, (default is fscope.idx)\n"
61" -m <mode> : is the data format written to <output> or stdout\n"
62" -o <output> : spacify the target for a extract (-e) operation\n"
63" -t <text> : extract any reference matching <text>\n"
64" -s <text> : extract only string references matching <text>\n"
65" -d <symbol> : extract definitions matching <symbol>\n"
66" -c <symbol> : extract the caller information for <symbol>\n"
67" -C <symbol> : extract the symbols called by <symbol>\n"
68" -l <value> : extract symbols with refcounts less than <value>\n"
69" -g <value> : extract symbols with refcounts greater than <value>\n"
70" -a : extract all symbols in <mode> format\n"
71" -e : expand path using getenv()\n"
72" -r : use regexp to do symbol matching\n"
73" -R <root> : replace symbolic ${..} with <root>\n"
74" -i : interactive mode\n"
75" -v : verbose mode\n"
76" -O <file> : write current index file as <file>\n";
77
78static void
79extract_noop(extract_t *info)
80{
81 /* do nothing */
82}
83
84output_mode_t outputmodes[] = {
85 { "grep", extract_noop, xref_grep_format, extract_noop },
86 { "tag", xref_tag_init, xref_tag_format, xref_tag_fini },
87 { "etag", xref_tag_init, xref_etag_format, xref_tag_fini },
88 { NULL, NULL }
89};
90
91static void
92usage(void)
93{
94 output_mode_t *mptr = outputmodes;
95
96 printf(help_msg);
97 printf("\nSupported <modes> for -m are: ");
98 while (mptr->name != NULL) {
99 if (mptr->name[0] != '!') {
100 printf("%s ", mptr->name);
101 }
102 mptr++;
103 }
104 printf("\n");
105}
106
107char *
108expand_filename(extract_t *info, xref_t *cref)
109{
110 char *file = cref->file->name;
111
112 if (info->flags & FLAG_ABS_PATH) {
113 char *bp;
114 char *bp_env = "${BP}";
115 char *base;
116 if (info->root_buf != NULL) {
117 free(info->root_buf);
118 info->root_buf = NULL;
119 }
120 bp = strstr(file, bp_env);
121 if (bp == NULL) {
122 bp = file;
123 } else {
124 bp += strlen(bp_env);
125 }
126 if (info->root == NULL) {
127 base = getenv("BP");
128 if (base == NULL) {
129 base = "";
130 }
131 } else {
132 base = info->root;
133 }
134 file = info->root_buf = malloc(strlen(base) + strlen(bp) + 1);
135 sprintf(file, "%s%s", base, bp);
136 }
137 return (file);
138}
139
140static output_mode_t *
141select_output_mode(char *type)
142{
143 output_mode_t *mptr = outputmodes;
144 output_mode_t *found = NULL;
145
146 while (mptr->name != NULL) {
147 if (strcmp(mptr->name, type) == 0) {
148 found = mptr;
149 break;
150 }
151 mptr++;
152 }
153 return (found);
154}
155
156static int
157limit_item(extract_t *info, search_t *item)
158{
159 xref_t *cref = item->xref;
160
161 if ((cref->called_by.insert < info->lo) &&
162 (cref->called_by.insert > info->hi))
163 return (1);
164
165 return (0);
166}
167
168static void
169extract_item(extract_t *info, search_t *item)
170{
171 info->extract->update(info, item->xref);
172}
173
174static void
175dump_refs(extract_t *info, xref_t *cref, ref_t *rref)
176{
177 int j;
178 for (j = 0; j < rref->insert; j++) {
179 info->extract->update(info, rref->ptr[j]);
180 }
181}
182
183static void
184dump_callers(extract_t *info, search_t *item)
185{
186 xref_t *cref;
187
188 cref = item->xref;
189 dump_refs(info, cref, &cref->called_by);
190}
191
192static void
193dump_calls(extract_t *info, search_t *item)
194{
195 xref_t *cref;
196
197 cref = item->xref;
198 dump_refs(info, cref, &cref->calls);
199}
200
201int
202main(int argc, char *argv[])
203{
204 extern char *optarg;
205 extern int optind;
206 int c;
207 extract_t info;
208 search_t *list = NULL;
209 char *options = "hf:m:d:c:C:o:il:g:as:erR:t:v";
210 info.lo = -1;
211 info.hi = -1;
212 info.flags = 0;
213 info.symbol = NULL;
214 info.state = NULL;
215 info.indexfile = NULL;
216 info.outputfile = NULL;
217 info.private = NULL;
218 info.root = NULL;
219
220 info.extract = select_output_mode("grep");
221 while ((c = getopt(argc, argv, options)) != EOF)
222 switch (c) {
223
224 case 'h':
225 usage();
226 exit(1);
227 break;
228
229 case 'm':
230 info.extract = select_output_mode(optarg);
231 if (info.extract == NULL) {
232 fprintf(stderr,
233 "Unsupported extract mode: %s\n",
234 optarg);
235 usage();
236 exit(1);
237 }
238 break;
239
240 case 'f':
241 info.indexfile = optarg;
242 break;
243
244 case 'd':
245 info.symbol = optarg;
246 info.type = TYPE_DEFINE;
247 break;
248
249 case 's':
250 info.symbol = optarg;
251 info.type = TYPE_STRING;
252 break;
253
254 case 't':
255 info.symbol = optarg;
256 info.type = TYPE_TEXT;
257 break;
258
259 case 'c':
260 info.symbol = optarg;
261 info.type = TYPE_CALLERS;
262 break;
263
264 case 'C':
265 info.symbol = optarg;
266 info.type = TYPE_CALLS;
267 break;
268
269 case 'o':
270 info.outputfile = optarg;
271 break;
272
273 case 'r':
274 info.flags |= FLAG_REGEXP;
275 break;
276
277 case 'i':
278 info.type = TYPE_INTERACT;
279 info.extract = select_output_mode("!interact");
280 break;
281
282 case 'l':
283 info.type = TYPE_LIMIT;
284 info.lo = atoi(optarg);
285 break;
286
287 case 'g':
288 info.type = TYPE_LIMIT;
289 info.hi = atoi(optarg);
290 break;
291
292 case 'a':
293 info.type = TYPE_LIMIT;
294 info.hi = -1;
295 info.lo = 100000;
296 break;
297
298 case 'R':
299 info.flags |= FLAG_ABS_PATH;
300 info.root = optarg;
301 break;
302
303 case 'e':
304 info.flags |= FLAG_ABS_PATH;
305 info.root = NULL;
306 break;
307
308 case 'v':
309 info.flags |= FLAG_VERBOSE;
310 break;
311
312 default:
313 break;
314 }
315
316 if (info.indexfile == NULL) {
317 info.indexfile = "fscope.idx";
318 }
319 info.state = xref_load_file(info.indexfile,
320 (info.flags & FLAG_VERBOSE));
321 if (info.state == NULL) {
322 fprintf(stderr, "%s: failed to load\n", info.indexfile);
323 exit(1);
324 }
325 if (info.type == TYPE_INTERACT) {
326 xref_interactive_mode(&info);
327 } else {
328 if (info.outputfile == NULL) {
329 info.outfd = stdout;
330 } else {
331 info.outfd = fopen(info.outputfile, "w");
332 if (info.outfd == NULL) {
333 fprintf(stderr, "Can create outputfile: %s\n",
334 info.outputfile);
335 exit(1);
336 }
337 }
338 info.extract->init(&info);
339 switch (info.type) {
340 case TYPE_LIMIT:
341 if (info.symbol == NULL) {
342 info.symbol = ".*";
343 info.flags |= FLAG_REGEXP;
344 }
345 list = build_searchlist(&info, NULL, XREF_DEFINITION);
346 list = search_list(&info, 1, list, limit_item);
347 iterate_list(&info, list, extract_item);
348 break;
349
350 case TYPE_CALLS:
351 list = build_searchlist(&info, NULL, XREF_DEFINITION);
352 iterate_list(&info, list, dump_calls);
353 break;
354
355 case TYPE_CALLERS:
356 list = build_searchlist(&info, NULL, XREF_DEFINITION);
357 iterate_list(&info, list, dump_callers);
358 break;
359
360 case TYPE_DEFINE:
361 list = build_searchlist(&info, NULL, XREF_DEFINITION);
362 iterate_list(&info, list, extract_item);
363 break;
364
365 case TYPE_STRING:
366 list = build_searchlist(&info, NULL, XREF_STRING);
367 iterate_list(&info, list, extract_item);
368 break;
369
370 case TYPE_TEXT:
371 list = build_searchlist(&info, NULL,
372 (XREF_STRING | XREF_DEFINITION));
373 iterate_list(&info, list, extract_item);
374 break;
375
376 default:
377 break;
378 }
379 if (list != NULL) {
380 free_searchlist(list);
381 list = NULL;
382 }
383 info.extract->fini(&info);
384 if (info.outputfile != NULL) {
385 fclose(info.outfd);
386 }
387 }
388 xref_free_state(info.state);
389 return (0);
390}