xref: /titanic_51/usr/src/lib/efcode/interpreter/interpreter.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2000-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Embedded Fcode Interpreter
31  *
32  * Process cmd line args and invoke Fcode engine.
33  */
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/wait.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <strings.h>
42 #include <stropts.h>
43 #include <ctype.h>
44 
45 #include <fcode/engine.h>
46 #include <fcode/log.h>
47 #include <fcode/debug.h>
48 
49 #include <fcdriver/fcdriver.h>
50 
51 #define	MSG_ERRLOG_DEFAULT	(MSG_FATAL|MSG_ERROR|MSG_WARN|MSG_INFO|\
52 				    MSG_DEBUG|MSG_FC_DEBUG)
53 #define	MSG_SYSLOG_DEFAULT	(MSG_FATAL|MSG_ERROR|MSG_WARN)
54 #define	DEBUG_FC_LIST		(DEBUG_COMMA|DEBUG_EXEC_TRACE|\
55 				    DEBUG_EXEC_DUMP_RS|DEBUG_EXEC_DUMP_RS|\
56 				    DEBUG_EXEC_SHOW_VITALS|DEBUG_TRACING|\
57 				    DEBUG_BYTELOAD_DS|DEBUG_BYTELOAD_RS|\
58 				    DEBUG_BYTELOAD_TOKENS|DEBUG_SHOW_RS|\
59 				    DEBUG_SHOW_STACK)
60 
61 common_data_t common;
62 
63 void *fc_env;
64 
65 void
66 usage(char *argv[])
67 {
68 	log_message(MSG_ERROR, "Usage: %s <flags>\n", argv[0]);
69 	log_message(MSG_ERROR,
70 	    "    -D                        fcode_debug = true\n");
71 	log_message(MSG_ERROR,
72 	    "    -d <level>                set debug level\n");
73 	log_message(MSG_ERROR,
74 	    "    -f <file>                 interpret fcode/source <file>\n");
75 	log_message(MSG_ERROR,
76 	    "    -i                        go 'interactive'\n");
77 	log_message(MSG_ERROR,
78 	    "    -s <string>               interpret <string> as forth\n");
79 	log_message(MSG_ERROR,
80 	    "    -a                        FCODE image has a.out header\n");
81 	log_message(MSG_ERROR,
82 	    "    -e [<msglvl>:]<errorlog>  Set error log file\n");
83 	log_message(MSG_ERROR,
84 	    "    -l <msglvl>               Set syslog message level\n");
85 	log_message(MSG_ERROR,
86 	    "    -k                        Toggle OBP page kludge\n");
87 }
88 
89 fcode_env_t *env;
90 
91 int
92 main(int argc, char *argv[])
93 {
94 	extern char *optarg;
95 	extern int optind, opterr, optopt;
96 	int c, aout = 0;
97 	char *fcode_file = NULL;
98 	char *forthstr = NULL;
99 	int debug = 0;
100 	int syslog_flags = MSG_SYSLOG_DEFAULT;
101 	int lflag = 0;
102 	int error_log_flags;
103 	char *errlog = NULL;
104 	extern void run_one_efdaemon_request(fcode_env_t *);
105 
106 	common.Progname = argv[0];
107 	common.search_path = getenv("FC_SEARCH_PATH");
108 	common.fcode_fd = -1;
109 	env = fc_env  = clone_environment(NULL, &common);
110 
111 	while ((c = getopt(argc, argv, "ad:e:f:l:iDs:k")) != EOF) {
112 		switch (c) {
113 		case 'a':
114 			aout = 1;
115 			break;
116 
117 		case 'd':
118 			debug = debug_flags_to_mask(optarg);
119 			set_interpreter_debug_level(debug);
120 			if (debug)
121 				env->fcode_debug = 1;
122 			break;
123 
124 		case 'e':
125 			if ((errlog = strchr(optarg, ':')) != NULL) {
126 				*errlog++ = '\0';
127 				error_log_flags = parse_msg_flags(optarg);
128 			} else {
129 				errlog = optarg;
130 				error_log_flags = MSG_ERRLOG_DEFAULT;
131 			}
132 			open_error_log(errlog, error_log_flags);
133 			break;
134 
135 		case 'l':
136 			syslog_flags = parse_msg_flags(optarg);
137 			lflag++;
138 			break;
139 
140 		case 'D':
141 			env->fcode_debug = 1;
142 			break;
143 
144 		case 'f':
145 			fcode_file = optarg;
146 			break;
147 
148 		case 'i':
149 			forthstr = "interact";
150 			env->fcode_debug = 1;
151 			break;
152 
153 		case 's':
154 			forthstr = optarg;
155 			break;
156 
157 		case '?':
158 			usage(argv);
159 			exit(1);
160 		}
161 	}
162 
163 	if (forthstr) {
164 		run_fcode(env, (uchar_t *)forthstr, strlen(forthstr));
165 	} else if (fcode_file) {
166 		run_fcode_from_file(env, fcode_file, aout);
167 	} else {
168 		if ((debug & DEBUG_FC_LIST) != 0 &&
169 		    ((error_log_flags | syslog_flags) & MSG_FC_DEBUG) == 0) {
170 			log_message(MSG_WARN, "Warning, verbose debug flag(s)"
171 			    " on, but syslog/errlog not enabled for verbose"
172 			    " debug\n");
173 			if (errlog)
174 				error_log_flags |= MSG_FC_DEBUG;
175 			else
176 				syslog_flags |= MSG_FC_DEBUG;
177 		}
178 		if ((debug & ~DEBUG_FC_LIST) != 0 &&
179 		    ((error_log_flags | syslog_flags) & MSG_DEBUG) == 0) {
180 			log_message(MSG_WARN, "Warning, debug flag(s) on, but"
181 			    " syslog/errlog not enabled for debug\n");
182 			if (errlog)
183 				error_log_flags |= MSG_DEBUG;
184 			else
185 				syslog_flags |= MSG_DEBUG;
186 		}
187 
188 		if (errlog == NULL || lflag) {
189 			if (syslog_flags & MSG_FC_DEBUG)
190 				log_message(MSG_WARN, "Warning, verbose debug"
191 				    " not recommended for syslog\n");
192 			open_syslog_log("interpreter", syslog_flags);
193 		}
194 		run_one_efdaemon_request(env);
195 	}
196 
197 	return (0);
198 }
199