update from main archive 961001
[glibc.git] / elf / eval.c
blob03b903b76f36212eaea8ec8497bb9068fc884531
1 /* You don't really want to know what this hack is for.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #include <stdio.h>
21 #include <ctype.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <dlfcn.h>
27 static void *funcall (char **stringp);
28 static void *eval (char **stringp);
30 static void *
31 funcall (char **stringp)
33 void *args[strlen (*stringp)], **ap = args;
34 void *argcookie = &args[1];
38 /* Evaluate the next token. */
39 *ap++ = eval (stringp);
41 /* Whitespace is irrelevant. */
42 while (isspace (**stringp))
43 ++*stringp;
45 /* Terminate at closing paren or end of line. */
46 } while (**stringp != '\0' && **stringp != ')');
47 if (**stringp != '\0')
48 /* Swallow closing paren. */
49 ++*stringp;
51 if (args[0] == NULL)
53 static const char unknown[] = "Unknown function\n";
54 write (1, unknown, sizeof unknown - 1);
55 return NULL;
58 /* Do it to it. */
59 __builtin_return (__builtin_apply (args[0],
60 &argcookie,
61 (char *) ap - (char *) &args[1]));
64 static void *
65 eval (char **stringp)
67 void *value;
68 char *p = *stringp, c;
70 /* Whitespace is irrelevant. */
71 while (isspace (*p))
72 ++p;
74 switch (*p)
76 case '"':
77 /* String constant. */
78 value = ++p;
80 if (*p == '\\')
82 switch (*strcpy (p, p + 1))
84 case 't':
85 *p = '\t';
86 break;
87 case 'n':
88 *p = '\n';
89 break;
91 ++p;
93 while (*p != '\0' && *p++ != '"');
94 if (p[-1] == '"')
95 p[-1] = '\0';
96 break;
98 case '(':
99 *stringp = ++p;
100 return funcall (stringp);
102 default:
103 /* Try to parse it as a number. */
104 value = (void *) strtol (p, stringp, 0);
105 if (*stringp != p)
106 return value;
108 /* Anything else is a symbol that produces its address. */
109 value = p;
111 ++p;
112 while (*p != '\0' && !isspace (*p) && (!ispunct (*p) || *p == '_'));
113 c = *p;
114 *p = '\0';
115 value = dlsym (NULL, value);
116 *p = c;
117 break;
120 *stringp = p;
121 return value;
125 void
126 _start (void)
128 char *buf = NULL;
129 size_t bufsz = 0;
131 while (getline (&buf, &bufsz, stdin) > 0)
133 char *p = buf;
134 eval (&p);
137 exit (0);