Link with C++ linker
[oweals/cde.git] / cde / programs / dtksh / symbolic.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: symbolic.c /main/4 1995/11/01 15:56:54 rswiston $ */
24 /*      Copyright (c) 1991, 1992 UNIX System Laboratories, Inc. */
25 /*      All Rights Reserved     */
26
27 /*      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF    */
28 /*      UNIX System Laboratories, Inc.                  */
29 /*      The copyright notice above does not evidence any       */
30 /*      actual or intended publication of such source code.    */
31
32 #include        "name.h"
33 #include        "shell.h"
34 #include "stdio.h"
35 #include "exksh.h" /* which includes sys/types.h */
36 #include "struct.h" /* which includes sys/types.h */
37 #include <string.h>
38 #include "msgs.h"
39
40 struct symlist *Symlist = NULL;
41 int Nsymlist;
42
43 /*
44 ** There is an implicit dirty trick going on here.  It is effective,
45 ** efficient and will work anywhere but it is tricky.  A memtbl has
46 ** strings in it.  The fact that a byte-by-byte comparison is being
47 ** done on a memtbl means that pointers are being compared.  This
48 ** means that EVERY UNIQUE MEMTBL SHOULD HAVE SOME UNIQUE FIELD (i.e.
49 ** in this case, the string for the name field).  If somebody uses
50 ** an algorithm in do_struct() that saves string space (by seeing if
51 ** the same string is lying around) this code will break and an ID
52 ** field will be necessary to maintain uniqueness.
53 */
54
55
56 struct symlist *
57 fsymbolic(
58         struct memtbl *tbl )
59 {
60         int i;
61
62         for (i = 0; i < Nsymlist; i++)
63                 if (memcmp(tbl, &Symlist[i].tbl, sizeof(struct memtbl)) == 0)
64                         return(Symlist + i);
65         return(NULL);
66 }
67
68 int
69 do_symbolic(
70         int argc,
71         char **argv )
72 {
73         int i, nsyms, isflag;
74         unsigned long j;
75         struct symarray syms[50];
76         struct memtbl *tbl;
77         char *p;
78         char *type = NULL;
79         char * errmsg;
80
81         nsyms = 0;
82         isflag = 0;
83         for (i = 1; (i < argc) && argv[i]; i++) {
84                 if (argv[i][0] == '-') {
85                         for (j = 1; argv[i][j]; j++) {
86                                 switch(argv[i][j]) {
87                                 case 'm':
88                                         isflag = 1;
89                                         break;
90                                 case 't':
91                                         if (argv[i][j + 1])
92                                                 type = argv[i] + j + 1;
93                                         else
94                                                 type = argv[++i];
95                                         j = strlen(argv[i]) - 1;
96                                         break;
97                                 }
98                         }
99                 }
100                 else {
101                         syms[nsyms++].str = argv[i];
102                         if (nsyms == 50)
103                                 break;
104                 }
105         }
106         if ((type == NULL) || (!nsyms)) {
107                 XK_USAGE(argv[0]);
108         }
109         if (p = strchr(type, '.')) {
110                 *p = '\0';
111                 if ((tbl = all_tbl_search(type, 0)) == NULL) {
112                         *p = '.';
113                         errmsg = strdup(GetSharedMsg(DT_UNDEF_TYPE));
114                         printerrf(argv[0], errmsg, type, NULL, NULL,
115                                   NULL, NULL, NULL, NULL, NULL);
116                         free(errmsg);
117                         return(SH_FAIL);
118                 }
119                 if ((tbl = ffind(tbl, p + 1, NULL)) == NULL) {
120                         errmsg=strdup(GETMESSAGE(13,1, 
121                            "Unable to locate a field named '%s' for the type '%s'"));
122                         printerrf(argv[0], errmsg, p + 1, type, NULL,
123                                   NULL, NULL, NULL, NULL, NULL);
124                         free(errmsg);
125                         *p = '.';
126                         return(SH_FAIL);
127                 }
128                 *p = '.';
129         }
130         else if ((tbl = all_tbl_search(type, 0)) == NULL) {
131                 errmsg = strdup(GetSharedMsg(DT_UNDEF_TYPE));
132                 printerrf(argv[0], errmsg, type, NULL, NULL,
133                           NULL, NULL, NULL, NULL, NULL);
134                 free(errmsg);
135                 return(SH_FAIL);
136         }
137                 
138         for (i = 0; i < nsyms; i++) {
139                 if (!fdef(syms[i].str, &j)) {
140                         errmsg=strdup(GETMESSAGE(13,2, 
141                                "The name '%s' has not been defined"));
142                         printerrf(argv[0], errmsg, syms[i].str,
143                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL);
144                         free(errmsg);
145                         return(SH_FAIL);
146                 }
147                 syms[i].str = strdup(syms[i].str);
148                 syms[i].addr = j;
149         }
150         add_symbolic(isflag, tbl, syms, nsyms);
151         return(SH_SUCC);
152 }
153
154 int
155 add_symbolic(
156         int isflag,
157         struct memtbl *tbl,
158         struct symarray *syms,
159         int nsyms )
160 {
161         struct symlist *symptr;
162
163         if ((symptr = fsymbolic(tbl)) == NULL) {
164                 if (!Symlist)
165                         Symlist = (struct symlist *) malloc((Nsymlist + 1) * sizeof(struct symlist));
166                 else
167                         Symlist = (struct symlist *) realloc(Symlist, (Nsymlist + 1) * sizeof(struct symlist));
168                 if (!Symlist)
169                         return(SH_FAIL);
170                 symptr = Symlist + Nsymlist;
171                 Nsymlist++;
172         }
173         else
174                 free(symptr->syms);
175         symptr->tbl = *tbl;
176         symptr->nsyms = nsyms;
177         symptr->isflag = isflag;
178         symptr->syms = (struct symarray *) malloc(nsyms * sizeof(struct symarray));
179         memcpy(symptr->syms, syms, nsyms * sizeof(struct symarray));
180 }