include-afsconfig-before-param-h-20010712
[openafs.git] / src / export / symtab.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * symtab -     symbol table routines
12  */
13 #include <afsconfig.h>
14 #include <afs/param.h>
15
16 RCSID("$Header$");
17
18 #include "sys/types.h"
19 #include "sym.h"
20
21 /*
22  * using the toc_syment structure, that we fabricate:
23  *      sym->n_offset is the string pointer
24  */
25 #define sym_off(sym)    ((sym)->n_offset)
26 #define sym_str(sym)    \
27         ((sym)->n_zeroes == 0 ? (char *) sym_off(sym) : (sym)->n_name)
28
29 sym_t *
30 sym_lookup(name, value)
31 char *name; {
32         static sym_t *symsrch(), *search();
33         char buf[64];
34         register sym_t *sym;
35
36         if (name) {
37                 /*
38                  * Heuristic:
39                  * first, try just the name. if that fails, try with a
40                  * prefix '.', and failing that, a prefix '_'.
41                  */
42                 if (sym = symsrch(name))
43                         return sym;
44                 bcopy(name, buf+1, sizeof (buf) - 2);
45                 buf[0] = '.';
46
47                 if (sym = symsrch(buf))
48                         return sym;
49
50                 buf[0] = '_';
51
52                 return symsrch(buf);
53         } else
54                 return search(value);
55 }
56
57 static sym_t *
58 search(addr)
59 unsigned addr; {
60         register sym_t *sp;
61         register sym_t *save;
62         unsigned value;
63
64         value = 0;
65         save  = 0;
66
67         for (sp = toc_syms; sp < &toc_syms[toc_nsyms]; ++sp) {
68                 if (sp->n_value <= addr && sp->n_value >= value) {
69                         value = sp->n_value;
70                         save  = sp;
71                         if (sp->n_value == addr)
72                                 break;
73                 }
74         }
75         return save ? sym_flex(save) : 0;
76 }
77
78 static sym_t *
79 symsrch(s)
80 register char *s; {
81         register sym_t *sp;
82         register sym_t *found;
83         register len;
84         register char *p;
85
86         /*
87          * determine length of symbol
88          */
89         for (len = 0, p = s; *p; ++p)
90                 ++len;
91
92         found = 0;
93         for (sp = toc_syms; sp < &toc_syms[toc_nsyms]; ++sp) {
94                 /*
95                  * exact matches preferred
96                  */
97                 if (strcmp(sym_str(sp), s) == 0) {
98                         found = sp;
99                         break;
100                 }
101                 /*
102                  * otherwise, prefices might interest us.
103                  */
104                 if (!found && (strncmp(sym_str(sp), s, len) == 0)) {
105                         found = sp;
106                         continue;
107                 }
108         }
109
110         return found ? sym_flex(found) : 0;
111 }
112
113 /*
114  * sym_flex -   convert a symbol so that there is no distinction between
115  *              flex-string and non flex-string format.
116  *
117  * Input:
118  *      sym     -       ^ to symbol table entry
119  *
120  * Returns:
121  *      ^ to static location containing modified symbol.
122  */
123 sym_t *
124 sym_flex(sym)
125 register sym_t *sym; {
126         static sym_t symbol;
127         static char name[48];
128
129         strncpy(name, sym_str(sym), sizeof (name) - 1);
130
131         if (sym->n_zeroes != 0)
132                 name[8] = 0;    /* make sure that we truncate correctly */
133
134         symbol          = *sym;
135         symbol.n_zeroes = 0;
136         symbol.n_nptr   = name;
137
138         return &symbol;
139 }