/* argv[i] = ARGV[i] */ static void set_ARGV(int argc, char **argv, int i) { SYMTAB *st_p; CELL argi; register CELL *cp; st_p = insert("ARGV"); st_p->type = ST_ARRAY; Argv = st_p->stval.array = new_ARRAY(); no_leaks_array(Argv); argi.type = C_DOUBLE; argi.dval = 0.0; cp = array_find(st_p->stval.array, &argi, CREATE); cp->type = C_STRING; cp->ptr = (PTR) new_STRING(progname); /* ARGV[0] is set, do the rest The type of ARGV[1] ... should be C_MBSTRN because the user might enter numbers from the command line */ for (argi.dval = 1.0; i < argc; i++, argi.dval += 1.0) { cp = array_find(st_p->stval.array, &argi, CREATE); cp->type = C_MBSTRN; cp->ptr = (PTR) new_STRING(argv[i]); } ARGC->type = C_DOUBLE; ARGC->dval = argi.dval; }
VALUE snow_arguments_get_by_name(SnArguments* args, SnSymbol name) { intx idx = args ? array_find(NAMES, symbol_to_value(name)) : -1; if (idx >= 0) return array_get(DATA, idx); return SN_NIL; }
void load_environ(ARRAY ENV) { CELL c; register char **p = environ; /* walks environ */ char *s; /* looks for the '=' */ CELL *cp; /* pts at ENV[&c] */ c.type = C_STRING; while (*p) { if ((s = strchr(*p, '='))) { /* shouldn't fail */ size_t len = (size_t) (s - *p); c.ptr = (PTR) new_STRING0(len); memcpy(string(&c)->str, *p, len); s++; cp = array_find(ENV, &c, CREATE); cp->type = C_MBSTRN; cp->ptr = (PTR) new_STRING(s); free_STRING(string(&c)); } p++; } }
// scan for windows and add them to the list of managed clients // from dwm.c void scan(void) { unsigned int num; Window d1, d2, *cl, *wins = NULL; unsigned long cl_count; XWindowAttributes wa; ewmh_get_original_client_list(&cl, &cl_count); if (XQueryTree(g_display, g_root, &d1, &d2, &wins, &num)) { for (int i = 0; i < num; i++) { if(!XGetWindowAttributes(g_display, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(g_display, wins[i], &d1)) continue; // only manage mapped windows.. no strange wins like: // luakit/dbus/(ncurses-)vim // but manage it if it was in the ewmh property _NET_CLIENT_LIST by // the previous window manager // TODO: what would dwm do? if (is_window_mapped(g_display, wins[i]) || 0 <= array_find(cl, cl_count, sizeof(Window), wins+i)) { manage_client(wins[i]); XMapWindow(g_display, wins[i]); } } if(wins) XFree(wins); } }
void command_disable_command (NICK * nick, CHANNEL * channel, const char *cmd, const char **args, int argc) { struct command_s *handler; // show usage if (argc < 1) { puttext ("NOTICE %s :Usage: %s command\n", nick->nick, cmd); return; } // find out handler if (!(handler = array_find (commands, args[0]))) { puttext ("NOTICE %s :Command '%s' not known\r\n", nick->nick, args[0]); // ENSURE THAT IT IS NOT DISABLE OR ENABLE AS THESE ARE CRITICAL COMMANDS } else if ((handler->handler == command_disable_command) || (handler->handler == command_enable_command)) { puttext ("NOTICE %s :Command '%s' cannot be disabled\r\n", nick->nick, handler->command); } else { // disable command handler->disabled = 1; puttext ("NOTICE %s :Command '%s' has been disabled\r\n", nick->nick, handler->command); } }
static void on_recent_menu_item_activate(G_GNUC_UNUSED GtkMenuItem *menuitem, const gchar *name) { RecentProgram *recent = (RecentProgram *) array_find(recent_programs, name, TRUE); if (recent && utils_filenamecmp(recent->name, *program_executable ? program_executable : program_load_script)) { char *configfile = recent_file_name(recent->id); GKeyFile *config = g_key_file_new(); GError *gerror = NULL; gchar *message; if (g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, &gerror)) { save_program_settings(); recent = (RecentProgram *) array_find(recent_programs, name, TRUE); stash_foreach((GFunc) stash_group_load_from_key_file, config); if ((unsigned) option_inspect_expand > EXPAND_MAX) option_inspect_expand = 100; breaks_load(config); watches_load(config); inspects_load(config); parse_load(config); message = g_strdup_printf(_("Loaded debug settings for %s."), recent->name); g_array_insert_vals(recent_programs, 0, ++recent, 1); array_remove(recent_programs, recent); recent_menu_create(); program_configure(); } else { message = g_strdup_printf(_("Could not load debug settings file %s: %s."), configfile, gerror->message); g_error_free(gerror); } if (menuitem) ui_set_statusbar(TRUE, "%s", message); else msgwin_status_add("%s", message); g_free(message); g_key_file_free(config); g_free(configfile); } }
void ewmh_window_update_tag(Window win, HSTag* tag) { int index = array_find(g_tags->data, g_tags->len, sizeof(HSTag*), &tag); if (index < 0) { g_warning("tag %s not found in internal list\n", tag->name->str); return; } XChangeProperty(g_display, win, g_netatom[NetWmDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&(index), 1); }
int scamper_dealias_prefixscan_xs_in(scamper_dealias_t *dealias, scamper_addr_t *addr) { scamper_dealias_prefixscan_t *prefixscan = dealias->data; if(array_find((void **)prefixscan->xs, prefixscan->xc, addr, (array_cmp_t)scamper_addr_cmp) != NULL) return 1; return 0; }
int test_array() { int *a[] = {NULL, NULL}; // 从变量标识符开始 // end with the basic type // go right when you can, go left when you must // 优先级[],()大于* int *(*b)[] = &a; (void) a; printf("sizeof(int *) = %ld\n", sizeof(int *)); printf("sizeof(func_1) = %ld\n", sizeof(func_1)); printf("sizeof(a) = %ld\n", sizeof(a)); printf("a %p &a[0] %p &a[1] %p\n", a, &a[0], &a[1]); printf("b %p\n", b); int i = 2; intp pi = &i; printf("i = %d\n", *pi); // array int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; printf("idx of 0: %d\n", array_find(arr, 10, 0)); printf("idx of 1: %d\n", array_find(arr, 10, 1)); printf("idx of 5: %d\n", array_find(arr, 10, 5)); printf("idx of 10: %d\n", array_find(arr, 10, 10)); printf("idx of 11: %d\n", array_find(arr, 10, 11)); // string printf("== TEST string ==\n"); printf("null char %d\n", '\0'); assert(str_cmp("abc", "abc") == 0); assert(str_cmp("abc", "ab") > 0); assert(str_cmp("abc", "abcd") < 0); char dest[256]; printf("str_cpy %s\n", str_cpy(dest, "abc")); printf("str_cpy %s\n", str_cpy(dest, "abcd")); printf("str_cpy %s\n", str_cpy(dest, "ab")); return 0; }
void ewmh_update_current_desktop() { HSTag* tag = get_current_monitor()->tag; int index = array_find(g_tags->data, g_tags->len, sizeof(HSTag*), &tag); if (index < 0) { g_warning("tag %s not found in internal list\n", tag->name->str); return; } XChangeProperty(g_display, g_root, g_netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&(index), 1); }
bool granted(CHAR_DATA *ch, char * command) { if(!ch || !command || command[0]=='\0' || IS_NPC(ch) || !ch->pcdata || !ch->pcdata->granted || array_len(ch->pcdata->granted)==0) return FALSE; if(array_find(ch->pcdata->granted, command)!=-1) return TRUE; return FALSE; }
void ewmh_remove_client(Window win) { int index = array_find(g_windows, g_window_count, sizeof(Window), &win); if (index < 0) { g_warning("could not find window %lx in g_windows\n", win); } else { g_memmove(g_windows + index, g_windows + index + 1, sizeof(Window) *(g_window_count - index - 1)); g_windows = g_renew(Window, g_windows, g_window_count - 1); g_window_count--; } ewmh_update_client_list(); ewmh_update_client_list_stacking(); }
static void save_program_settings(void) { const gchar *program_name = *program_executable ? program_executable : program_load_script; if (*program_name) { RecentProgram *recent = (RecentProgram *) array_find(recent_programs, program_name, TRUE); GKeyFile *config = g_key_file_new(); char *configfile; if (!recent) { recent = (RecentProgram *) array_append(recent_programs); recent->name = g_strdup(program_name); for (recent->id = 1; recent->id < RECENT_COUNT; recent->id++) if ((recent_bitmap & (1 << recent->id)) == 0) break; recent_bitmap |= 1 << recent->id; } configfile = recent_file_name(recent->id); stash_foreach((GFunc) stash_group_save_to_key_file, config); breaks_save(config); watches_save(config); inspects_save(config); parse_save(config); utils_key_file_write_to_file(config, configfile); g_free(configfile); g_key_file_free(config); g_array_insert_vals(recent_programs, 0, ++recent, 1); array_remove(recent_programs, recent); recent_menu_create(); if (recent_programs->len > RECENT_COUNT) { recent_bitmap &= ~(1 << recent->id); array_remove(recent_programs, recent); } } }
/* * task_fd * * make sure the task has a hold on this fd. */ static scamper_fd_t *task_fd(scamper_task_t *t, scamper_fd_t *fd) { if(fd == NULL) return NULL; if(array_find((void **)t->fds, t->fdc, fd, (array_cmp_t)task_fd_cmp) == NULL) { if(array_insert((void ***)&t->fds, &t->fdc, fd, (array_cmp_t)task_fd_cmp) != 0) { scamper_fd_free(fd); return NULL; } } else { /* already have a hold of the fd */ scamper_fd_free(fd); } return fd; }
int scamper_dealias_prefixscan_xs_add(scamper_dealias_t *dealias, scamper_addr_t *addr) { scamper_dealias_prefixscan_t *prefixscan = dealias->data; int tmp; if(array_find((void **)prefixscan->xs, prefixscan->xc, addr, (array_cmp_t)scamper_addr_cmp) != NULL) return 0; if((tmp = prefixscan->xc) == 65535) return -1; if(array_insert((void ***)&prefixscan->xs, &tmp, addr, (array_cmp_t)scamper_addr_cmp) != 0) return -1; scamper_addr_use(addr); prefixscan->xc++; return 0; }
intx snow_arguments_add_name(SnArguments* args, SnSymbol sym) { VALUE vsym = symbol_to_value(sym); intx idx = array_find(NAMES, vsym); if (idx < 0) { // not found, but first fill out the unnamed slots for (idx = 0; idx < array_size(NAMES); ++idx) { if (!snow_eval_truth(array_get(NAMES, idx))) { array_set(NAMES, idx, vsym); return idx; } } // no unnamed slots, add it at the end idx = array_size(NAMES); array_push(NAMES, vsym); } return idx; }
void command_enable_command (NICK * nick, CHANNEL * channel, const char *cmd, const char **args, int argc) { struct command_s *handler; // show usage if (argc < 1) { puttext ("NOTICE %s :Usage: %s command\r\n", nick->nick, cmd); return; } // find handler if (!(handler = array_find (commands, args[0]))) { puttext ("NOTICE %s :Command '%s' not known\r\n", nick->nick, args[0]); } else { // enable it handler->disabled = 0; puttext ("NOTICE %s :Command '%s' has been enabled\r\n", nick->nick, handler->command); } }
int stream_process (stream_t* strm, account_t* account, extension_t* ext) { if (strm == NULL) fatal ("stream_start: strm is null"); if (account == NULL) fatal ("stream_start: account is null"); int err = 0; switch (strm->state) { case STREAM_STATE_NONE: fatal ("stream_process: strm->state is STREAM_STATE_NONE"); case STREAM_STATE_START: { if (ext->type != EXTENSION_TYPE_STREAM_START) return ERR_BAD_PROTOCOL; struct stream_start_t* s = (struct stream_start_t*) ext->data; if (s->fVersion != NULL && strcmp (s->fVersion, "1.0") != 0) return ERR_XMPP_VERSION; stream_start_free (ext->data); strm->state = STREAM_STATE_WANT_FEATURES; break; } case STREAM_STATE_WANT_FEATURES: { if (ext->type != EXTENSION_TYPE_STREAM_FEATURES) return ERR_BAD_PROTOCOL; struct stream_features_data_t* stream_data = strm->userdata; stream_data->features = ext->data; uint8_t i = 0; for (i = stream_data->iterator; i < knownfeatures_len; i++ ) { extension_t* feature = array_find (stream_data->features, knownfeatures[i]->extension_type); if (feature == NULL) { if (knownfeatures[i]->is_mandatory(strm)) return ERR_FEATURE_IS_REQUIRED; else continue; } strm->state = STREAM_STATE_NEGOTATE; stream_data->iterator = i; err = knownfeatures[i]->negotate (strm, account, &stream_data->data, feature); if (err == 1) return 0; if (err != 0) return err; return 0; } stream_features_free (stream_data->features); free (strm->userdata); strm->userdata = NULL; strm->state = STREAM_STATE_ESTABLISHED; break; } case STREAM_STATE_NEGOTATE: { struct stream_features_data_t* stream_data = strm->userdata; err = knownfeatures[stream_data->iterator]->negotate (strm, account, &stream_data->data, ext); xstream_extension_free (ext); if (err == 1) return 0; if (err != 0) return err; if (knownfeatures[stream_data->iterator]->need_to_restart()) { stream_features_free (stream_data->features); xmlreader_reset (&strm->reader); xmlwriter_reset (&strm->writer); int err = xmlwriter_set_prefix (&strm->writer, NULL, strm->content_namespace); if (err != 0) fatal ("stream_new: cannot set default namespace"); stream_data->iterator++; strm->state = STREAM_STATE_NONE; return stream_start (strm, account); } stream_data->iterator++; uint8_t i = 0; for (i = stream_data->iterator; i < knownfeatures_len; i++) { extension_t* feature = array_find (stream_data->features, knownfeatures[i]->extension_type); if (feature == NULL) { if (knownfeatures[i]->is_mandatory(strm)) return ERR_FEATURE_IS_REQUIRED; else continue; } strm->state = STREAM_STATE_NEGOTATE; stream_data->iterator = i; err = knownfeatures[i]->negotate (strm, account, &stream_data->data, feature); if (err == 1) return 0; if (err != 0) return err; break; } stream_features_free (stream_data->features); free (strm->userdata); strm->userdata = NULL; strm->state = STREAM_STATE_ESTABLISHED; return 0; } case STREAM_STATE_ESTABLISHED: if (strm->session_handler != NULL) strm->session_handler (strm, account, ext); xstream_extension_free (ext); // break; default: fatal ("Unknown stream state"); } return 0; }
void do_revoke(CHAR_DATA *ch, char *argument) { int cmd; CHAR_DATA * victim; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char ** newArray=0; char ** ar=0; char buf[MAX_STRING_LENGTH]; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if(arg1[0]=='\0' || arg2[0]=='\0') { send_to_char("\n\r{WSyntax:{C revoke {Y<player>{B <command>{x\n\r", ch); return; } if((victim=get_char_world(ch, arg1))==NULL) { send_to_char("\n\r{CThat Player is not online.{x\n\r", ch); return; } if(IS_NPC(victim)) { send_to_char("\n\r{RNot on NPC's.{x\n\r", ch ); return; } for(cmd=0;cmd_table[cmd].name[0]!='\0';cmd++) { if(!str_prefix(arg2, cmd_table[cmd].name)) break; } if(cmd_table[cmd].name[0]=='\0') { send_to_char("\n\r{RNo valid command found.{x\n\r", ch); return; } if(array_find(victim->pcdata->granted, cmd_table[cmd].name)==-1) { sprintf(buf, "\n\r{W%s{R has not yet been granted the {W%s{R command!{x\n\r", victim->name, cmd_table[cmd].name); send_to_char(buf, ch); return; } for(ar=victim->pcdata->granted;ar && *ar;ar++) { if(strcmp(*ar, cmd_table[cmd].name)) newArray = array_append(newArray, *ar); } victim->pcdata->granted = array_free(victim->pcdata->granted); victim->pcdata->granted = newArray; sprintf(buf, "\n\r{GCommand {W%s{G was revoked from player {W%s{x\n\r", cmd_table[cmd].name, victim->name); send_to_char(buf, ch); sprintf(buf, "\n\r{GYou have been revoked from using the command: {W%s{x\n\r", cmd_table[cmd].name); send_to_char(buf, victim); if(array_len(victim->pcdata->granted)==1 && !strcmp(victim->pcdata->granted[0], "wizhelp")) { sprintf(buf, "%s wizhelp", victim->name); do_revoke(ch, buf); } return; }
void do_grant(CHAR_DATA *ch, char *argument) { int cmd; CHAR_DATA * victim; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if(arg1[0]=='\0') { send_to_char("\n\r{WSyntax:{C grant {Y<player>{B <command>{x\n\r", ch); return; } if((victim=get_char_world(ch, arg1))==NULL) { send_to_char("\n\r{CThat Player is not online.{x\n\r", ch); return; } if(IS_NPC(victim)) { send_to_char("\n\r{RNot on NPC's.{x\n\r", ch ); return; } if(arg2[0]=='\0') { sprintf(buf, "\n\r{CPlayer {W%s{C has been granted the following commands:{x\n\r", victim->name); send_to_char(buf, ch); show_granted_to_char(victim, ch); return; } if(!strcmp(arg2, "builder")) { sprintf(buf, "%s alist", victim->name); do_grant(ch, buf); sprintf(buf, "%s asave", victim->name); do_grant(ch, buf); sprintf(buf, "%s force", victim->name); do_grant(ch, buf); sprintf(buf, "%s fvlist", victim->name); do_grant(ch, buf); sprintf(buf, "%s goto", victim->name); do_grant(ch, buf); sprintf(buf, "%s grab", victim->name); do_grant(ch, buf); sprintf(buf, "%s hedit", victim->name); do_grant(ch, buf); sprintf(buf, "%s holylight", victim->name); do_grant(ch, buf); sprintf(buf, "%s medit", victim->name); do_grant(ch, buf); sprintf(buf, "%s mlevel", victim->name); do_grant(ch, buf); sprintf(buf, "%s mload", victim->name); do_grant(ch, buf); sprintf(buf, "%s mpedit", victim->name); do_grant(ch, buf); sprintf(buf, "%s msearch", victim->name); do_grant(ch, buf); sprintf(buf, "%s mstat", victim->name); do_grant(ch, buf); sprintf(buf, "%s oedit", victim->name); do_grant(ch, buf); sprintf(buf, "%s oload", victim->name); do_grant(ch, buf); sprintf(buf, "%s olevel", victim->name); do_grant(ch, buf); sprintf(buf, "%s osearch", victim->name); do_grant(ch, buf); sprintf(buf, "%s ostat", victim->name); do_grant(ch, buf); sprintf(buf, "%s otype", victim->name); do_grant(ch, buf); sprintf(buf, "%s peace", victim->name); do_grant(ch, buf); sprintf(buf, "%s purge", victim->name); do_grant(ch, buf); sprintf(buf, "%s redit", victim->name); do_grant(ch, buf); sprintf(buf, "%s resets", victim->name); do_grant(ch, buf); sprintf(buf, "%s rstat", victim->name); do_grant(ch, buf); sprintf(buf, "%s slay", victim->name); do_grant(ch, buf); sprintf(buf, "%s stat", victim->name); do_grant(ch, buf); sprintf(buf, "%s vlist", victim->name); do_grant(ch, buf); sprintf(buf, "%s vnumlist", victim->name); do_grant(ch, buf); } for(cmd=0;cmd_table[cmd].name[0]!='\0';cmd++) { if(!str_prefix(arg2, cmd_table[cmd].name)) break; } if(cmd_table[cmd].name[0]=='\0') { send_to_char("\n\r{RNo valid command found.{x\n\r", ch); return; } if(strcmp(cmd_table[cmd].name, "wizhelp") && array_find(victim->pcdata->granted, "wizhelp")==-1) { sprintf(buf, "%s wizhelp", victim->name); do_grant(ch, buf); } if(array_find(victim->pcdata->granted, cmd_table[cmd].name)!=-1) { sprintf(buf, "\n\r{W%s{R already has the {W%s{R command!{x\n\r", victim->name, cmd_table[cmd].name); send_to_char(buf, ch); return; } victim->pcdata->granted = array_append(victim->pcdata->granted, cmd_table[cmd].name); sprintf(buf, "\n\r{GCommand {W%s{G was granted to player {W%s{x\n\r", cmd_table[cmd].name, victim->name); send_to_char(buf, ch); sprintf(buf, "\n\r{GYou have been granted the command: {W%s{x\n\r", cmd_table[cmd].name); send_to_char(buf, victim); return; }
/** * Try to parse a command and call handler. * @param nick - Calling nick * @param channel - Possible channel * @param line - possible command line * @return 1 if no command, 0 if command */ int command_try_parse (NICK * nick, CHANNEL * channel, const char *line) { struct command_s *handler; char **phase1; char **phase2; char **tptr; int nphase1; int nphase2; /* Use the channel-parse-line */ phase1 = phase2 = NULL; if (channel) { // we know we have a channel, so we just split it in three parts // namely, trigger, command, args string_split (line, 3, &phase1, &nphase1); // failed. if (phase1 == NULL) return 1; // was it addressed to me? if ((strrfccmp (phase1[0], irc_get_me ()->nick)) && (strrfccmp (phase1[0], trigger))) { free (phase1[0]); free (phase1); return 1; } // do we have such command? if (!(handler = array_find (commands, phase1[1]))) { free (phase1[0]); free (phase1); return 1; } // is it available to use? if (handler->disabled) { puttext ("NOTICE %s :Command disabled\r\n", nick->nick); free (phase1[0]); free (phase1); return 0; } nphase2 = 0; // ensure permissions if (command_check_perms (nick, channel, handler)) { if (nick->user) puttext ("NOTICE %s :Permission denied\r\n", nick->nick); print ("%s[%s] tried to use %s - denied", nick->nick, (nick->user ? nick->user->user : "******"), handler->command); } else { // phase 2. Split arguments as the handler would like to have them // (sunny side up? My of course!) string_split (phase1[2], handler->params, &phase2, &nphase2); print ("%s[%s] used %s on %s", nick->nick, (nick->user ? nick->user->user : "******"), handler->command, channel->channel); // call handler callback (*handler->handler) (nick, channel, handler->command, (const char **) phase2, nphase2); } // release memory if (phase2) { free (phase2[0]); free (phase2); } free (phase1[0]); free (phase1); return 0; } else { // OK. here we do not have the luxury of knowing channel. // this: here: splits the string into command and args. string_split (line, 2, &phase1, &nphase1); if (phase1 == NULL) return 1; // locate handler if (!(handler = array_find (commands, phase1[0]))) { free (phase1[0]); free (phase1); return 1; } // is it disabled if (handler->disabled) { puttext ("NOTICE %s :Command disabled\r\n", nick->nick); free (phase1[0]); free (phase1); return 0; } nphase2 = 0; // in contrast to behaviour before, we split the string before // permission checks. The channel is added there, IF needed. if (handler->needchan) { string_split (phase1[1], (handler->params == 0 ? 0 : handler->params + 1), &phase2, &nphase2); // check that there is a channel. if (nphase2 < 1) { puttext ("NOTICE %s :Command '%s' needs a valid channel as first argument\r\n", nick->nick, handler->command); free (phase1[0]); free (phase1); return 0; } // check again. if ((channel = channel_find (phase2[0])) == NULL) { puttext ("NOTICE %s :Command '%s' needs a valid channel as first argument - not %s\r\n", nick->nick, handler->command, phase2[0]); // free memory if (phase2) { free (phase2[0]); free (phase2); } free (phase1[0]); free (phase1); return 0; } } else { // split the params normally. string_split (phase1[1], handler->params, &phase2, &nphase2); } // check for access. if (command_check_perms (nick, channel, handler)) { if (nick->user) puttext ("NOTICE %s :Permission denied\r\n", nick->nick); print ("%s[%s] tried to use %s - denied", nick->nick, (nick->user ? nick->user->user : "******"), handler->command); if (phase2) { free (phase2[0]); free (phase2); } free (phase1[0]); free (phase1); return 0; } // log usage if (channel) { print ("%s[%s] used %s on %s", nick->nick, (nick->user ? nick->user->user : "******"), handler->command, channel->channel); } else { print ("%s[%s] used %s", nick->nick, (nick->user ? nick->user->user : "******"), handler->command); } // execute properly. if (handler->needchan) { (*handler->handler) (nick, channel, handler->command, (const char **) (nphase2 - handler->needchan ? phase2 + 1 : NULL), nphase2 - handler->needchan); } else { (*handler->handler) (nick, channel, handler->command, (const char **) phase2, nphase2); } // free memory if (phase2) { free (phase2[0]); free (phase2); } if (phase1) { free (phase1[0]); free (phase1); } return 0; } return 1; }
void execute(INST * cdp, /* code ptr, start execution here */ CELL *sp, /* eval_stack pointer */ CELL *fp) /* frame ptr into eval_stack for user defined functions */ { /* some useful temporaries */ CELL *cp; int t; unsigned tu; /* save state for array loops via a stack */ ALOOP_STATE *aloop_state = (ALOOP_STATE *) 0; /* for moving the eval stack on deep recursion */ CELL *old_stack_base = 0; CELL *old_sp = 0; #ifdef DEBUG CELL *entry_sp = sp; #endif int force_exit = (end_start == 0); if (fp) { /* we are a function call, check for deep recursion */ if (sp > stack_danger) { /* change stacks */ old_stack_base = stack_base; old_sp = sp; stack_base = (CELL *) zmalloc(sizeof(CELL) * EVAL_STACK_SIZE); stack_danger = stack_base + DANGER; sp = stack_base; /* waste 1 slot for ANSI, actually large model msdos breaks in RET if we don't */ #ifdef DEBUG entry_sp = sp; #endif } else old_stack_base = (CELL *) 0; } while (1) { TRACE(("execute %s sp(%ld:%s)\n", da_op_name(cdp), (long) (sp - stack_base), da_type_name(sp))); switch ((cdp++)->op) { /* HALT only used by the disassemble now ; this remains so compilers don't offset the jump table */ case _HALT: case _STOP: /* only for range patterns */ #ifdef DEBUG if (sp != entry_sp + 1) bozo("stop0"); #endif return; case _PUSHC: inc_sp(); cellcpy(sp, (cdp++)->ptr); break; case _PUSHD: inc_sp(); sp->type = C_DOUBLE; sp->dval = *(double *) (cdp++)->ptr; break; case _PUSHS: inc_sp(); sp->type = C_STRING; sp->ptr = (cdp++)->ptr; string(sp)->ref_cnt++; break; case F_PUSHA: cp = (CELL *) cdp->ptr; if (cp != field) { if (nf < 0) split_field0(); if (!(cp >= NF && cp <= LAST_PFIELD)) { /* it is a real field $1, $2 ... If it is greater than $NF, we have to make sure it is set to "" so that (++|--) and g?sub() work right */ t = field_addr_to_index(cp); if (t > nf) { cp->type = C_STRING; cp->ptr = (PTR) & null_str; null_str.ref_cnt++; } } } /* fall thru */ case _PUSHA: case A_PUSHA: inc_sp(); sp->ptr = (cdp++)->ptr; break; case _PUSHI: /* put contents of next address on stack */ inc_sp(); cellcpy(sp, (cdp++)->ptr); break; case L_PUSHI: /* put the contents of a local var on stack, cdp->op holds the offset from the frame pointer */ inc_sp(); cellcpy(sp, fp + (cdp++)->op); break; case L_PUSHA: /* put a local address on eval stack */ inc_sp(); sp->ptr = (PTR) (fp + (cdp++)->op); break; case F_PUSHI: /* push contents of $i cdp[0] holds & $i , cdp[1] holds i */ inc_sp(); if (nf < 0) split_field0(); cp = (CELL *) cdp->ptr; t = (cdp + 1)->op; cdp += 2; if (t <= nf) cellcpy(sp, cp); else { /* an unset field */ sp->type = C_STRING; sp->ptr = (PTR) & null_str; null_str.ref_cnt++; } break; case NF_PUSHI: inc_sp(); if (nf < 0) split_field0(); cellcpy(sp, NF); break; case FE_PUSHA: if (sp->type != C_DOUBLE) cast1_to_d(sp); tu = d_to_index(sp->dval); if (tu && nf < 0) split_field0(); sp->ptr = (PTR) field_ptr((int) tu); if ((int) tu > nf) { /* make sure it is set to "" */ cp = (CELL *) sp->ptr; cell_destroy(cp); cp->type = C_STRING; cp->ptr = (PTR) & null_str; null_str.ref_cnt++; } break; case FE_PUSHI: if (sp->type != C_DOUBLE) cast1_to_d(sp); tu = d_to_index(sp->dval); if (nf < 0) split_field0(); if ((int) tu <= nf) { cellcpy(sp, field_ptr((int) tu)); } else { sp->type = C_STRING; sp->ptr = (PTR) & null_str; null_str.ref_cnt++; } break; case AE_PUSHA: /* top of stack has an expr, cdp->ptr points at an array, replace the expr with the cell address inside the array */ cp = array_find((ARRAY) (cdp++)->ptr, sp, CREATE); cell_destroy(sp); sp->ptr = (PTR) cp; break; case AE_PUSHI: /* top of stack has an expr, cdp->ptr points at an array, replace the expr with the contents of the cell inside the array */ cp = array_find((ARRAY) (cdp++)->ptr, sp, CREATE); cell_destroy(sp); cellcpy(sp, cp); break; case LAE_PUSHI: /* sp[0] is an expression cdp->op is offset from frame pointer of a CELL which has an ARRAY in the ptr field, replace expr with array[expr] */ if (fp != 0) { cp = array_find((ARRAY) fp[(cdp++)->op].ptr, sp, CREATE); cell_destroy(sp); cellcpy(sp, cp); } break; case LAE_PUSHA: /* sp[0] is an expression cdp->op is offset from frame pointer of a CELL which has an ARRAY in the ptr field, replace expr with & array[expr] */ if (fp != 0) { cp = array_find((ARRAY) fp[(cdp++)->op].ptr, sp, CREATE); cell_destroy(sp); sp->ptr = (PTR) cp; } break; case LA_PUSHA: /* cdp->op is offset from frame pointer of a CELL which has an ARRAY in the ptr field. Push this ARRAY on the eval stack */ if (fp != 0) { inc_sp(); sp->ptr = fp[(cdp++)->op].ptr; } break; case SET_ALOOP: { ALOOP_STATE *ap = ZMALLOC(ALOOP_STATE); size_t vector_size; ap->var = (CELL *) sp[-1].ptr; ap->base = ap->ptr = array_loop_vector((ARRAY) sp->ptr, &vector_size); ap->limit = ap->base + vector_size; sp -= 2; /* push onto aloop stack */ ap->link = aloop_state; aloop_state = ap; cdp += cdp->op; } break; case ALOOP: { ALOOP_STATE *ap = aloop_state; if (ap != 0 && (ap->ptr < ap->limit)) { cell_destroy(ap->var); ap->var->type = C_STRING; ap->var->ptr = (PTR) * ap->ptr++; cdp += cdp->op; } else { cdp++; } } break; case POP_AL: { /* finish up an array loop */ ALOOP_STATE *ap = aloop_state; if (ap != 0) { aloop_state = ap->link; while (ap->ptr < ap->limit) { free_STRING(*ap->ptr); ap->ptr++; } if (ap->base < ap->limit) { zfree(ap->base, ((unsigned) (ap->limit - ap->base) * sizeof(STRING *))); } ZFREE(ap); } } break; case _POP: cell_destroy(sp); sp--; break; case _ASSIGN: /* top of stack has an expr, next down is an address, put the expression in *address and replace the address with the expression */ /* don't propagate type C_MBSTRN */ if (sp->type == C_MBSTRN) check_strnum(sp); sp--; cell_destroy(((CELL *) sp->ptr)); cellcpy(sp, cellcpy(sp->ptr, sp + 1)); cell_destroy(sp + 1); break; case F_ASSIGN: /* assign to a field */ if (sp->type == C_MBSTRN) check_strnum(sp); sp--; field_assign((CELL *) sp->ptr, sp + 1); cell_destroy(sp + 1); cellcpy(sp, (CELL *) sp->ptr); break; case _ADD_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); #ifdef SW_FP_CHECK /* specific to V7 and XNX23A */ clrerr(); #endif cp->dval += (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = cp->dval; break; case _SUB_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); #ifdef SW_FP_CHECK clrerr(); #endif cp->dval -= (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = cp->dval; break; case _MUL_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); #ifdef SW_FP_CHECK clrerr(); #endif cp->dval *= (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = cp->dval; break; case _DIV_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); #ifdef NOINFO_SIGFPE CHECK_DIVZERO(sp->dval); #endif #ifdef SW_FP_CHECK clrerr(); #endif cp->dval /= (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = cp->dval; break; case _MOD_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); #ifdef NOINFO_SIGFPE CHECK_DIVZERO(sp->dval); #endif cp->dval = fmod(cp->dval, (sp--)->dval); sp->type = C_DOUBLE; sp->dval = cp->dval; break; case _POW_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); cp->dval = pow(cp->dval, (sp--)->dval); sp->type = C_DOUBLE; sp->dval = cp->dval; break; /* will anyone ever use these ? */ case F_ADD_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; cast1_to_d(cellcpy(&tc, cp)); #ifdef SW_FP_CHECK clrerr(); #endif tc.dval += (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = tc.dval; field_assign(cp, &tc); break; case F_SUB_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; cast1_to_d(cellcpy(&tc, cp)); #ifdef SW_FP_CHECK clrerr(); #endif tc.dval -= (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = tc.dval; field_assign(cp, &tc); break; case F_MUL_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; cast1_to_d(cellcpy(&tc, cp)); #ifdef SW_FP_CHECK clrerr(); #endif tc.dval *= (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = tc.dval; field_assign(cp, &tc); break; case F_DIV_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; cast1_to_d(cellcpy(&tc, cp)); #ifdef NOINFO_SIGFPE CHECK_DIVZERO(sp->dval); #endif #ifdef SW_FP_CHECK clrerr(); #endif tc.dval /= (sp--)->dval; #ifdef SW_FP_CHECK fpcheck(); #endif sp->type = C_DOUBLE; sp->dval = tc.dval; field_assign(cp, &tc); break; case F_MOD_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; cast1_to_d(cellcpy(&tc, cp)); #ifdef NOINFO_SIGFPE CHECK_DIVZERO(sp->dval); #endif tc.dval = fmod(tc.dval, (sp--)->dval); sp->type = C_DOUBLE; sp->dval = tc.dval; field_assign(cp, &tc); break; case F_POW_ASG: if (sp->type != C_DOUBLE) cast1_to_d(sp); cp = (CELL *) (sp - 1)->ptr; cast1_to_d(cellcpy(&tc, cp)); tc.dval = pow(tc.dval, (sp--)->dval); sp->type = C_DOUBLE; sp->dval = tc.dval; field_assign(cp, &tc); break; case _ADD: sp--; if (TEST2(sp) != TWO_DOUBLES) cast2_to_d(sp); #ifdef SW_FP_CHECK clrerr(); #endif sp[0].dval += sp[1].dval; #ifdef SW_FP_CHECK fpcheck(); #endif break; case _SUB: sp--; if (TEST2(sp) != TWO_DOUBLES) cast2_to_d(sp); #ifdef SW_FP_CHECK clrerr(); #endif sp[0].dval -= sp[1].dval; #ifdef SW_FP_CHECK fpcheck(); #endif break; case _MUL: sp--; if (TEST2(sp) != TWO_DOUBLES) cast2_to_d(sp); #ifdef SW_FP_CHECK clrerr(); #endif sp[0].dval *= sp[1].dval; #ifdef SW_FP_CHECK fpcheck(); #endif break; case _DIV: sp--; if (TEST2(sp) != TWO_DOUBLES) cast2_to_d(sp); #ifdef NOINFO_SIGFPE CHECK_DIVZERO(sp[1].dval); #endif #ifdef SW_FP_CHECK clrerr(); #endif sp[0].dval /= sp[1].dval; #ifdef SW_FP_CHECK fpcheck(); #endif break; case _MOD: sp--; if (TEST2(sp) != TWO_DOUBLES) cast2_to_d(sp); #ifdef NOINFO_SIGFPE CHECK_DIVZERO(sp[1].dval); #endif sp[0].dval = fmod(sp[0].dval, sp[1].dval); break; case _POW: sp--; if (TEST2(sp) != TWO_DOUBLES) cast2_to_d(sp); sp[0].dval = pow(sp[0].dval, sp[1].dval); break; case _NOT: /* evaluates to 0.0 or 1.0 */ reswitch_1: switch (sp->type) { case C_NOINIT: sp->dval = 1.0; break; case C_DOUBLE: sp->dval = sp->dval != 0.0 ? 0.0 : 1.0; break; case C_FIELDWIDTHS: case C_STRING: sp->dval = string(sp)->len ? 0.0 : 1.0; free_STRING(string(sp)); break; case C_STRNUM: /* test as a number */ sp->dval = sp->dval != 0.0 ? 0.0 : 1.0; free_STRING(string(sp)); break; case C_MBSTRN: check_strnum(sp); goto reswitch_1; default: bozo("bad type on eval stack"); } sp->type = C_DOUBLE; break; case _TEST: /* evaluates to 0.0 or 1.0 */ reswitch_2: switch (sp->type) { case C_NOINIT: sp->dval = 0.0; break; case C_DOUBLE: sp->dval = sp->dval != 0.0 ? 1.0 : 0.0; break; case C_FIELDWIDTHS: case C_STRING: sp->dval = string(sp)->len ? 1.0 : 0.0; free_STRING(string(sp)); break; case C_STRNUM: /* test as a number */ sp->dval = sp->dval != 0.0 ? 1.0 : 0.0; free_STRING(string(sp)); break; case C_MBSTRN: check_strnum(sp); goto reswitch_2; default: bozo("bad type on eval stack"); } sp->type = C_DOUBLE; break; case _UMINUS: if (sp->type != C_DOUBLE) cast1_to_d(sp); sp->dval = -sp->dval; break; case _UPLUS: if (sp->type != C_DOUBLE) cast1_to_d(sp); break; case _CAT: { size_t len1, len2; char *str1, *str2; STRING *b; sp--; if (TEST2(sp) != TWO_STRINGS) cast2_to_s(sp); str1 = string(sp)->str; len1 = string(sp)->len; str2 = string(sp + 1)->str; len2 = string(sp + 1)->len; b = new_STRING0(len1 + len2); memcpy(b->str, str1, len1); memcpy(b->str + len1, str2, len2); free_STRING(string(sp)); free_STRING(string(sp + 1)); sp->ptr = (PTR) b; break; } case _PUSHINT: inc_sp(); sp->type = (short) (cdp++)->op; break; case _BUILTIN: case _PRINT: sp = (*(PF_CP) (cdp++)->ptr) (sp); break; case _POST_INC: cp = (CELL *) sp->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); sp->type = C_DOUBLE; sp->dval = cp->dval; cp->dval += 1.0; break; case _POST_DEC: cp = (CELL *) sp->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); sp->type = C_DOUBLE; sp->dval = cp->dval; cp->dval -= 1.0; break; case _PRE_INC: cp = (CELL *) sp->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); sp->dval = cp->dval += 1.0; sp->type = C_DOUBLE; break; case _PRE_DEC: cp = (CELL *) sp->ptr; if (cp->type != C_DOUBLE) cast1_to_d(cp); sp->dval = cp->dval -= 1.0; sp->type = C_DOUBLE; break; case F_POST_INC: cp = (CELL *) sp->ptr; cellcpy(&tc, cp); cast1_to_d(&tc); sp->type = C_DOUBLE; sp->dval = tc.dval; tc.dval += 1.0; field_assign(cp, &tc); break; case F_POST_DEC: cp = (CELL *) sp->ptr; cellcpy(&tc, cp); cast1_to_d(&tc); sp->type = C_DOUBLE; sp->dval = tc.dval; tc.dval -= 1.0; field_assign(cp, &tc); break; case F_PRE_INC: cp = (CELL *) sp->ptr; cast1_to_d(cellcpy(sp, cp)); sp->dval += 1.0; field_assign(cp, sp); break; case F_PRE_DEC: cp = (CELL *) sp->ptr; cast1_to_d(cellcpy(sp, cp)); sp->dval -= 1.0; field_assign(cp, sp); break; case _JMP: cdp += cdp->op; break; case _JNZ: /* jmp if top of stack is non-zero and pop stack */ if (test(sp)) cdp += cdp->op; else cdp++; cell_destroy(sp); sp--; break; case _JZ: /* jmp if top of stack is zero and pop stack */ if (!test(sp)) cdp += cdp->op; else cdp++; cell_destroy(sp); sp--; break; case _LJZ: /* special jump for logical and */ /* this is always preceded by _TEST */ if (sp->dval == 0.0) { /* take jump, but don't pop stack */ cdp += cdp->op; } else { /* pop and don't jump */ sp--; cdp++; } break; case _LJNZ: /* special jump for logical or */ /* this is always preceded by _TEST */ if (sp->dval != 0.0) { /* take jump, but don't pop stack */ cdp += cdp->op; } else { /* pop and don't jump */ sp--; cdp++; } break; /* the relation operations */ /* compare() makes sure string ref counts are OK */ case _EQ: t = compare(--sp); sp->type = C_DOUBLE; sp->dval = t == 0 ? 1.0 : 0.0; break; case _NEQ: t = compare(--sp); sp->type = C_DOUBLE; sp->dval = t ? 1.0 : 0.0; break; case _LT: t = compare(--sp); sp->type = C_DOUBLE; sp->dval = t < 0 ? 1.0 : 0.0; break; case _LTE: t = compare(--sp); sp->type = C_DOUBLE; sp->dval = t <= 0 ? 1.0 : 0.0; break; case _GT: t = compare(--sp); sp->type = C_DOUBLE; sp->dval = t > 0 ? 1.0 : 0.0; break; case _GTE: t = compare(--sp); sp->type = C_DOUBLE; sp->dval = t >= 0 ? 1.0 : 0.0; break; case _MATCH0: /* does $0 match, the RE at cdp? */ inc_sp(); if (field->type >= C_STRING) { sp->type = C_DOUBLE; sp->dval = (REtest(string(field)->str, string(field)->len, cast_to_re((cdp++)->ptr)) ? 1.0 : 0.0); break /* the case */ ; } else { cellcpy(sp, field); /* and FALL THRU */ } case _MATCH1: /* does expr at sp[0] match RE at cdp */ if (sp->type < C_STRING) cast1_to_s(sp); t = REtest(string(sp)->str, string(sp)->len, cast_to_re((cdp++)->ptr)); free_STRING(string(sp)); sp->type = C_DOUBLE; sp->dval = t ? 1.0 : 0.0; break; case _MATCH2: /* does sp[-1] match sp[0] as re */ cast_to_RE(sp); if ((--sp)->type < C_STRING) cast1_to_s(sp); t = REtest(string(sp)->str, string(sp)->len, cast_to_re((sp + 1)->ptr)); free_STRING(string(sp)); no_leaks_re_ptr((sp + 1)->ptr); sp->type = C_DOUBLE; sp->dval = t ? 1.0 : 0.0; break; case A_LENGTH: sp--; sp->type = C_DOUBLE; sp->dval = (double) (((ARRAY) ((sp + 0)->ptr))->size); break; case A_TEST: /* entry : sp[0].ptr-> an array sp[-1] is an expression we compute (expression in array) */ sp--; cp = array_find((sp + 1)->ptr, sp, NO_CREATE); cell_destroy(sp); sp->type = C_DOUBLE; sp->dval = (cp != (CELL *) 0) ? 1.0 : 0.0; break; case A_DEL: /* sp[0].ptr -> array sp[-1] is an expr delete array[expr] */ array_delete(sp->ptr, sp - 1); cell_destroy(sp - 1); sp -= 2; break; case DEL_A: /* free all the array at once */ array_clear(sp->ptr); sp--; break; /* form a multiple array index */ case A_CAT: sp = array_cat(sp, (cdp++)->op); break; case _EXIT: if (sp->type != C_DOUBLE) cast1_to_d(sp); exit_code = d_to_i(sp->dval); sp--; /* fall thru */ case _EXIT0: if (force_exit) mawk_exit(exit_code); cdp = end_start; force_exit = 1; /* makes sure next exit exits */ if (begin_start) { free_codes("BEGIN", begin_start, begin_size); begin_start = 0; begin_size = 0; } if (main_start) { free_codes("MAIN", main_start, main_size); main_start = 0; main_size = 0; } sp = eval_stack - 1; /* might be in user function */ CLEAR_ALOOP_STACK(); /* ditto */ break; case _JMAIN: /* go from BEGIN code to MAIN code */ free_codes("BEGIN", begin_start, begin_size); begin_start = 0; begin_size = 0; cdp = main_start; break; case _OMAIN: if (!main_fin) open_main(); restart_label = cdp; cdp = next_label; break; case _NEXT: /* next might be inside an aloop -- clear stack */ CLEAR_ALOOP_STACK(); cdp = next_label; break; case _NEXTFILE: /* nextfile might be inside an aloop -- clear stack */ CLEAR_ALOOP_STACK(); FINsemi_close(main_fin); cdp = next_label; break; case OL_GL: { char *p; size_t len; if (!(p = FINgets(main_fin, &len))) { if (force_exit) mawk_exit(0); cdp = end_start; zfree(main_start, main_size); main_start = (INST *) 0; force_exit = 1; } else { set_field0(p, len); cdp = restart_label; rt_nr++; rt_fnr++; } } break; /* two kinds of OL_GL is a historical stupidity from working on a machine with very slow floating point emulation */ case OL_GL_NR: { char *p; size_t len; if (!(p = FINgets(main_fin, &len))) { if (force_exit) mawk_exit(0); cdp = end_start; zfree(main_start, main_size); main_start = (INST *) 0; force_exit = 1; } else { set_field0(p, len); cdp = restart_label; if (TEST2(NR) != TWO_DOUBLES) cast2_to_d(NR); NR->dval += 1.0; rt_nr++; FNR->dval += 1.0; rt_fnr++; } } break; case _RANGE: /* test a range pattern: pat1, pat2 { action } entry : cdp[0].op -- a flag, test pat1 if on else pat2 cdp[1].op -- offset of pat2 code from cdp cdp[2].op -- offset of action code from cdp cdp[3].op -- offset of code after the action from cdp cdp[4] -- start of pat1 code */ #define FLAG cdp[0].op #define PAT2 cdp[1].op #define ACTION cdp[2].op #define FOLLOW cdp[3].op #define PAT1 4 if (FLAG) /* test against pat1 */ { execute(cdp + PAT1, sp, fp); t = test(sp + 1); cell_destroy(sp + 1); if (t) FLAG = 0; else { cdp += FOLLOW; break; /* break the switch */ } } /* test against pat2 and then perform the action */ execute(cdp + PAT2, sp, fp); FLAG = test(sp + 1); cell_destroy(sp + 1); cdp += ACTION; break; /* function calls */ case _RET0: inc_sp(); sp->type = C_NOINIT; /* fall thru */ case _RET: #ifdef DEBUG if (sp != entry_sp + 1) bozo("ret"); #endif if (old_stack_base) /* reset stack */ { /* move the return value */ cellcpy(old_sp + 1, sp); cell_destroy(sp); zfree(stack_base, sizeof(CELL) * EVAL_STACK_SIZE); stack_base = old_stack_base; stack_danger = old_stack_base + DANGER; } /* return might be inside an aloop -- clear stack */ CLEAR_ALOOP_STACK(); return; case _CALL: /* cdp[0] holds ptr to "function block" cdp[1] holds number of input arguments */ { FBLOCK *fbp = (FBLOCK *) (cdp++)->ptr; int a_args = (cdp++)->op; /* actual number of args */ CELL *nfp = sp - a_args + 1; /* new fp for callee */ CELL *local_p = sp + 1; /* first local argument on stack */ char *type_p = 0; /* pts to type of an argument */ if (fbp->nargs) type_p = fbp->typev + a_args - 1; /* create space for locals */ t = fbp->nargs - a_args; /* t is number of locals */ while (t > 0) { t--; sp++; type_p++; sp->type = C_NOINIT; if ((type_p) != 0 && (*type_p == ST_LOCAL_ARRAY)) sp->ptr = (PTR) new_ARRAY(); } execute(fbp->code, sp, nfp); /* cleanup the callee's arguments */ /* putting return value at top of eval stack */ if ((type_p != 0) && (sp >= nfp)) { cp = sp + 1; /* cp -> the function return */ do { if (*type_p == ST_LOCAL_ARRAY) { if (sp >= local_p) { array_clear(sp->ptr); ZFREE((ARRAY) sp->ptr); } } else { cell_destroy(sp); } type_p--; sp--; } while (sp >= nfp); cellcpy(++sp, cp); cell_destroy(cp); } else sp++; /* no arguments passed */ } break; default: bozo("bad opcode"); } } }
static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev) { struct snd_card *card; struct snd_opl3 *opl3; struct snd_cmi8328 *cmi; #ifdef SUPPORT_JOYSTICK struct resource *res; #endif int err, pos; static long mpu_ports[] = { 0x330, 0x300, 0x310, 0x320, 0x332, 0x334, 0x336, -1 }; static u8 mpu_port_bits[] = { 3, 0, 1, 2, 4, 5, 6 }; static int mpu_irqs[] = { 9, 7, 5, 3, -1 }; static u8 mpu_irq_bits[] = { 3, 2, 1, 0 }; static int irqs[] = { 9, 10, 11, 7, -1 }; static u8 irq_bits[] = { 2, 3, 4, 1 }; static int dma1s[] = { 3, 1, 0, -1 }; static u8 dma_bits[] = { 3, 2, 1 }; static int dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1}, {0, -1} }; u16 port = cmi8328_ports[ndev]; u8 val; /* 0xff is invalid configuration (but settable - hope it isn't set) */ if (snd_cmi8328_cfg_read(port, CFG1) == 0xff) return -ENODEV; /* the SB disable bit must NEVER EVER be cleared or the WSS dies */ snd_cmi8328_cfg_write(port, CFG1, CFG1_SB_DISABLE); if (snd_cmi8328_cfg_read(port, CFG1) != CFG1_SB_DISABLE) return -ENODEV; /* disable everything first */ snd_cmi8328_cfg_write(port, CFG2, 0); /* disable CDROM and MPU401 */ snd_cmi8328_cfg_write(port, CFG3, 0); /* disable CDROM IRQ and DMA */ if (irq[ndev] == SNDRV_AUTO_IRQ) { irq[ndev] = snd_legacy_find_free_irq(irqs); if (irq[ndev] < 0) { snd_printk(KERN_ERR "unable to find a free IRQ\n"); return -EBUSY; } } if (dma1[ndev] == SNDRV_AUTO_DMA) { dma1[ndev] = snd_legacy_find_free_dma(dma1s); if (dma1[ndev] < 0) { snd_printk(KERN_ERR "unable to find a free DMA1\n"); return -EBUSY; } } if (dma2[ndev] == SNDRV_AUTO_DMA) { dma2[ndev] = snd_legacy_find_free_dma(dma2s[dma1[ndev] % 4]); if (dma2[ndev] < 0) { snd_printk(KERN_WARNING "unable to find a free DMA2, full-duplex will not work\n"); dma2[ndev] = -1; } } /* configure WSS IRQ... */ pos = array_find(irqs, irq[ndev]); if (pos < 0) { snd_printk(KERN_ERR "invalid IRQ %d\n", irq[ndev]); return -EINVAL; } val = irq_bits[pos] << 3; /* ...and DMA... */ pos = array_find(dma1s, dma1[ndev]); if (pos < 0) { snd_printk(KERN_ERR "invalid DMA1 %d\n", dma1[ndev]); return -EINVAL; } val |= dma_bits[pos]; /* ...and DMA2 */ if (dma2[ndev] >= 0 && dma1[ndev] != dma2[ndev]) { pos = array_find(dma2s[dma1[ndev]], dma2[ndev]); if (pos < 0) { snd_printk(KERN_ERR "invalid DMA2 %d\n", dma2[ndev]); return -EINVAL; } val |= 0x04; /* enable separate capture DMA */ } outb(val, port); err = snd_card_create(index[ndev], id[ndev], THIS_MODULE, sizeof(struct snd_cmi8328), &card); if (err < 0) return err; cmi = card->private_data; cmi->card = card; cmi->port = port; cmi->wss_cfg = val; snd_card_set_dev(card, pdev); err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev], dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss); if (err < 0) goto error; err = snd_wss_pcm(cmi->wss, 0, NULL); if (err < 0) goto error; err = snd_wss_mixer(cmi->wss); if (err < 0) goto error; err = snd_cmi8328_mixer(cmi->wss); if (err < 0) goto error; if (snd_wss_timer(cmi->wss, 0, NULL) < 0) snd_printk(KERN_WARNING "error initializing WSS timer\n"); if (mpuport[ndev] == SNDRV_AUTO_PORT) { mpuport[ndev] = snd_legacy_find_free_ioport(mpu_ports, 2); if (mpuport[ndev] < 0) snd_printk(KERN_ERR "unable to find a free MPU401 port\n"); } if (mpuirq[ndev] == SNDRV_AUTO_IRQ) { mpuirq[ndev] = snd_legacy_find_free_irq(mpu_irqs); if (mpuirq[ndev] < 0) snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n"); } /* enable and configure MPU401 */ if (mpuport[ndev] > 0 && mpuirq[ndev] > 0) { val = CFG2_MPU_ENABLE; pos = array_find_l(mpu_ports, mpuport[ndev]); if (pos < 0) snd_printk(KERN_WARNING "invalid MPU401 port 0x%lx\n", mpuport[ndev]); else { val |= mpu_port_bits[pos] << 5; pos = array_find(mpu_irqs, mpuirq[ndev]); if (pos < 0) snd_printk(KERN_WARNING "invalid MPU401 IRQ %d\n", mpuirq[ndev]); else { val |= mpu_irq_bits[pos] << 3; snd_cmi8328_cfg_write(port, CFG2, val); if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, mpuport[ndev], 0, mpuirq[ndev], NULL) < 0) snd_printk(KERN_ERR "error initializing MPU401\n"); } } } /* OPL3 is hardwired to 0x388 and cannot be disabled */ if (snd_opl3_create(card, 0x388, 0x38a, OPL3_HW_AUTO, 0, &opl3) < 0) snd_printk(KERN_ERR "error initializing OPL3\n"); else if (snd_opl3_hwdep_new(opl3, 0, 1, NULL) < 0) snd_printk(KERN_WARNING "error initializing OPL3 hwdep\n"); strcpy(card->driver, "CMI8328"); strcpy(card->shortname, "C-Media CMI8328"); sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d,%d", card->shortname, cmi->wss->port, irq[ndev], dma1[ndev], (dma2[ndev] >= 0) ? dma2[ndev] : dma1[ndev]); dev_set_drvdata(pdev, card); err = snd_card_register(card); if (err < 0) goto error; #ifdef SUPPORT_JOYSTICK if (!gameport[ndev]) return 0; /* gameport is hardwired to 0x200 */ res = request_region(0x200, 8, "CMI8328 gameport"); if (!res) snd_printk(KERN_WARNING "unable to allocate gameport I/O port\n"); else { struct gameport *gp = cmi->gameport = gameport_allocate_port(); if (!cmi->gameport) release_and_free_resource(res); else { gameport_set_name(gp, "CMI8328 Gameport"); gameport_set_phys(gp, "%s/gameport0", dev_name(pdev)); gameport_set_dev_parent(gp, pdev); gp->io = 0x200; gameport_set_port_data(gp, res); /* Enable gameport */ snd_cmi8328_cfg_write(port, CFG1, CFG1_SB_DISABLE | CFG1_GAMEPORT); gameport_register_port(gp); } } #endif return 0; error: snd_card_free(card); return err; }
intx snow_arguments_get_index_for_name(SnArguments* args, SnSymbol name) { return array_find(NAMES, symbol_to_value(name)); }
/* get the next command line file open */ static FIN * next_main(int open_flag) /* called by open_main() if on */ { register CELL *cp; CELL *cp0; CELL argc; /* copy of ARGC */ CELL c_argi; /* cell copy of argi */ CELL argval; /* copy of ARGV[c_argi] */ int failed = 1; argval.type = C_NOINIT; c_argi.type = C_DOUBLE; if (main_fin) { FINclose(main_fin); main_fin = 0; } /* FILENAME and FNR don't change unless we really open a new file */ /* make a copy of ARGC to avoid side effect */ if (cellcpy(&argc, ARGC)->type != C_DOUBLE) cast1_to_d(&argc); while (argi < argc.dval) { c_argi.dval = argi; argi += 1.0; if (!(cp0 = array_find(Argv, &c_argi, NO_CREATE))) continue; /* its deleted */ /* make a copy so we can cast w/o side effect */ cell_destroy(&argval); cp = cellcpy(&argval, cp0); #ifndef NO_LEAKS cell_destroy(cp0); #endif if (cp->type < C_STRING) cast1_to_s(cp); if (string(cp)->len == 0) { /* file argument is "" */ cell_destroy(cp); continue; } /* it might be a command line assignment */ if (is_cmdline_assign(string(cp)->str)) { continue; } /* try to open it -- we used to continue on failure, but posix says we should quit */ if (!(main_fin = FINopen(string(cp)->str, 1))) { errmsg(errno, "cannot open %s", string(cp)->str); mawk_exit(2); } /* success -- set FILENAME and FNR */ cell_destroy(FILENAME); cellcpy(FILENAME, cp); cell_destroy(cp); cell_destroy(FNR); FNR->type = C_DOUBLE; FNR->dval = 0.0; rt_fnr = 0; failed = 0; break; } if (failed) { cell_destroy(&argval); if (open_flag) { /* all arguments were null or assignment */ set_main_to_stdin(); } else { main_fin = &dead_main; /* since MAIN_FLAG is not set, FINgets won't call next_main() */ } } return main_fin; }