1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 2000 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <unistd.h> 32*7c478bd9Sstevel@tonic-gate #include <string.h> 33*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 34*7c478bd9Sstevel@tonic-gate #include <setjmp.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <fcode/private.h> 38*7c478bd9Sstevel@tonic-gate #include <fcode/log.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate void (*to_ptr)(fcode_env_t *env) = do_set_action; 41*7c478bd9Sstevel@tonic-gate jmp_buf *jmp_buf_ptr = NULL; 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate char * 44*7c478bd9Sstevel@tonic-gate parse_a_string(fcode_env_t *env, int *lenp) 45*7c478bd9Sstevel@tonic-gate { 46*7c478bd9Sstevel@tonic-gate parse_word(env); 47*7c478bd9Sstevel@tonic-gate return (pop_a_string(env, lenp)); 48*7c478bd9Sstevel@tonic-gate } 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate void 51*7c478bd9Sstevel@tonic-gate constant(fcode_env_t *env) 52*7c478bd9Sstevel@tonic-gate { 53*7c478bd9Sstevel@tonic-gate char *name; 54*7c478bd9Sstevel@tonic-gate int len; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate name = parse_a_string(env, &len); 57*7c478bd9Sstevel@tonic-gate env->instance_mode = 0; 58*7c478bd9Sstevel@tonic-gate make_common_access(env, name, len, 1, 0, 59*7c478bd9Sstevel@tonic-gate &do_constant, &do_constant, NULL); 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate void 63*7c478bd9Sstevel@tonic-gate buffer_colon(fcode_env_t *env) 64*7c478bd9Sstevel@tonic-gate { 65*7c478bd9Sstevel@tonic-gate char *name; 66*7c478bd9Sstevel@tonic-gate int len; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate PUSH(DS, 0); 69*7c478bd9Sstevel@tonic-gate name = parse_a_string(env, &len); 70*7c478bd9Sstevel@tonic-gate make_common_access(env, name, len, 2, 71*7c478bd9Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_buffer_actions); 72*7c478bd9Sstevel@tonic-gate } 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate void 75*7c478bd9Sstevel@tonic-gate value(fcode_env_t *env) 76*7c478bd9Sstevel@tonic-gate { 77*7c478bd9Sstevel@tonic-gate char *name; 78*7c478bd9Sstevel@tonic-gate int len; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate name = parse_a_string(env, &len); 81*7c478bd9Sstevel@tonic-gate make_common_access(env, name, len, 1, 82*7c478bd9Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_value_actions); 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate void 86*7c478bd9Sstevel@tonic-gate variable(fcode_env_t *env) 87*7c478bd9Sstevel@tonic-gate { 88*7c478bd9Sstevel@tonic-gate char *name; 89*7c478bd9Sstevel@tonic-gate int len; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate PUSH(DS, 0); 92*7c478bd9Sstevel@tonic-gate name = parse_a_string(env, &len); 93*7c478bd9Sstevel@tonic-gate make_common_access(env, name, len, 1, 94*7c478bd9Sstevel@tonic-gate env->instance_mode, &instance_variable, &do_create, NULL); 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate void 98*7c478bd9Sstevel@tonic-gate defer(fcode_env_t *env) 99*7c478bd9Sstevel@tonic-gate { 100*7c478bd9Sstevel@tonic-gate static void (*crash_ptr)(fcode_env_t *env) = do_crash; 101*7c478bd9Sstevel@tonic-gate char *name; 102*7c478bd9Sstevel@tonic-gate int len; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)&crash_ptr); 105*7c478bd9Sstevel@tonic-gate name = parse_a_string(env, &len); 106*7c478bd9Sstevel@tonic-gate make_common_access(env, name, len, 1, 107*7c478bd9Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_defer_actions); 108*7c478bd9Sstevel@tonic-gate } 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate void 111*7c478bd9Sstevel@tonic-gate field(fcode_env_t *env) 112*7c478bd9Sstevel@tonic-gate { 113*7c478bd9Sstevel@tonic-gate char *name; 114*7c478bd9Sstevel@tonic-gate int len; 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate over(env); 117*7c478bd9Sstevel@tonic-gate name = parse_a_string(env, &len); 118*7c478bd9Sstevel@tonic-gate make_common_access(env, name, len, 1, 0, &do_field, &do_field, NULL); 119*7c478bd9Sstevel@tonic-gate add(env); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate void 123*7c478bd9Sstevel@tonic-gate bye(fcode_env_t *env) 124*7c478bd9Sstevel@tonic-gate { 125*7c478bd9Sstevel@tonic-gate exit(0); 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate void 129*7c478bd9Sstevel@tonic-gate do_resume(fcode_env_t *env) 130*7c478bd9Sstevel@tonic-gate { 131*7c478bd9Sstevel@tonic-gate if (env->interactive) env->interactive--; 132*7c478bd9Sstevel@tonic-gate COMPLETE_INTERRUPT; 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate /* 136*7c478bd9Sstevel@tonic-gate * In interactive mode, jmp_buf_ptr should be non-null. 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate void 139*7c478bd9Sstevel@tonic-gate return_to_interact(fcode_env_t *env) 140*7c478bd9Sstevel@tonic-gate { 141*7c478bd9Sstevel@tonic-gate if (jmp_buf_ptr) 142*7c478bd9Sstevel@tonic-gate longjmp(*jmp_buf_ptr, 1); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate void 146*7c478bd9Sstevel@tonic-gate do_interact(fcode_env_t *env) 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate int level; 149*7c478bd9Sstevel@tonic-gate jmp_buf jmp_env; 150*7c478bd9Sstevel@tonic-gate jmp_buf *ojmp_ptr; 151*7c478bd9Sstevel@tonic-gate error_frame new; 152*7c478bd9Sstevel@tonic-gate input_typ *old_input = env->input; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Type resume to return\n"); 155*7c478bd9Sstevel@tonic-gate env->interactive++; 156*7c478bd9Sstevel@tonic-gate level = env->interactive; 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate ojmp_ptr = jmp_buf_ptr; 159*7c478bd9Sstevel@tonic-gate jmp_buf_ptr = &jmp_env; 160*7c478bd9Sstevel@tonic-gate env->input->separator = ' '; 161*7c478bd9Sstevel@tonic-gate env->input->maxlen = 256; 162*7c478bd9Sstevel@tonic-gate env->input->buffer = MALLOC(env->input->maxlen); 163*7c478bd9Sstevel@tonic-gate env->input->scanptr = env->input->buffer; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate if (setjmp(jmp_env)) { 166*7c478bd9Sstevel@tonic-gate if (in_forth_abort > 1) { 167*7c478bd9Sstevel@tonic-gate RS = env->rs0; 168*7c478bd9Sstevel@tonic-gate DS = env->ds0; 169*7c478bd9Sstevel@tonic-gate MYSELF = 0; 170*7c478bd9Sstevel@tonic-gate IP = 0; 171*7c478bd9Sstevel@tonic-gate env->input = old_input; 172*7c478bd9Sstevel@tonic-gate env->order_depth = 0; 173*7c478bd9Sstevel@tonic-gate } else { 174*7c478bd9Sstevel@tonic-gate RS = new.rs; 175*7c478bd9Sstevel@tonic-gate DS = new.ds; 176*7c478bd9Sstevel@tonic-gate MYSELF = new.myself; 177*7c478bd9Sstevel@tonic-gate IP = new.ip; 178*7c478bd9Sstevel@tonic-gate env->input = old_input; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate do_forth(env); 181*7c478bd9Sstevel@tonic-gate do_definitions(env); 182*7c478bd9Sstevel@tonic-gate in_forth_abort = 0; 183*7c478bd9Sstevel@tonic-gate } else { 184*7c478bd9Sstevel@tonic-gate new.rs = RS; 185*7c478bd9Sstevel@tonic-gate new.ds = DS; 186*7c478bd9Sstevel@tonic-gate new.myself = MYSELF; 187*7c478bd9Sstevel@tonic-gate new.ip = IP; 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate while (env->interactive == level) { 191*7c478bd9Sstevel@tonic-gate int wlen; 192*7c478bd9Sstevel@tonic-gate char *p; 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate DEBUGF(SHOW_RS, output_return_stack(env, 0, MSG_FC_DEBUG)); 195*7c478bd9Sstevel@tonic-gate DEBUGF(SHOW_STACK, output_data_stack(env, MSG_FC_DEBUG)); 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate #define USE_READLINE 198*7c478bd9Sstevel@tonic-gate #ifdef USE_READLINE 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate char *line; 201*7c478bd9Sstevel@tonic-gate void read_line(fcode_env_t *); 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate read_line(env); 204*7c478bd9Sstevel@tonic-gate if ((line = pop_a_string(env, NULL)) == NULL) 205*7c478bd9Sstevel@tonic-gate continue; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate env->input->scanptr = strcpy(env->input->buffer, line); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate #else 210*7c478bd9Sstevel@tonic-gate if (isatty(fileno(stdin))) 211*7c478bd9Sstevel@tonic-gate printf("ok "); 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate env->input->scanptr = fgets(env->input->buffer, 214*7c478bd9Sstevel@tonic-gate env->input->maxlen, stdin); 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate if (feof(stdin)) 217*7c478bd9Sstevel@tonic-gate break; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate if (env->input->scanptr == NULL) 220*7c478bd9Sstevel@tonic-gate continue; 221*7c478bd9Sstevel@tonic-gate #endif 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate if ((p = strpbrk(env->input->scanptr, "\n\r")) != NULL) 224*7c478bd9Sstevel@tonic-gate *p = '\0'; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate if ((wlen = strlen(env->input->scanptr)) == 0) 227*7c478bd9Sstevel@tonic-gate continue; 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)env->input->buffer); 230*7c478bd9Sstevel@tonic-gate PUSH(DS, wlen); 231*7c478bd9Sstevel@tonic-gate evaluate(env); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate jmp_buf_ptr = ojmp_ptr; 235*7c478bd9Sstevel@tonic-gate FREE(env->input->buffer); 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate static void 239*7c478bd9Sstevel@tonic-gate temp_base(fcode_env_t *env, fstack_t base) 240*7c478bd9Sstevel@tonic-gate { 241*7c478bd9Sstevel@tonic-gate fstack_t obase; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate obase = env->num_base; 244*7c478bd9Sstevel@tonic-gate env->num_base = base; 245*7c478bd9Sstevel@tonic-gate parse_word(env); 246*7c478bd9Sstevel@tonic-gate evaluate(env); 247*7c478bd9Sstevel@tonic-gate env->num_base = obase; 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate static void 251*7c478bd9Sstevel@tonic-gate temp_decimal(fcode_env_t *env) 252*7c478bd9Sstevel@tonic-gate { 253*7c478bd9Sstevel@tonic-gate temp_base(env, 10); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate static void 257*7c478bd9Sstevel@tonic-gate temp_hex(fcode_env_t *env) 258*7c478bd9Sstevel@tonic-gate { 259*7c478bd9Sstevel@tonic-gate temp_base(env, 0x10); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate static void 263*7c478bd9Sstevel@tonic-gate temp_binary(fcode_env_t *env) 264*7c478bd9Sstevel@tonic-gate { 265*7c478bd9Sstevel@tonic-gate temp_base(env, 2); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate static void 269*7c478bd9Sstevel@tonic-gate do_hex(fcode_env_t *env) 270*7c478bd9Sstevel@tonic-gate { 271*7c478bd9Sstevel@tonic-gate env->num_base = 0x10; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate static void 275*7c478bd9Sstevel@tonic-gate do_decimal(fcode_env_t *env) 276*7c478bd9Sstevel@tonic-gate { 277*7c478bd9Sstevel@tonic-gate env->num_base = 10; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate static void 281*7c478bd9Sstevel@tonic-gate do_binary(fcode_env_t *env) 282*7c478bd9Sstevel@tonic-gate { 283*7c478bd9Sstevel@tonic-gate env->num_base = 2; 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate static void 287*7c478bd9Sstevel@tonic-gate do_clear(fcode_env_t *env) 288*7c478bd9Sstevel@tonic-gate { 289*7c478bd9Sstevel@tonic-gate DS = env->ds0; 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate static void 293*7c478bd9Sstevel@tonic-gate action_one(fcode_env_t *env) 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate do_tick(env); 297*7c478bd9Sstevel@tonic-gate if (env->state) { 298*7c478bd9Sstevel@tonic-gate COMPILE_TOKEN(&to_ptr); 299*7c478bd9Sstevel@tonic-gate } else { 300*7c478bd9Sstevel@tonic-gate PUSH(DS, 1); 301*7c478bd9Sstevel@tonic-gate perform_action(env); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate void 306*7c478bd9Sstevel@tonic-gate do_if(fcode_env_t *env) 307*7c478bd9Sstevel@tonic-gate { 308*7c478bd9Sstevel@tonic-gate branch_common(env, 1, 1, 0); 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate void 312*7c478bd9Sstevel@tonic-gate do_else(fcode_env_t *env) 313*7c478bd9Sstevel@tonic-gate { 314*7c478bd9Sstevel@tonic-gate branch_common(env, 1, 0, 1); 315*7c478bd9Sstevel@tonic-gate bresolve(env); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate void 319*7c478bd9Sstevel@tonic-gate do_then(fcode_env_t *env) 320*7c478bd9Sstevel@tonic-gate { 321*7c478bd9Sstevel@tonic-gate bresolve(env); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate void 325*7c478bd9Sstevel@tonic-gate do_of(fcode_env_t *env) 326*7c478bd9Sstevel@tonic-gate { 327*7c478bd9Sstevel@tonic-gate branch_common(env, 0, 2, 0); 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate void 331*7c478bd9Sstevel@tonic-gate load_file(fcode_env_t *env) 332*7c478bd9Sstevel@tonic-gate { 333*7c478bd9Sstevel@tonic-gate int fd; 334*7c478bd9Sstevel@tonic-gate int len, n; 335*7c478bd9Sstevel@tonic-gate char *name; 336*7c478bd9Sstevel@tonic-gate char *buffer; 337*7c478bd9Sstevel@tonic-gate struct stat buf; 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "load-file"); 340*7c478bd9Sstevel@tonic-gate name = pop_a_string(env, &len); 341*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "load_file: '%s'\n", name); 342*7c478bd9Sstevel@tonic-gate fd = open(name, O_RDONLY); 343*7c478bd9Sstevel@tonic-gate if (fd < 0) { 344*7c478bd9Sstevel@tonic-gate forth_perror(env, "Can't open '%s'", name); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate fstat(fd, &buf); 347*7c478bd9Sstevel@tonic-gate len = buf.st_size; 348*7c478bd9Sstevel@tonic-gate buffer = MALLOC(len); 349*7c478bd9Sstevel@tonic-gate if (buffer == 0) 350*7c478bd9Sstevel@tonic-gate forth_perror(env, "load_file: MALLOC(%d)", len); 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate if ((n = read(fd, buffer, len)) < 0) 353*7c478bd9Sstevel@tonic-gate forth_perror(env, "read error '%s'", name); 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate close(fd); 356*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)buffer); 357*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)n); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate void 361*7c478bd9Sstevel@tonic-gate load(fcode_env_t *env) 362*7c478bd9Sstevel@tonic-gate { 363*7c478bd9Sstevel@tonic-gate parse_word(env); 364*7c478bd9Sstevel@tonic-gate if (TOS > 0) 365*7c478bd9Sstevel@tonic-gate load_file(env); 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate void 369*7c478bd9Sstevel@tonic-gate fevaluate(fcode_env_t *env) 370*7c478bd9Sstevel@tonic-gate { 371*7c478bd9Sstevel@tonic-gate char *buffer; 372*7c478bd9Sstevel@tonic-gate int bytes, len; 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate two_dup(env); 375*7c478bd9Sstevel@tonic-gate buffer = pop_a_string(env, &len); 376*7c478bd9Sstevel@tonic-gate for (bytes = 0; bytes < len; bytes++) { 377*7c478bd9Sstevel@tonic-gate if ((buffer[bytes] == '\n') || (buffer[bytes] == '\r')) 378*7c478bd9Sstevel@tonic-gate buffer[bytes] = ' '; 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate evaluate(env); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate void 384*7c478bd9Sstevel@tonic-gate fload(fcode_env_t *env) 385*7c478bd9Sstevel@tonic-gate { 386*7c478bd9Sstevel@tonic-gate char *buffer; 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate load(env); 389*7c478bd9Sstevel@tonic-gate two_dup(env); 390*7c478bd9Sstevel@tonic-gate buffer = pop_a_string(env, NULL); 391*7c478bd9Sstevel@tonic-gate fevaluate(env); 392*7c478bd9Sstevel@tonic-gate FREE(buffer); 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate #include <sys/termio.h> 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate #define MAX_LINE_BUF 20 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate static char *history_lines[MAX_LINE_BUF]; 400*7c478bd9Sstevel@tonic-gate int num_lines = 0; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate static void 403*7c478bd9Sstevel@tonic-gate add_line_to_history(fcode_env_t *env, char *line) 404*7c478bd9Sstevel@tonic-gate { 405*7c478bd9Sstevel@tonic-gate int i; 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate if (num_lines < MAX_LINE_BUF) 408*7c478bd9Sstevel@tonic-gate history_lines[num_lines++] = STRDUP(line); 409*7c478bd9Sstevel@tonic-gate else { 410*7c478bd9Sstevel@tonic-gate FREE(history_lines[0]); 411*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_LINE_BUF - 1; i++) 412*7c478bd9Sstevel@tonic-gate history_lines[i] = history_lines[i + 1]; 413*7c478bd9Sstevel@tonic-gate history_lines[MAX_LINE_BUF - 1] = STRDUP(line); 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate static void 418*7c478bd9Sstevel@tonic-gate do_emit_chars(fcode_env_t *env, char c, int n) 419*7c478bd9Sstevel@tonic-gate { 420*7c478bd9Sstevel@tonic-gate int i; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) 423*7c478bd9Sstevel@tonic-gate do_emit(env, c); 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate static void 427*7c478bd9Sstevel@tonic-gate do_emit_str(fcode_env_t *env, char *str, int n) 428*7c478bd9Sstevel@tonic-gate { 429*7c478bd9Sstevel@tonic-gate int i; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) 432*7c478bd9Sstevel@tonic-gate do_emit(env, *str++); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate static char * 436*7c478bd9Sstevel@tonic-gate find_next_word(char *cursor, char *eol) 437*7c478bd9Sstevel@tonic-gate { 438*7c478bd9Sstevel@tonic-gate while (cursor < eol && *cursor != ' ') 439*7c478bd9Sstevel@tonic-gate cursor++; 440*7c478bd9Sstevel@tonic-gate while (cursor < eol && *cursor == ' ') 441*7c478bd9Sstevel@tonic-gate cursor++; 442*7c478bd9Sstevel@tonic-gate return (cursor); 443*7c478bd9Sstevel@tonic-gate } 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate static char * 446*7c478bd9Sstevel@tonic-gate find_prev_word(char *buf, char *cursor) 447*7c478bd9Sstevel@tonic-gate { 448*7c478bd9Sstevel@tonic-gate int skippedword = 0; 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate if (cursor == buf) 451*7c478bd9Sstevel@tonic-gate return (cursor); 452*7c478bd9Sstevel@tonic-gate cursor--; 453*7c478bd9Sstevel@tonic-gate while (cursor > buf && *cursor == ' ') 454*7c478bd9Sstevel@tonic-gate cursor--; 455*7c478bd9Sstevel@tonic-gate while (cursor > buf && *cursor != ' ') { 456*7c478bd9Sstevel@tonic-gate skippedword++; 457*7c478bd9Sstevel@tonic-gate cursor--; 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate if (skippedword && *cursor == ' ') 460*7c478bd9Sstevel@tonic-gate cursor++; 461*7c478bd9Sstevel@tonic-gate return (cursor); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate void 465*7c478bd9Sstevel@tonic-gate redraw_line(fcode_env_t *env, char *prev_l, char *prev_cursor, char *prev_eol, 466*7c478bd9Sstevel@tonic-gate char *new_l, char *new_cursor, char *new_eol) 467*7c478bd9Sstevel@tonic-gate { 468*7c478bd9Sstevel@tonic-gate int len; 469*7c478bd9Sstevel@tonic-gate 470*7c478bd9Sstevel@tonic-gate /* backup to beginning of previous line */ 471*7c478bd9Sstevel@tonic-gate do_emit_chars(env, '\b', prev_cursor - prev_l); 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate /* overwrite new line */ 474*7c478bd9Sstevel@tonic-gate do_emit_str(env, new_l, new_eol - new_l); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate /* Output blanks to erase previous line chars if old line was longer */ 477*7c478bd9Sstevel@tonic-gate len = max(0, (prev_eol - prev_l) - (new_eol - new_l)); 478*7c478bd9Sstevel@tonic-gate do_emit_chars(env, ' ', len); 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate /* Backup cursor for new line */ 481*7c478bd9Sstevel@tonic-gate do_emit_chars(env, '\b', len + (new_eol - new_cursor)); 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate #define MAX_LINE_SIZE 256 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate static void 487*7c478bd9Sstevel@tonic-gate do_save_buf(char *save_buf, char *buf, int n) 488*7c478bd9Sstevel@tonic-gate { 489*7c478bd9Sstevel@tonic-gate n = max(0, min(n, MAX_LINE_SIZE)); 490*7c478bd9Sstevel@tonic-gate memcpy(save_buf, buf, n); 491*7c478bd9Sstevel@tonic-gate save_buf[n] = '\0'; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate char prompt_string[80] = "ok "; 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate void 497*7c478bd9Sstevel@tonic-gate read_line(fcode_env_t *env) 498*7c478bd9Sstevel@tonic-gate { 499*7c478bd9Sstevel@tonic-gate char buf[MAX_LINE_SIZE+1], save_buf[MAX_LINE_SIZE+1]; 500*7c478bd9Sstevel@tonic-gate char save_line[MAX_LINE_SIZE+1]; 501*7c478bd9Sstevel@tonic-gate char *p, *cursor, *eol, *tp, *cp; 502*7c478bd9Sstevel@tonic-gate fstack_t d; 503*7c478bd9Sstevel@tonic-gate int saw_esc = 0, do_quote = 0, i, cur_line, len, my_line, save_cursor; 504*7c478bd9Sstevel@tonic-gate struct termio termio, savetermio; 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate if (!isatty(fileno(stdin))) { 507*7c478bd9Sstevel@tonic-gate fgets(buf, sizeof (buf), stdin); 508*7c478bd9Sstevel@tonic-gate push_string(env, buf, strlen(buf)); 509*7c478bd9Sstevel@tonic-gate return; 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate printf(prompt_string); 512*7c478bd9Sstevel@tonic-gate fflush(stdout); 513*7c478bd9Sstevel@tonic-gate ioctl(fileno(stdin), TCGETA, &termio); 514*7c478bd9Sstevel@tonic-gate savetermio = termio; 515*7c478bd9Sstevel@tonic-gate termio.c_lflag &= ~(ICANON|ECHO|ECHOE|IEXTEN); 516*7c478bd9Sstevel@tonic-gate termio.c_cc[VTIME] = 0; 517*7c478bd9Sstevel@tonic-gate termio.c_cc[VMIN] = 1; 518*7c478bd9Sstevel@tonic-gate ioctl(fileno(stdin), TCSETA, &termio); 519*7c478bd9Sstevel@tonic-gate my_line = cur_line = num_lines; 520*7c478bd9Sstevel@tonic-gate save_buf[0] = '\0'; 521*7c478bd9Sstevel@tonic-gate for (cursor = eol = buf; ; ) { 522*7c478bd9Sstevel@tonic-gate for (d = FALSE; d == FALSE; d = POP(DS)) 523*7c478bd9Sstevel@tonic-gate keyquestion(env); 524*7c478bd9Sstevel@tonic-gate key(env); 525*7c478bd9Sstevel@tonic-gate d = POP(DS); 526*7c478bd9Sstevel@tonic-gate if (do_quote) { 527*7c478bd9Sstevel@tonic-gate do_quote = 0; 528*7c478bd9Sstevel@tonic-gate if ((cursor - buf) < MAX_LINE_SIZE) { 529*7c478bd9Sstevel@tonic-gate *cursor++ = d; 530*7c478bd9Sstevel@tonic-gate if (cursor > eol) 531*7c478bd9Sstevel@tonic-gate eol = cursor; 532*7c478bd9Sstevel@tonic-gate do_emit(env, d); 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate continue; 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate if (saw_esc) { 537*7c478bd9Sstevel@tonic-gate saw_esc = 0; 538*7c478bd9Sstevel@tonic-gate switch (d) { 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate default: /* Ignore anything else */ 541*7c478bd9Sstevel@tonic-gate continue; 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate case 'b': /* Move backward one word */ 544*7c478bd9Sstevel@tonic-gate case 'B': 545*7c478bd9Sstevel@tonic-gate tp = find_prev_word(buf, cursor); 546*7c478bd9Sstevel@tonic-gate if (tp < cursor) { 547*7c478bd9Sstevel@tonic-gate do_emit_chars(env, '\b', cursor - tp); 548*7c478bd9Sstevel@tonic-gate cursor = tp; 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate continue; 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate case 'f': /* Move forward one word */ 553*7c478bd9Sstevel@tonic-gate case 'F': 554*7c478bd9Sstevel@tonic-gate tp = find_next_word(cursor, eol); 555*7c478bd9Sstevel@tonic-gate if (tp > cursor) { 556*7c478bd9Sstevel@tonic-gate do_emit_str(env, tp, tp - cursor); 557*7c478bd9Sstevel@tonic-gate cursor = tp; 558*7c478bd9Sstevel@tonic-gate } 559*7c478bd9Sstevel@tonic-gate continue; 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate case 'h': /* Erase from beginning of word to */ 562*7c478bd9Sstevel@tonic-gate case 'H': /* just before cursor, saving chars */ 563*7c478bd9Sstevel@tonic-gate d = CTRL('w'); 564*7c478bd9Sstevel@tonic-gate break; 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate case 'd': 567*7c478bd9Sstevel@tonic-gate case 'D': 568*7c478bd9Sstevel@tonic-gate tp = find_next_word(cursor, eol); 569*7c478bd9Sstevel@tonic-gate if (tp <= cursor) 570*7c478bd9Sstevel@tonic-gate continue; 571*7c478bd9Sstevel@tonic-gate len = tp - cursor; 572*7c478bd9Sstevel@tonic-gate do_save_buf(save_buf, cursor, len); 573*7c478bd9Sstevel@tonic-gate memmove(cursor, tp, eol - tp); 574*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor, 575*7c478bd9Sstevel@tonic-gate eol - len); 576*7c478bd9Sstevel@tonic-gate eol -= len; 577*7c478bd9Sstevel@tonic-gate continue; 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate switch (d) { 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate default: 583*7c478bd9Sstevel@tonic-gate if ((cursor - buf) < MAX_LINE_SIZE) { 584*7c478bd9Sstevel@tonic-gate *cursor++ = d; 585*7c478bd9Sstevel@tonic-gate if (cursor > eol) 586*7c478bd9Sstevel@tonic-gate eol = cursor; 587*7c478bd9Sstevel@tonic-gate do_emit(env, d); 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate continue; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate case CTRL('['): /* saw esc. character */ 592*7c478bd9Sstevel@tonic-gate saw_esc = 1; 593*7c478bd9Sstevel@tonic-gate continue; 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate case CTRL('f'): /* move forward one char */ 596*7c478bd9Sstevel@tonic-gate if (cursor < eol) 597*7c478bd9Sstevel@tonic-gate do_emit(env, *cursor++); 598*7c478bd9Sstevel@tonic-gate continue; 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate case CTRL('a'): /* cursor to beginning of line */ 601*7c478bd9Sstevel@tonic-gate do_emit_chars(env, '\b', cursor - buf); 602*7c478bd9Sstevel@tonic-gate cursor = buf; 603*7c478bd9Sstevel@tonic-gate continue; 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate case CTRL('e'): /* cursor to end of line */ 606*7c478bd9Sstevel@tonic-gate do_emit_str(env, cursor, eol - cursor); 607*7c478bd9Sstevel@tonic-gate cursor = eol; 608*7c478bd9Sstevel@tonic-gate continue; 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate case CTRL('n'): /* Move to next line in buffer */ 612*7c478bd9Sstevel@tonic-gate case CTRL('p'): /* Move to previous line in buffer */ 613*7c478bd9Sstevel@tonic-gate if (d == CTRL('p')) { 614*7c478bd9Sstevel@tonic-gate if (cur_line <= 0) 615*7c478bd9Sstevel@tonic-gate continue; 616*7c478bd9Sstevel@tonic-gate if (my_line == cur_line) { 617*7c478bd9Sstevel@tonic-gate do_save_buf(save_line, buf, eol - buf); 618*7c478bd9Sstevel@tonic-gate save_cursor = cursor - buf; 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate cur_line--; 621*7c478bd9Sstevel@tonic-gate } else { 622*7c478bd9Sstevel@tonic-gate if (cur_line >= num_lines) 623*7c478bd9Sstevel@tonic-gate continue; 624*7c478bd9Sstevel@tonic-gate cur_line++; 625*7c478bd9Sstevel@tonic-gate if (cur_line == num_lines) { 626*7c478bd9Sstevel@tonic-gate len = strlen(save_line); 627*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, 628*7c478bd9Sstevel@tonic-gate save_line, save_line + save_cursor, 629*7c478bd9Sstevel@tonic-gate save_line + len); 630*7c478bd9Sstevel@tonic-gate strcpy(buf, save_line); 631*7c478bd9Sstevel@tonic-gate eol = buf + len; 632*7c478bd9Sstevel@tonic-gate cursor = buf + save_cursor; 633*7c478bd9Sstevel@tonic-gate continue; 634*7c478bd9Sstevel@tonic-gate } 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate p = history_lines[cur_line]; 637*7c478bd9Sstevel@tonic-gate len = strlen(p); 638*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, p, p, p + len); 639*7c478bd9Sstevel@tonic-gate strcpy(buf, history_lines[cur_line]); 640*7c478bd9Sstevel@tonic-gate cursor = buf; 641*7c478bd9Sstevel@tonic-gate eol = buf + len; 642*7c478bd9Sstevel@tonic-gate continue; 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate case CTRL('o'): /* Insert newline */ 645*7c478bd9Sstevel@tonic-gate continue; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate case CTRL('k'): /* Erase from cursor to eol, saving */ 648*7c478bd9Sstevel@tonic-gate /* chars, at eol, joins two lines */ 649*7c478bd9Sstevel@tonic-gate if (cursor == eol) { 650*7c478bd9Sstevel@tonic-gate if (cur_line >= num_lines) 651*7c478bd9Sstevel@tonic-gate continue; 652*7c478bd9Sstevel@tonic-gate if (cur_line == num_lines - 1) { 653*7c478bd9Sstevel@tonic-gate p = save_line; 654*7c478bd9Sstevel@tonic-gate len = strlen(save_line); 655*7c478bd9Sstevel@tonic-gate num_lines -= 1; 656*7c478bd9Sstevel@tonic-gate my_line = num_lines; 657*7c478bd9Sstevel@tonic-gate } else { 658*7c478bd9Sstevel@tonic-gate cur_line++; 659*7c478bd9Sstevel@tonic-gate p = history_lines[cur_line]; 660*7c478bd9Sstevel@tonic-gate len = strlen(p); 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate len = min(len, MAX_LINE_SIZE - (eol - buf)); 663*7c478bd9Sstevel@tonic-gate memcpy(eol, p, len); 664*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor, 665*7c478bd9Sstevel@tonic-gate eol + len); 666*7c478bd9Sstevel@tonic-gate eol += len; 667*7c478bd9Sstevel@tonic-gate continue; 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate do_save_buf(save_buf, cursor, eol - cursor); 670*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor, 671*7c478bd9Sstevel@tonic-gate cursor); 672*7c478bd9Sstevel@tonic-gate eol = cursor; 673*7c478bd9Sstevel@tonic-gate continue; 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate case CTRL('w'): /* Erase word */ 676*7c478bd9Sstevel@tonic-gate tp = find_prev_word(buf, cursor); 677*7c478bd9Sstevel@tonic-gate if (tp == cursor) 678*7c478bd9Sstevel@tonic-gate continue; 679*7c478bd9Sstevel@tonic-gate len = cursor - tp; 680*7c478bd9Sstevel@tonic-gate do_save_buf(save_buf, tp, len); 681*7c478bd9Sstevel@tonic-gate memmove(tp, cursor, eol - cursor); 682*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor - len, 683*7c478bd9Sstevel@tonic-gate eol - len); 684*7c478bd9Sstevel@tonic-gate eol -= len; 685*7c478bd9Sstevel@tonic-gate cursor -= len; 686*7c478bd9Sstevel@tonic-gate continue; 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate case CTRL('u'): /* Erases line, saving chars */ 689*7c478bd9Sstevel@tonic-gate do_save_buf(save_buf, buf, eol - buf); 690*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, buf, buf); 691*7c478bd9Sstevel@tonic-gate cursor = buf; 692*7c478bd9Sstevel@tonic-gate eol = buf; 693*7c478bd9Sstevel@tonic-gate continue; 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate case CTRL('y'): /* Insert save buffer before cursor */ 696*7c478bd9Sstevel@tonic-gate len = min(strlen(save_buf), 697*7c478bd9Sstevel@tonic-gate MAX_LINE_SIZE - (eol - buf)); 698*7c478bd9Sstevel@tonic-gate if (len == 0) 699*7c478bd9Sstevel@tonic-gate continue; 700*7c478bd9Sstevel@tonic-gate memmove(cursor + len, cursor, eol - cursor); 701*7c478bd9Sstevel@tonic-gate memcpy(cursor, save_buf, len); 702*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor + len, 703*7c478bd9Sstevel@tonic-gate eol + len); 704*7c478bd9Sstevel@tonic-gate cursor += len; 705*7c478bd9Sstevel@tonic-gate eol += len; 706*7c478bd9Sstevel@tonic-gate continue; 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate case CTRL('q'): /* Quote next char */ 709*7c478bd9Sstevel@tonic-gate do_quote = 1; 710*7c478bd9Sstevel@tonic-gate continue; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate case CTRL('l'): /* Display edit buffer */ 713*7c478bd9Sstevel@tonic-gate do_emit(env, '\n'); 714*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_lines; i++) { 715*7c478bd9Sstevel@tonic-gate do_emit_str(env, history_lines[i], 716*7c478bd9Sstevel@tonic-gate strlen(history_lines[i])); 717*7c478bd9Sstevel@tonic-gate do_emit(env, '\n'); 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, buf, buf, buf, cursor, eol); 720*7c478bd9Sstevel@tonic-gate continue; 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate case CTRL('r'): /* redraw line */ 723*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor, eol); 724*7c478bd9Sstevel@tonic-gate continue; 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate case CTRL('c'): /* Exit script editor */ 727*7c478bd9Sstevel@tonic-gate continue; 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate case CTRL('b'): /* backup cursor */ 730*7c478bd9Sstevel@tonic-gate if (cursor <= buf) 731*7c478bd9Sstevel@tonic-gate continue; 732*7c478bd9Sstevel@tonic-gate cursor--; 733*7c478bd9Sstevel@tonic-gate do_emit(env, '\b'); 734*7c478bd9Sstevel@tonic-gate continue; 735*7c478bd9Sstevel@tonic-gate 736*7c478bd9Sstevel@tonic-gate case CTRL('h'): /* Backspace */ 737*7c478bd9Sstevel@tonic-gate case 0x7f: /* DEL */ 738*7c478bd9Sstevel@tonic-gate if (cursor <= buf) 739*7c478bd9Sstevel@tonic-gate continue; 740*7c478bd9Sstevel@tonic-gate memmove(cursor - 1, cursor, eol - cursor); 741*7c478bd9Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor - 1, 742*7c478bd9Sstevel@tonic-gate eol - 1); 743*7c478bd9Sstevel@tonic-gate cursor--; 744*7c478bd9Sstevel@tonic-gate eol--; 745*7c478bd9Sstevel@tonic-gate continue; 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate case '\r': 748*7c478bd9Sstevel@tonic-gate case '\n': 749*7c478bd9Sstevel@tonic-gate *eol = '\0'; 750*7c478bd9Sstevel@tonic-gate do_emit(env, '\n'); 751*7c478bd9Sstevel@tonic-gate break; 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate break; 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate add_line_to_history(env, buf); 756*7c478bd9Sstevel@tonic-gate ioctl(fileno(stdin), TCSETA, &savetermio); 757*7c478bd9Sstevel@tonic-gate push_string(env, buf, strlen(buf)); 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate static void 761*7c478bd9Sstevel@tonic-gate set_prompt(fcode_env_t *env) 762*7c478bd9Sstevel@tonic-gate { 763*7c478bd9Sstevel@tonic-gate char *prompt; 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate if ((prompt = parse_a_string(env, NULL)) != NULL) 766*7c478bd9Sstevel@tonic-gate strncpy(prompt_string, prompt, sizeof (prompt_string)); 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate #pragma init(_init) 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate static void 772*7c478bd9Sstevel@tonic-gate _init(void) 773*7c478bd9Sstevel@tonic-gate { 774*7c478bd9Sstevel@tonic-gate fcode_env_t *env = initial_env; 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate ASSERT(env); 777*7c478bd9Sstevel@tonic-gate NOTICE; 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "if", do_if); 780*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "else", do_else); 781*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "then", do_then); 782*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "case", bcase); 783*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "of", do_of); 784*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "endof", do_else); 785*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "endcase", bendcase); 786*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "value", value); 787*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "variable", variable); 788*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "constant", constant); 789*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "defer", defer); 790*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "buffer:", buffer_colon); 791*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "field", field); 792*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "struct", zero); 793*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "to", action_one); 794*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "d#", temp_decimal); 795*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "h#", temp_hex); 796*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "b#", temp_binary); 797*7c478bd9Sstevel@tonic-gate FORTH(0, "decimal", do_decimal); 798*7c478bd9Sstevel@tonic-gate FORTH(0, "hex", do_hex); 799*7c478bd9Sstevel@tonic-gate FORTH(0, "binary", do_binary); 800*7c478bd9Sstevel@tonic-gate FORTH(0, "clear", do_clear); 801*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "bye", bye); 802*7c478bd9Sstevel@tonic-gate FORTH(0, "interact", do_interact); 803*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "resume", do_resume); 804*7c478bd9Sstevel@tonic-gate FORTH(0, "fload", fload); 805*7c478bd9Sstevel@tonic-gate FORTH(0, "load", load); 806*7c478bd9Sstevel@tonic-gate FORTH(0, "read-line", read_line); 807*7c478bd9Sstevel@tonic-gate FORTH(0, "set-prompt", set_prompt); 808*7c478bd9Sstevel@tonic-gate } 809