cdesktopenv/cde/programs/dtksh/symbolic.c

181 lines
5.2 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: symbolic.c /main/4 1995/11/01 15:56:54 rswiston $ */
/* Copyright (c) 1991, 1992 UNIX System Laboratories, Inc. */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* UNIX System Laboratories, Inc. */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#include "name.h"
#include "shell.h"
#include "stdio.h"
#include "exksh.h" /* which includes sys/types.h */
#include "struct.h" /* which includes sys/types.h */
#include <string.h>
#include "msgs.h"
struct symlist *Symlist = NULL;
int Nsymlist;
/*
** There is an implicit dirty trick going on here. It is effective,
** efficient and will work anywhere but it is tricky. A memtbl has
** strings in it. The fact that a byte-by-byte comparison is being
** done on a memtbl means that pointers are being compared. This
** means that EVERY UNIQUE MEMTBL SHOULD HAVE SOME UNIQUE FIELD (i.e.
** in this case, the string for the name field). If somebody uses
** an algorithm in do_struct() that saves string space (by seeing if
** the same string is lying around) this code will break and an ID
** field will be necessary to maintain uniqueness.
*/
struct symlist *
fsymbolic(
struct memtbl *tbl )
{
int i;
for (i = 0; i < Nsymlist; i++)
if (memcmp(tbl, &Symlist[i].tbl, sizeof(struct memtbl)) == 0)
return(Symlist + i);
return(NULL);
}
int
do_symbolic(
int argc,
char **argv )
{
int i, nsyms, isflag;
unsigned long j;
struct symarray syms[50];
struct memtbl *tbl;
char *p;
char *type = NULL;
char * errmsg;
nsyms = 0;
isflag = 0;
for (i = 1; (i < argc) && argv[i]; i++) {
if (argv[i][0] == '-') {
for (j = 1; argv[i][j]; j++) {
switch(argv[i][j]) {
case 'm':
isflag = 1;
break;
case 't':
if (argv[i][j + 1])
type = argv[i] + j + 1;
else
type = argv[++i];
j = strlen(argv[i]) - 1;
break;
}
}
}
else {
syms[nsyms++].str = argv[i];
if (nsyms == 50)
break;
}
}
if ((type == NULL) || (!nsyms)) {
XK_USAGE(argv[0]);
}
if (p = strchr(type, '.')) {
*p = '\0';
if ((tbl = all_tbl_search(type, 0)) == NULL) {
*p = '.';
errmsg = strdup(GetSharedMsg(DT_UNDEF_TYPE));
printerrf(argv[0], errmsg, type, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(SH_FAIL);
}
if ((tbl = ffind(tbl, p + 1, NULL)) == NULL) {
errmsg=strdup(GETMESSAGE(13,1,
"Unable to locate a field named '%s' for the type '%s'"));
printerrf(argv[0], errmsg, p + 1, type, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
*p = '.';
return(SH_FAIL);
}
*p = '.';
}
else if ((tbl = all_tbl_search(type, 0)) == NULL) {
errmsg = strdup(GetSharedMsg(DT_UNDEF_TYPE));
printerrf(argv[0], errmsg, type, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(SH_FAIL);
}
for (i = 0; i < nsyms; i++) {
if (!fdef(syms[i].str, &j)) {
errmsg=strdup(GETMESSAGE(13,2,
"The name '%s' has not been defined"));
printerrf(argv[0], errmsg, syms[i].str,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(SH_FAIL);
}
syms[i].str = strdup(syms[i].str);
syms[i].addr = j;
}
add_symbolic(isflag, tbl, syms, nsyms);
return(SH_SUCC);
}
int
add_symbolic(
int isflag,
struct memtbl *tbl,
struct symarray *syms,
int nsyms )
{
struct symlist *symptr;
if ((symptr = fsymbolic(tbl)) == NULL) {
if (!Symlist)
Symlist = (struct symlist *) malloc((Nsymlist + 1) * sizeof(struct symlist));
else
Symlist = (struct symlist *) realloc(Symlist, (Nsymlist + 1) * sizeof(struct symlist));
if (!Symlist)
return(SH_FAIL);
symptr = Symlist + Nsymlist;
Nsymlist++;
}
else
free(symptr->syms);
symptr->tbl = *tbl;
symptr->nsyms = nsyms;
symptr->isflag = isflag;
symptr->syms = (struct symarray *) malloc(nsyms * sizeof(struct symarray));
memcpy(symptr->syms, syms, nsyms * sizeof(struct symarray));
}