void c_end_catch(error_context_t * econ) { free_svalue(&catch_value, "F_END_CATCH"); catch_value = const0; /* We come here when no longjmp() was executed */ pop_control_stack(); push_number(0); pop_context(econ); }
/* New version used when not in -o mode. The epilog() in master.c is * supposed to return an array of files (castles in 2.4.5) to load. The array * returned by apply() will be freed at next call of apply(), which means that * the ref count has to be incremented to protect against deallocation. * * The master object is asked to do the actual loading. */ void preload_objects (int eflag) { VOLATILE array_t *prefiles; svalue_t *ret; VOLATILE int ix; error_context_t econ; save_context(&econ); if (SETJMP(econ.context)) { restore_context(&econ); pop_context(&econ); return; } push_number(eflag); ret = apply_master_ob(APPLY_EPILOG, 1); pop_context(&econ); if ((ret == 0) || (ret == (svalue_t *)-1) || (ret->type != T_ARRAY)) return; else prefiles = ret->u.arr; if ((prefiles == 0) || (prefiles->size < 1)) return; debug_message("\nLoading preloaded files ...\n"); prefiles->ref++; ix = 0; /* in case of an error, effectively do a 'continue' */ save_context(&econ); if (SETJMP(econ.context)) { restore_context(&econ); ix++; } for ( ; ix < prefiles->size; ix++) { if (prefiles->item[ix].type != T_STRING) continue; set_eval(max_cost); push_svalue(((array_t *)prefiles)->item + ix); (void) apply_master_ob(APPLY_PRELOAD, 1); } free_array((array_t *)prefiles); pop_context(&econ); } /* preload_objects() */
/* Should NOT be called with cs_error held */ KHMEXP void KHMAPI kherr_pop_context(void) { kherr_context * c; EnterCriticalSection(&cs_error); c = pop_context(); if(IS_KHERR_CTX(c)) { release_context(c); } LeaveCriticalSection(&cs_error); }
void c_caught_error(error_context_t * econ) { restore_context(econ); STACK_INC; *sp = catch_value; catch_value = const1; /* if it's too deep or max eval, we can't let them catch it */ pop_context(econ); if (max_eval_error) error("Can't catch eval cost too big error.\n"); if (too_deep_error) error("Can't catch too deep recursion error.\n"); }
// ----------------------------------------------------------------------------- void hron__finalize (hron__parser_state parser_state) { secret__scanner_state * ss = parser_state; if (!ss) { return; } ss->parser_state.indention = 0; pop_context (ss); ss->parser_state.document__end (ss->parser_state.payload); free(ss); }
void cp_genericize (tree fndecl) { tree t; struct pointer_set_t *p_set; /* Fix up the types of parms passed by invisible reference. */ for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t)) if (TREE_ADDRESSABLE (TREE_TYPE (t))) { /* If a function's arguments are copied to create a thunk, then DECL_BY_REFERENCE will be set -- but the type of the argument will be a pointer type, so we will never get here. */ gcc_assert (!DECL_BY_REFERENCE (t)); gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t)); TREE_TYPE (t) = DECL_ARG_TYPE (t); DECL_BY_REFERENCE (t) = 1; TREE_ADDRESSABLE (t) = 0; relayout_decl (t); } /* Do the same for the return value. */ if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl)))) { t = DECL_RESULT (fndecl); TREE_TYPE (t) = build_reference_type (TREE_TYPE (t)); DECL_BY_REFERENCE (t) = 1; TREE_ADDRESSABLE (t) = 0; relayout_decl (t); } /* If we're a clone, the body is already GIMPLE. */ if (DECL_CLONED_FUNCTION_P (fndecl)) return; /* We do want to see every occurrence of the parms, so we can't just use walk_tree's hash functionality. */ p_set = pointer_set_create (); walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, p_set, NULL); pointer_set_destroy (p_set); /* Do everything else. */ push_context (); c_genericize (fndecl); pop_context (); }
enum thing layer_to_board_object_type(struct world *mzx_world) { int dialog_result; struct element *elements[3]; struct dialog di; int object_type = 0; const char *radio_button_strings[] = { "Custom Block", "Custom Floor", "Text" }; // Prevent previous keys from carrying through. force_release_all_keys(); set_context(CTX_BLOCK_TYPE); elements[0] = construct_radio_button(6, 4, radio_button_strings, 3, 12, &object_type); elements[1] = construct_button(5, 11, "OK", 0); elements[2] = construct_button(15, 11, "Cancel", -1); construct_dialog(&di, "Object type", 26, 4, 28, 14, elements, 3, 0); dialog_result = run_dialog(mzx_world, &di); destruct_dialog(&di); pop_context(); // Prevent UI keys from carrying through. force_release_all_keys(); if(dialog_result) return NO_ID; switch(object_type) { case 0: return CUSTOM_BLOCK; case 1: return CUSTOM_FLOOR; case 2: return __TEXT; } return NO_ID; }
svalue_t * safe_call_function_pointer (funptr_t * funp, int num_arg) { error_context_t econ; svalue_t *ret; if (!save_context(&econ)) return 0; if (!SETJMP(econ.context)) { ret = call_function_pointer(funp, num_arg); } else { restore_context(&econ); /* condition was restored to where it was when we came in */ pop_n_elems(num_arg); ret = 0; } pop_context(&econ); return ret; }
void c_genericize (tree fndecl) { FILE *dump_file; int local_dump_flags; struct cgraph_node *cgn; /* Dump the C-specific tree IR. */ dump_file = dump_begin (TDI_original, &local_dump_flags); if (dump_file) { fprintf (dump_file, "\n;; Function %s", lang_hooks.decl_printable_name (fndecl, 2)); fprintf (dump_file, " (%s)\n", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))); fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original)); fprintf (dump_file, "\n"); if (local_dump_flags & TDF_RAW) dump_node (DECL_SAVED_TREE (fndecl), TDF_SLIM | local_dump_flags, dump_file); else print_c_tree (dump_file, DECL_SAVED_TREE (fndecl)); fprintf (dump_file, "\n"); dump_end (TDI_original, dump_file); } /* Go ahead and gimplify for now. */ push_context (); gimplify_function_tree (fndecl); pop_context (); /* Dump the genericized tree IR. */ dump_function (TDI_generic, fndecl); /* Genericize all nested functions now. We do things in this order so that items like VLA sizes are expanded properly in the context of the correct function. */ cgn = cgraph_node (fndecl); for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) c_genericize (cgn->decl); }
/* * Despite the name, this routine takes care of several things. * It will run once every 15 minutes. * * . It will attempt to reconnect to the address server if the connection has * been lost. * . It will loop through all objects. * * . If an object is found in a state of not having done reset, and the * delay to next reset has passed, then reset() will be done. * * . If the object has a existed more than the time limit given for swapping, * then 'clean_up' will first be called in the object * * There are some problems if the object self-destructs in clean_up, so * special care has to be taken of how the linked list is used. */ static void look_for_objects_to_swap() { static int next_time; #ifndef NO_IP_DEMON extern int no_ip_demon; static int next_server_time; #endif object_t *ob; VOLATILE object_t *next_ob; error_context_t econ; #ifndef NO_IP_DEMON if (current_time >= next_server_time) { /* initialize the address server. if it is already initialized, then * this is a nop. this will cause the driver to reattempt connecting * to the address server once every 15 minutes in the event that it * has gone down. */ if (!no_ip_demon && next_server_time) init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT); next_server_time = current_time + 15 * 60; } #endif if (current_time < next_time) return; /* Not time to look yet */ next_time = current_time + 5 * 60; /* Next time is in 5 minutes */ /* * Objects object can be destructed, which means that next object to * investigate is saved in next_ob. If very unlucky, that object can be * destructed too. In that case, the loop is simply restarted. */ next_ob = obj_list; save_context(&econ); if (SETJMP(econ.context)) restore_context(&econ); while ((ob = (object_t *)next_ob)) { int ready_for_clean_up = 0; if (ob->flags & O_DESTRUCTED) ob = obj_list; /* restart */ next_ob = ob->next_all; /* * Check reference time before reset() is called. */ if (current_time - ob->time_of_ref > time_to_clean_up) ready_for_clean_up = 1; #if !defined(NO_RESETS) && !defined(LAZY_RESETS) /* * Should this object have reset(1) called ? */ if ((ob->flags & O_WILL_RESET) && (ob->next_reset < current_time) && !(ob->flags & O_RESET_STATE)) { debug(d_flag, ("RESET /%s\n", ob->obname)); set_eval(max_cost); reset_object(ob); if(ob->flags & O_DESTRUCTED) continue; } #endif if (time_to_clean_up > 0) { /* * Has enough time passed, to give the object a chance to * self-destruct ? Save the O_RESET_STATE, which will be cleared. * * Only call clean_up in objects that has defined such a function. * * Only if the clean_up returns a non-zero value, will it be called * again. */ if (ready_for_clean_up && (ob->flags & O_WILL_CLEAN_UP)) { int save_reset_state = ob->flags & O_RESET_STATE; svalue_t *svp; debug(d_flag, ("clean up /%s\n", ob->obname)); /* * Supply a flag to the object that says if this program is * inherited by other objects. Cloned objects might as well * believe they are not inherited. Swapped objects will not * have a ref count > 1 (and will have an invalid ob->prog * pointer). * * Note that if it is in the apply_low cache, it will also * get a flag of 1, which may cause the mudlib not to clean * up the object. This isn't bad because: * (1) one expects it is rare for objects that have untouched * long enough to clean_up to still be in the cache, especially * on busy MUDs. * (2) the ones that are are the more heavily used ones, so * keeping them around seems justified. */ push_number(ob->flags & (O_CLONE) ? 0 : ob->prog->ref); set_eval(max_cost); svp = apply(APPLY_CLEAN_UP, ob, 1, ORIGIN_DRIVER); if (ob->flags & O_DESTRUCTED) continue; if (!svp || (svp->type == T_NUMBER && svp->u.number == 0)) ob->flags &= ~O_WILL_CLEAN_UP; ob->flags |= save_reset_state; } } } pop_context(&econ); } /* look_for_objects_to_swap() */
/* * DO statement * Handles DO;, DO CASE, DO WHILE, and iterative DO */ void parse_do(TOKEN *first_token) { TOKEN token; int token_class; int case_line; char case_statement[MAX_TOKEN_LENGTH]; char case_output[MAX_CASE_STATEMENT_SIZE]; char var_string[MAX_TOKEN_LENGTH]; char *temp_out_string, *temp_out_string1; DECL_MEMBER *var_decl; DECL_ID *var_decl_id; /* Create new context */ new_context(DO, (TOKEN *) NULL); out_white_space(first_token); /* Determine what kind of DO statement */ token_class = get_token(&token); switch (token_class) { case END_OF_LINE : /* DO; */ out_white_space(&token); out_char('{'); /* } for dumb vi */ parse_to_end(); break; case IDENTIFIER : /* DO counter = start TO limit BY step */ out_str("for"); out_must_white(&token); out_char('('); /* Put full variable in var_string */ var_string[0] = '\0'; temp_out_string = out_string; out_string = var_string; token_class = parse_variable(&token, &var_decl, &var_decl_id); out_string = temp_out_string; /* Check for '=' */ if ((token_class != OPERATOR) || (token.token_type != EQUAL)) { parse_error("Missing '='"); pop_context(); return; } /* Send <ident> '=' <expr> */ out_str(var_string); out_token(&token); token_class = parse_expression(&token); if ((token_class != RESERVED) || (token.token_type != TO)) { parse_error("Missing TO"); pop_context(); return; } /* Send <ident> <= <limit> */ out_str("; "); out_str(var_string); out_str(" <="); token_class = parse_expression(&token); out_str("; "); /* Parse increment */ if ((token_class == RESERVED) && (token.token_type == BY)) { /* Send <ident> += <step> */ out_str(var_string); out_str(" +="); token_class = parse_expression(&token); } else { /* Send <ident>++ */ out_str(var_string); out_str("++"); } out_str(") {"); /* } for dumb vi */ out_white_space(&token); if (token_class != END_OF_LINE) { parse_error("BY or ';' expected"); pop_context(); return; } parse_to_end(); break; case RESERVED : switch (token.token_type) { case CASE : /* DO CASE <expr>; */ out_str("switch ("); if (parse_expression(&token) != END_OF_LINE) { parse_error("';' expected"); pop_context(); return; } out_white_space(&token); out_str(") {"); /* } for dumb vi */ case_line = 0; while (1) { /* Place case statement in out_string */ temp_out_string1 = out_string; case_output[0] = '\0'; out_string = case_output; (void) snprintf(case_statement, sizeof(case_statement), "case %d :", case_line++); token_class = parse_new_statement(); if (token_class == END_OF_FILE) { parse_error("Premature end-of-file"); exit(1); } if (token_class == END) { out_string = temp_out_string1; out_str(case_output); break; } out_string = temp_out_string1; out_white_space(first_token); out_str(case_statement); out_str(case_output); out_white_space(first_token); out_str("break;\n"); } break; case WHILE : /* DO WHILE <expr>; */ out_str("while ("); if (parse_expression(&token) != END_OF_LINE) { parse_error("';' expected"); pop_context(); return; } out_white_space(&token); out_str(") {"); /* } for dumb vi */ parse_to_end(); break; default: parse_error("Illegal DO clause"); pop_context(); return; } break; } /* End of context */ pop_context(); }
/* * Parse statement starting with an identifier. * Possibilities include: * Assignment * Procedure statement */ void parse_identifier(TOKEN *first_token) { TOKEN token, next_token; TOKEN param_token, attrib_token, type_token; int token_class, next_token_class; DECL *decl_list, *extra_decl_list; PARAM_LIST *param_list, *param_ptr; DECL_MEMBER *decl_ptr; DECL_ID *decl_id; BOOLEAN extern_proc, got_type, interrupt_proc; char *tmp_text_ptr; /* Check for label or procedure */ tmp_text_ptr = text_ptr; token_class = get_token(&token); if (token_class == LABEL) { /* Determine if label or procedure definition */ next_token_class = get_token(&next_token); if ((next_token_class == RESERVED) && (next_token.token_type == PROCEDURE)) { /* * Procedure - Check for parameter list */ param_list = NULL; token_class = get_token(¶m_token); if (token_class == LEFT_PAREN) { /* Yes - get parameter list */ get_param_list(¶m_list); /* Get token after parameter list */ token_class = get_token(&attrib_token); } else /* No param list - save as attribute */ token_copy(¶m_token, &attrib_token); out_white_space(first_token); extern_proc = FALSE; interrupt_proc = FALSE; got_type = (token_class == RESERVED) && (attrib_token.token_type >= BYTE) && (attrib_token.token_type <= SELECTOR); if (got_type) { /* * Process [ <type> ] */ token_copy(&attrib_token, &type_token); token_class = get_token(&attrib_token); } while (token_class == RESERVED) { if (attrib_token.token_type == INTERRUPT) { /* * Process [ <interrupt> ] */ interrupt_proc = TRUE; token_class = get_token(&attrib_token); if (token_class == NUMERIC) /* Interrupt number */ token_class = get_token(&attrib_token); } else /* * Process [ EXTERNAL | { [ PUBLIC ] [ REENTRANT ] } ] */ if (attrib_token.token_type == EXTERNAL) { out_str("extern"); out_must_white(&attrib_token); extern_proc = TRUE; token_class = get_token(&attrib_token); } else if ((attrib_token.token_type == PUBLIC) || (attrib_token.token_type == REENTRANT)) { do { if (attrib_token.token_type == PUBLIC) { /* Ignore for now */ token_class = get_token(&attrib_token); } else if (attrib_token.token_type == REENTRANT) { /* Ignore for now */ token_class = get_token(&attrib_token); } else break; } while (token_class == RESERVED); } else break; } if (token_class != END_OF_LINE) { parse_error("';' expected"); return; } if (interrupt_proc && !extern_proc) parse_warning("INTERRUPT procedure declared"); /* Create declaration for procedure */ get_element_ptr(&decl_ptr); get_var_ptr(&decl_ptr->name_list); /* Type = PROCEDURE */ get_token_ptr(&decl_ptr->type); token_copy(&next_token, decl_ptr->type); /* Name = procedure name */ get_token_ptr(&decl_ptr->name_list->name); token_copy(first_token, decl_ptr->name_list->name); /* Flag if parameter list */ if (param_list) decl_ptr->initialization = DATA; /* Add it to context */ add_to_context(decl_ptr); if (got_type) { /* Output procedure type */ out_token_name(&type_token); out_must_white(&type_token); } /* Output procedure name */ out_token_name(first_token); if (extern_proc) { out_str("()"); if (param_list) /* Parse parameter declarations */ parse_param_list(param_list, &decl_list, &extra_decl_list); out_char(';'); /* Eat closing 'END [<proc name>];' */ token_class = get_token(&token); if ((token_class != RESERVED) || (token.token_type != END)) { parse_error("END expected"); return; } out_white_space(&token); token_class = get_token(&token); if (token_class == IDENTIFIER) { token_class = get_token(&token); } if (token_class != END_OF_LINE) { parse_error("';' expected"); } return; } else if (param_list) { out_token(¶m_token); /* Output parameter list */ param_ptr = param_list; while (param_ptr) { out_token(¶m_ptr->param); param_ptr = param_ptr->next_param; if (param_ptr) out_char(','); } out_char(')'); /* Parse parameter declarations */ parse_param_list(param_list, &decl_list, &extra_decl_list); /* Output declarations */ if (decl_list) { out_decl(decl_list); /* Add declarations to context */ add_decl_to_context(decl_list); } out_str("\n{"); /* } for dumb vi */ if (extra_decl_list) { out_decl(extra_decl_list); /* Add declarations to context */ add_decl_to_context(extra_decl_list); } /* Discard declarations */ free_decl(decl_list); free_decl(extra_decl_list); } else /* No parameter list */ out_str("()\n{"); /* } for dumb vi */ /* Create new context */ new_context(PROCEDURE, first_token); /* Parse statements to END */ parse_to_end(); /* Pop procedure context */ pop_context(); } else { /* * Label - add label name */ out_token(first_token); /* Add colon */ out_token(&token); /* Is this a defined label or a module? */ if (find_symbol(first_token, &decl_ptr, &decl_id)) { if (decl_ptr->type->token_class == LABEL) { /* Label - new context */ new_context(MODULE, first_token); parse_statement(&next_token); pop_context(); } else { parse_error("Illegal label name"); return; } } else parse_statement(&next_token); } return; } /* Assignment statement */ text_ptr = tmp_text_ptr; token_copy(first_token, &token); token_class = parse_variable(&token, &decl_ptr, &decl_id); /* Check for multiple assignments */ while (token_class == COMMA) { /* Print ' =' instead of ',' */ out_str(" ="); out_white_space(&token); /* Get identifier part of next assignment variable */ token_class = get_token(&token); if (token_class != IDENTIFIER) { parse_error("Illegal assignment"); return; } /* Parse remainder of variable (if any) */ token_class = parse_variable(&token, &decl_ptr, &decl_id); } if (token_class == OPERATOR) { if (token.token_type != EQUAL) { parse_error("Illegal use of identifier"); return; } out_token(&token); /* Check for POINTER assignment */ if (decl_ptr->type->token_type == POINTER) { /* Yes - cast it */ out_str(" ("); out_str(TYPE_POINTER); out_str(" *) "); } if (parse_expression(&token) != END_OF_LINE) parse_error("';' expected"); else out_token(&token); return; } else if (token_class != LABEL) { parse_error("Illegal use of identifier"); return; } }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LEXICAL SCANNER */ LOCAL te_dp_event yylex(void) { lastToken = DP_EV_INVALID; scanAgain: /* * Start the process of locating a token. * We branch here after skipping over a comment * or processing a directive (which may change our context). */ if (IS_WHITESPACE_CHAR(*pCurCtx->pzScan)) trim_whitespace(); switch (*pCurCtx->pzScan) { case NUL: /* * IF we are not inside an include context, * THEN go finish. */ if (pCurCtx->pCtx == NULL) goto lex_done; pop_context(); goto scanAgain; case '#': { extern char * processDirective(char*); char * pz = processDirective(pCurCtx->pzScan+1); /* * Ensure that the compiler doesn't try to save a copy of * "pCurCtx" in a register. It must be reloaded from memory. */ pCurCtx->pzScan = pz; goto scanAgain; } case '{': SET_LIT_TKN(O_BRACE); break; case '=': SET_LIT_TKN(EQ); break; case '}': SET_LIT_TKN(C_BRACE); break; case '[': SET_LIT_TKN(OPEN_BKT); break; case ']': SET_LIT_TKN(CLOSE_BKT); break; case ';': SET_LIT_TKN(SEMI); break; case ',': SET_LIT_TKN(COMMA); break; case '\'': case '"': { char* pz = ao_string_cook(pCurCtx->pzScan, &(pCurCtx->lineNo)); if (pz == NULL) goto NUL_error; pz_token = pCurCtx->pzScan; lastToken = DP_EV_STRING; pCurCtx->pzScan = pz; break; } case '<': switch (lex_here_string()) { case SUCCESS: break; case FAILURE: goto BrokenToken; case PROBLEM: return DP_EV_INVALID; } break; case '(': loadScheme(); break; case '\\': if (strncmp(pCurCtx->pzScan+1, "'(", (size_t)2) == 0) { alist_to_autogen_def(); goto scanAgain; } lex_escaped_char(); break; case '`': switch (lex_backquote()) { case FAILURE: goto NUL_error; case PROBLEM: goto scanAgain; case SUCCESS: break; } break; case '/': switch (lex_comment()) { case SUCCESS: goto scanAgain; default: break; } /* FALLTHROUGH */ /* to Invalid input char */ default: BrokenToken: pCurCtx->pzScan = assembleName(pCurCtx->pzScan, &lastToken); break; } /* switch (*pCurCtx->pzScan) */ return lastToken; NUL_error: AG_ABEND(aprf(zErrMsg, pzProg, "unterminated quote in definition", pCurCtx->pzCtxFname, pCurCtx->lineNo)); return DP_EV_INVALID; lex_done: /* * First time through, return the DP_EV_END token. * Second time through, we really finish. */ if (pCurCtx->pzScan == zNil) { pCurCtx->pCtx = pDoneCtx; pDoneCtx = pCurCtx; return DP_EV_INVALID; } pCurCtx->pzScan = (char*)zNil; return DP_EV_END; }
void call_heart_beat() { object_t *ob; heart_beat_t *curr_hb; error_context_t econ; current_interactive = 0; if ((num_hb_to_do = num_hb_objs)) { num_hb_calls++; heart_beat_index = 0; save_context(&econ); while (1) { ob = (curr_hb = &heart_beats[heart_beat_index])->ob; DEBUG_CHECK(!(ob->flags & O_HEART_BEAT), "Heartbeat not set in object on heartbeat list!"); /* is it time to do a heart beat ? */ curr_hb->heart_beat_ticks--; if (ob->prog->heart_beat != 0) { if (curr_hb->heart_beat_ticks < 1) { object_t *new_command_giver; curr_hb->heart_beat_ticks = curr_hb->time_to_heart_beat; current_heart_beat = ob; new_command_giver = ob; #ifndef NO_SHADOWS while (new_command_giver->shadowing) new_command_giver = new_command_giver->shadowing; #endif #ifndef NO_ADD_ACTION if (!(new_command_giver->flags & O_ENABLE_COMMANDS)) new_command_giver = 0; #endif #ifdef PACKAGE_MUDLIB_STATS add_heart_beats(&ob->stats, 1); #endif set_eval(max_cost); if (SETJMP(econ.context)) { restore_context(&econ); } else { save_command_giver(new_command_giver); call_direct(ob, ob->prog->heart_beat - 1, ORIGIN_DRIVER, 0); pop_stack(); /* pop the return value */ restore_command_giver(); } current_object = 0; } } if (++heart_beat_index == num_hb_to_do) break; } pop_context(&econ); if (heart_beat_index < num_hb_to_do) perc_hb_probes = 100 * (float) heart_beat_index / num_hb_to_do; else perc_hb_probes = 100.0; heart_beat_index = num_hb_to_do = 0; } current_prog = 0; current_heart_beat = 0; look_for_objects_to_swap(); #ifdef PACKAGE_MUDLIB_STATS mudlib_stats_decay(); #endif } /* call_heart_beat() */
/* Called from 'big_loop' in parser.c. Return 1 if we find menu syntax to process, otherwise return 0. */ int handle_menu (ELEMENT **current_inout, char **line_inout) { ELEMENT *current = *current_inout; char *line = *line_inout; int retval = 1; // 4052 /* A "*" at the start of a line beginning a menu entry. */ if (*line == '*' && current->type == ET_preformatted && (current->parent->type == ET_menu_comment || current->parent->type == ET_menu_entry_description) && current->contents.number > 0 && last_contents_child(current)->type == ET_empty_line) { ELEMENT *star; debug ("MENU STAR"); abort_empty_line (¤t, 0); line++; /* Past the '*'. */ star = new_element (ET_menu_star); text_append (&star->text, "*"); add_to_element_contents (current, star); /* The ET_menu_star element won't appear in the final tree. */ } // 4067 /* A space after a "*" at the beginning of a line. */ else if (strchr (whitespace_chars, *line) && current->contents.number > 0 && last_contents_child(current)->type == ET_menu_star) { ELEMENT *menu_entry, *leading_text, *entry_name; int leading_spaces; debug ("MENU ENTRY (certainly)"); leading_spaces = strspn (line, whitespace_chars); destroy_element (pop_element_from_contents (current)); if (current->type == ET_preformatted && current->parent->type == ET_menu_comment) { ELEMENT *menu = current->parent->parent; /* Remove an empty ET_preformatted, and an empty ET_menu_comment. */ if (current->contents.number == 0) { pop_element_from_contents (current->parent); if (current->parent->contents.number == 0) { pop_element_from_contents (menu); destroy_element (current->parent); } destroy_element (current); } current = menu; } else { /* current should be ET_preformatted, 1st parent ET_menu_entry_description, 2nd parent ET_menu_entry, 3rd parent @menu. */ current = current->parent->parent->parent; } if (pop_context () != ct_preformatted) abort (); // bug menu_entry = new_element (ET_menu_entry); leading_text = new_element (ET_menu_entry_leading_text); entry_name = new_element (ET_menu_entry_name); add_to_element_contents (current, menu_entry); add_to_element_args (menu_entry, leading_text); add_to_element_args (menu_entry, entry_name); current = entry_name; text_append (&leading_text->text, "*"); text_append_n (&leading_text->text, line, leading_spaces); line += leading_spaces; } // 4116 /* A "*" followed by anything other than a space. */ else if (current->contents.number > 0 && last_contents_child(current)->type == ET_menu_star) { debug ("ABORT MENU STAR"); destroy_element (pop_element_from_contents (current)); } // 4122 /* After a separator in a menu. */ else if (current->args.number > 0 && last_args_child (current)->type == ET_menu_entry_separator) { ELEMENT *last_child; char *separator; last_child = last_args_child (current); separator = last_child->text.text; /* Separator is "::". */ if (!strcmp (separator, ":") && *line == ':') { text_append (&last_child->text, ":"); line++; /* Whitespace following the "::" is subsequently appended to the separator element. */ } /* A "." not followed by a space. Not a separator. */ else if (!strcmp (separator, ".") && !strchr (whitespace_chars, *line)) { pop_element_from_args (current); current = last_args_child (current); merge_text (current, last_child->text.text); destroy_element (last_child); } else if (strchr (whitespace_chars_except_newline, *line)) { int n; n = strspn (line, whitespace_chars_except_newline); text_append_n (&last_child->text, line, n); line += n; } else if (!strncmp (separator, "::", 2)) { ELEMENT *entry_name; debug ("MENU NODE no entry %s", separator); entry_name = args_child_by_index (current, -2); /* Change it from ET_menu_entry_name (i.e. the label). */ entry_name->type = ET_menu_entry_node; current = enter_menu_entry_node (current); } /* End of the label. Begin the element for the destination. */ else if (*separator == ':') { ELEMENT *entry_node; debug ("MENU ENTRY %s", separator); entry_node = new_element (ET_menu_entry_node); add_to_element_args (current, entry_node); current = entry_node; } else { debug ("MENU NODE"); current = enter_menu_entry_node (current); } } else retval = 0; *current_inout = current; *line_inout = line; return retval; }
int main (int argc, char ** argv) { time_t tm; int i, new_mudlib = 0, got_defaults = 0; char *p; char version_buf[80]; #if 0 int dtablesize; #endif error_context_t econ; #ifdef PROTO_TZSET void tzset(); #endif #ifdef INCL_LOCALE_H setlocale(LC_ALL, "C"); #endif #if !defined(__SASC) && (defined(AMITCP) || defined(AS225)) amiga_sockinit(); atexit(amiga_sockexit); #endif #ifdef WRAPPEDMALLOC wrappedmalloc_init(); #endif /* WRAPPEDMALLOC */ #ifdef DEBUGMALLOC MDinit(); #endif #if (defined(PROFILING) && !defined(PROFILE_ON) && defined(HAS_MONCONTROL)) moncontrol(0); #endif #ifdef USE_TZSET tzset(); #endif boot_time = get_current_time(); const0.type = T_NUMBER; const0.u.number = 0; const1.type = T_NUMBER; const1.u.number = 1; /* const0u used by undefinedp() */ const0u.type = T_NUMBER; const0u.subtype = T_UNDEFINED; const0u.u.number = 0; //fake_prog.program_size = 0; //0 anyway /* * Check that the definition of EXTRACT_UCHAR() is correct. */ p = (char *) &i; *p = -10; if (EXTRACT_UCHAR(p) != 0x100 - 10) { fprintf(stderr, "Bad definition of EXTRACT_UCHAR() in interpret.h.\n"); exit(-1); } /* * An added test: can we do EXTRACT_UCHAR(x++)? * (read_number, etc uses it) */ p = (char *) &i; (void) EXTRACT_UCHAR(p++); if ((p - (char *) &i) != 1) { fprintf(stderr, "EXTRACT_UCHAR() in interpret.h evaluates its argument more than once.\n"); exit(-1); } /* * Check the living hash table size */ if (CFG_LIVING_HASH_SIZE != 4 && CFG_LIVING_HASH_SIZE != 16 && CFG_LIVING_HASH_SIZE != 64 && CFG_LIVING_HASH_SIZE != 256 && CFG_LIVING_HASH_SIZE != 1024 && CFG_LIVING_HASH_SIZE != 4096) { fprintf(stderr, "CFG_LIVING_HASH_SIZE in options.h must be one of 4, 16, 64, 256, 1024, 4096, ...\n"); exit(-1); } #ifdef RAND srand(get_current_time()); #else # ifdef DRAND48 srand48(get_current_time()); # else # ifdef RANDOM srandom(get_current_time()); # else fprintf(stderr, "Warning: no random number generator specified!\n"); # endif # endif #endif current_time = get_current_time(); /* * Initialize the microsecond clock. */ init_usec_clock(); /* read in the configuration file */ got_defaults = 0; for (i = 1; (i < argc) && !got_defaults; i++) { if (argv[i][0] != '-') { set_defaults(argv[i]); got_defaults = 1; } } get_version(version_buf); if (!got_defaults) { fprintf(stderr, "%s for %s.\n", version_buf, ARCH); fprintf(stderr, "You must specify the configuration filename as an argument.\n"); exit(-1); } printf("Initializing internal tables....\n"); init_strings(); /* in stralloc.c */ init_otable(); /* in otable.c */ init_identifiers(); /* in lex.c */ init_locals(); /* in compiler.c */ /* * If our estimate is larger than FD_SETSIZE, then we need more file * descriptors than the operating system can handle. This is a problem * that can be resolved by decreasing MAX_USERS, MAX_EFUN_SOCKS, or both. * * Unfortunately, since neither MAX_USERS or MAX_EFUN_SOCKS exist any more, * we have no clue how many we will need. This code really should be * moved to places where ENFILE/EMFILE is returned. */ #if 0 if (dtablesize > FD_SETSIZE) { fprintf(stderr, "Warning: File descriptor requirements exceed system capacity!\n"); fprintf(stderr, " Configuration exceeds system capacity by %d descriptor(s).\n", dtablesize - FD_SETSIZE); } #ifdef HAS_SETDTABLESIZE /* * If the operating system supports setdtablesize() then we can request * the number of file descriptors we really need. First check to see if * wee already have enough. If so dont bother the OS. If not, attempt to * allocate the number we estimated above. There are system imposed * limits on file descriptors, so we may not get as many as we asked for. * Check to make sure we get enough. */ if (getdtablesize() < dtablesize) if (setdtablesize(dtablesize) < dtablesize) { fprintf(stderr, "Warning: Could not allocate enough file descriptors!\n"); fprintf(stderr, " setdtablesize() could not allocate %d descriptor(s).\n", getdtablesize() - dtablesize); } /* * Just be polite and tell the administrator how many he has. */ fprintf(stderr, "%d file descriptors were allocated, (%d were requested).\n", getdtablesize(), dtablesize); #endif #endif time_to_clean_up = TIME_TO_CLEAN_UP; max_cost = MAX_COST; reserved_size = RESERVED_SIZE; max_array_size = MAX_ARRAY_SIZE; if(max_array_size > 65535){ fprintf(stderr, "Maximum array size can not exceed 65535"); max_array_size = 65535; } max_buffer_size = MAX_BUFFER_SIZE; max_string_length = MAX_STRING_LENGTH; mud_lib = (char *) MUD_LIB; set_inc_list(INCLUDE_DIRS); if (reserved_size > 0) reserved_area = (char *) DMALLOC(reserved_size, TAG_RESERVED, "main.c: reserved_area"); for (i = 0; i < sizeof consts / sizeof consts[0]; i++) consts[i] = exp(-i / 900.0); reset_machine(1); /* * The flags are parsed twice ! The first time, we only search for the -m * flag, which specifies another mudlib, and the D-flags, so that they * will be available when compiling master.c. */ for (i = 1; i < argc; i++) { if (argv[i][0] != '-') continue; switch (argv[i][1]) { case 'D': if (argv[i][2]) { lpc_predef_t *tmp = ALLOCATE(lpc_predef_t, TAG_PREDEFINES, "predef"); tmp->flag = argv[i] + 2; tmp->next = lpc_predefs; lpc_predefs = tmp; continue; } fprintf(stderr, "Illegal flag syntax: %s\n", argv[i]); exit(-1); case 'N': no_ip_demon++; continue; #ifdef HAS_CONSOLE case 'C': has_console = 1; continue; #endif #ifdef YYDEBUG case 'y': yydebug = 1; continue; #endif /* YYDEBUG */ case 'm': mud_lib = alloc_cstring(argv[i] + 2, "mudlib dir"); if (chdir(mud_lib) == -1) { fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib); exit(-1); } new_mudlib = 1; break; } } if (!new_mudlib && chdir(mud_lib) == -1) { fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib); exit(-1); } time(&tm); debug_message("----------------------------------------------------------------------------\n%s (%s) starting up on %s - %s\n\n", MUD_NAME, version_buf, ARCH, ctime(&tm)); add_predefines(); #ifdef WIN32 _tzset(); #endif #ifndef NO_IP_DEMON if (!no_ip_demon && ADDR_SERVER_IP) init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT); #endif /* NO_IP_DEMON */ set_eval(max_cost); save_context(&econ); if (SETJMP(econ.context)) { debug_message("The simul_efun (%s) and master (%s) objects must be loadable.\n", SIMUL_EFUN, MASTER_FILE); exit(-1); } else { init_simul_efun(SIMUL_EFUN); init_master(); } pop_context(&econ); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { continue; } else { /* * Look at flags. -m and -o has already been tested. */ switch (argv[i][1]) { case 'D': case 'N': case 'm': case 'y': case 'C': continue; case 'f': save_context(&econ); if (SETJMP(econ.context)) { debug_message("Error while calling master::flag(\"%s\"), aborting ...\n", argv[i] + 2); exit(-1); } push_constant_string(argv[i] + 2); apply_master_ob(APPLY_FLAG, 1); if (MudOS_is_being_shut_down) { debug_message("Shutdown by master object.\n"); exit(0); } pop_context(&econ); continue; case 'e': e_flag++; continue; case 'p': external_port[0].port = atoi(argv[i] + 2); continue; case 'd': #ifdef DEBUG_MACRO if (argv[i][2]) debug_level_set(&argv[i][2]); else debug_level |= DBG_d_flag; #else debug_message("Driver must be compiled with DEBUG_MACRO on to use -d.\n"); #endif break; case 'c': comp_flag++; continue; case 't': t_flag++; continue; default: debug_message("Unknown flag: %s\n", argv[i]); exit(-1); } } } if (MudOS_is_being_shut_down) exit(1); if (*(DEFAULT_FAIL_MESSAGE)) { char buf[8192]; strcpy(buf, DEFAULT_FAIL_MESSAGE); strcat(buf, "\n"); default_fail_message = make_shared_string(buf); } else default_fail_message = "What?\n"; #ifdef PACKAGE_MUDLIB_STATS restore_stat_files(); #endif preload_objects(e_flag); #ifdef SIGFPE signal(SIGFPE, sig_fpe); #endif #ifdef TRAP_CRASHES #ifdef SIGUSR1 signal(SIGUSR1, sig_usr1); #endif #ifdef SIGUSR2 signal(SIGUSR2, sig_usr2); #endif signal(SIGTERM, sig_term); signal(SIGINT, sig_int); #ifndef DEBUG #if defined(SIGABRT) signal(SIGABRT, sig_abrt); #endif #ifdef SIGIOT signal(SIGIOT, sig_iot); #endif #ifdef SIGHUP signal(SIGHUP, sig_hup); #endif #ifdef SIGBUS signal(SIGBUS, sig_bus); #endif signal(SIGSEGV, sig_segv); signal(SIGILL, sig_ill); #endif /* DEBUG */ #endif #ifndef WIN32 #ifdef USE_BSD_SIGNALS signal(SIGCHLD, sig_cld); #else signal(SIGCLD, sig_cld); #endif #endif #ifdef HAS_CONSOLE if(has_console >= 0) signal(SIGTTIN, sig_ttin); signal(SIGTTOU, SIG_IGN); #endif backend(); return 0; }
//string pcre_replace_callback(string, string, function) void f_pcre_replace_callback(void) { int num_arg = st_num_arg, i; char *ret; pcre_t *run; svalue_t *arg; array_t *arr, *r; function_to_call_t ftc; arg = sp - num_arg + 1; run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_replace: run"); run->ovector = NULL; run->ovecsize = 0; run->subject = arg->u.string; assign_svalue_no_free(&run->pattern, (arg + 1)); run->s_length = SVALUE_STRLEN(arg); if(pcre_magic(run) < 0) { pcre_free_memory(run); error("PCRE compilation failed at offset %d: %s\n", run->erroffset, run->error); } if (run->rc < 0) /* No match. could do handling of matching errors if wanted */ { pop_n_elems(num_arg-1); pcre_free_memory(run); return; } if (run->rc > (run->ovecsize/3-1)) { pcre_free_memory(run); error("Too many substrings.\n"); } arr = pcre_get_substrings(run); if(arg[2].type == T_FUNCTION || arg[2].type == T_STRING) process_efun_callback(2, &ftc, F_PCRE_REPLACE_CALLBACK); else {// 0 pcre_free_memory(run); error("Illegal third argument (0) to pcre_replace_callback"); } r = allocate_array(run->rc - 1); //can't use the empty variant in case we error below push_refed_array(r); push_refed_array(arr); error_context_t econ; if (!save_context(&econ)){ pcre_free_memory(run); error("context stack full!\n"); } if (SETJMP(econ.context)) { restore_context(&econ); /* condition was restored to where it was when we came in */ pcre_free_memory(run); pop_context(&econ); error("error in callback!\n"); } for (i = 0; i < run->rc - 1; i++) { svalue_t *v; push_svalue(arr->item + i); push_number(i); v = call_efun_callback(&ftc, 2); /* Mimic behaviour of map(string, function) when function pointer returns null, ie return the input. */ if (v && v->type == T_STRING && v->u.string != NULL) assign_svalue_no_free(&r->item[i], v); else assign_svalue_no_free(&r->item[i], &arr->item[i]); } pop_context(&econ); ret = pcre_get_replace(run, r); pop_n_elems(num_arg+2); //refed arrays push_malloced_string(ret); pcre_free_memory(run); return; }
int main P2(int, argc, char **, argv) { time_t tm; int i, new_mudlib = 0, got_defaults = 0; int no_ip_demon = 0; char *p; char version_buf[80]; #if 0 int dtablesize; #endif error_context_t econ; #if !defined(LATTICE) && !defined(OLD_ULTRIX) && !defined(sequent) && \ !defined(sgi) void tzset(); #endif struct lpc_predef_s predefs; #if !defined(__SASC) && (defined(AMITCP) || defined(AS225)) amiga_sockinit(); atexit(amiga_sockexit); #endif #ifdef WRAPPEDMALLOC wrappedmalloc_init(); #endif /* WRAPPEDMALLOC */ #ifdef DEBUGMALLOC MDinit(); #endif #if (defined(PROFILING) && !defined(PROFILE_ON) && defined(HAS_MONCONTROL)) moncontrol(0); #endif #if !defined(OLD_ULTRIX) && !defined(LATTICE) && !defined(sequent) tzset(); #endif boot_time = get_current_time(); const0.type = T_NUMBER; const0.u.number = 0; const1.type = T_NUMBER; const1.u.number = 1; /* const0u used by undefinedp() */ const0u.type = T_NUMBER; const0u.subtype = T_UNDEFINED; const0u.u.number = 0; /* const0n used by nullp() */ const0n.type = T_NUMBER; const0n.subtype = T_NULLVALUE; const0n.u.number = 0; fake_prog.program_size = 0; /* * Check that the definition of EXTRACT_UCHAR() is correct. */ p = (char *) &i; *p = -10; if (EXTRACT_UCHAR(p) != 0x100 - 10) { fprintf(stderr, "Bad definition of EXTRACT_UCHAR() in interpret.h.\n"); exit(-1); } /* * An added test: can we do EXTRACT_UCHAR(x++)? * (read_number, etc uses it) */ p = (char *) &i; (void) EXTRACT_UCHAR(p++); if ((p - (char *) &i) != 1) { fprintf(stderr, "EXTRACT_UCHAR() in interpret.h evaluates its argument more than once.\n"); exit(-1); } /* * Check the living hash table size */ if (CFG_LIVING_HASH_SIZE != 4 && CFG_LIVING_HASH_SIZE != 16 && CFG_LIVING_HASH_SIZE != 64 && CFG_LIVING_HASH_SIZE != 256 && CFG_LIVING_HASH_SIZE != 1024 && CFG_LIVING_HASH_SIZE != 4096) { fprintf(stderr, "CFG_LIVING_HASH_SIZE in options.h must be one of 4, 16, 64, 256, 1024, 4096, ...\n"); exit(-1); } #ifdef RAND srand(get_current_time()); #else # ifdef DRAND48 srand48(get_current_time()); # else # ifdef RANDOM srandom(get_current_time()); # else fprintf(stderr, "Warning: no random number generator specified!\n"); # endif # endif #endif current_time = get_current_time(); /* * Initialize the microsecond clock. */ init_usec_clock(); /* read in the configuration file */ got_defaults = 0; for (i = 1; (i < argc) && !got_defaults; i++) { if (argv[i][0] != '-') { set_defaults(argv[i]); got_defaults = 1; } } if (!got_defaults) { fprintf(stderr, "You must specify the configuration filename as an argument.\n"); exit(-1); } printf("Initializing internal tables....\n"); init_strings(); /* in stralloc.c */ init_otable(); /* in otable.c */ init_identifiers(); /* in lex.c */ init_locals(); /* in compiler.c */ /* disable this for now */ #if 0 /* * We estimate that we will need MAX_USERS + MAX_EFUN_SOCKS + 10 file * descriptors if the maximum number of users were to log in and all LPC * sockets were in use. This is a pretty close estimate. */ #ifndef LATTICE dtablesize = MAX_USERS + MAX_EFUN_SOCKS + 10; #else /* * Amiga sockets separate from file descriptors */ dtablesize = MAX_USERS + MAX_EFUN_SOCKS; #endif /* * If our estimate is larger than FD_SETSIZE, then we need more file * descriptors than the operating system can handle. This is a problem * that can be resolved by decreasing MAX_USERS, MAX_EFUN_SOCKS, or both. */ if (dtablesize > FD_SETSIZE) { fprintf(stderr, "Warning: File descriptor requirements exceed system capacity!\n"); fprintf(stderr, " Configuration exceeds system capacity by %d descriptor(s).\n", dtablesize - FD_SETSIZE); } #ifdef HAS_SETDTABLESIZE /* * If the operating system supports setdtablesize() then we can request * the number of file descriptors we really need. First check to see if * wee already have enough. If so dont bother the OS. If not, attempt to * allocate the number we estimated above. There are system imposed * limits on file descriptors, so we may not get as many as we asked for. * Check to make sure we get enough. */ if (getdtablesize() < dtablesize) if (setdtablesize(dtablesize) < dtablesize) { fprintf(stderr, "Warning: Could not allocate enough file descriptors!\n"); fprintf(stderr, " setdtablesize() could not allocate %d descriptor(s).\n", getdtablesize() - dtablesize); } /* * Just be polite and tell the administrator how many he has. */ fprintf(stderr, "%d file descriptors were allocated, (%d were requested).\n", getdtablesize(), dtablesize); #endif #endif time_to_clean_up = TIME_TO_CLEAN_UP; time_to_swap = TIME_TO_SWAP; max_cost = MAX_COST; reserved_size = RESERVED_SIZE; max_array_size = MAX_ARRAY_SIZE; max_buffer_size = MAX_BUFFER_SIZE; max_string_length = MAX_STRING_LENGTH; master_file_name = (char *) MASTER_FILE; /* fix the filename */ while (*master_file_name == '/') master_file_name++; p = master_file_name; while (*p++); if (p[-2]=='c' && p[-3]=='.') p[-3]=0; mud_lib = (char *) MUD_LIB; set_inc_list(INCLUDE_DIRS); if (reserved_size > 0) reserved_area = (char *) DMALLOC(reserved_size, TAG_RESERVED, "main.c: reserved_area"); for (i = 0; i < sizeof consts / sizeof consts[0]; i++) consts[i] = exp(-i / 900.0); init_num_args(); reset_machine(1); /* * The flags are parsed twice ! The first time, we only search for the -m * flag, which specifies another mudlib, and the D-flags, so that they * will be available when compiling master.c. */ for (i = 1; i < argc; i++) { if (argv[i][0] != '-') continue; switch (argv[i][1]) { case 'D': if (argv[i][2]) { /* Amylaar : allow flags to be passed down to * the LPC preprocessor */ struct lpc_predef_s *tmp; tmp = &predefs; tmp->flag = argv[i] + 2; tmp->next = lpc_predefs; lpc_predefs = tmp; continue; } fprintf(stderr, "Illegal flag syntax: %s\n", argv[i]); exit(-1); case 'N': no_ip_demon++; continue; #ifdef YYDEBUG case 'y': yydebug = 1; continue; #endif /* YYDEBUG */ case 'm': mud_lib = alloc_cstring(argv[i] + 2, "mudlib dir"); if (chdir(mud_lib) == -1) { fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib); exit(-1); } new_mudlib = 1; break; } } if (!new_mudlib && chdir(mud_lib) == -1) { fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib); exit(-1); } get_version(version_buf); time(&tm); debug_message("----------------------------------------------------------------------------\n%s (%s) starting up on %s - %s\n\n", MUD_NAME, version_buf, ARCH, ctime(&tm)); #ifdef BINARIES init_binaries(argc, argv); #endif #ifdef LPC_TO_C init_lpc_to_c(); #endif add_predefines(); #ifndef NO_IP_DEMON if (!no_ip_demon && ADDR_SERVER_IP) init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT); #endif /* NO_IP_DEMON */ eval_cost = max_cost; /* needed for create() functions */ save_context(&econ); if (SETJMP(econ.context)) { debug_message("The simul_efun (%s) and master (%s) objects must be loadable.\n", SIMUL_EFUN, MASTER_FILE); exit(-1); } else { init_simul_efun(SIMUL_EFUN); init_master(MASTER_FILE); } pop_context(&econ); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { continue; } else { /* * Look at flags. -m and -o has already been tested. */ switch (argv[i][1]) { case 'D': case 'N': case 'm': case 'y': continue; case 'f': save_context(&econ); if (SETJMP(econ.context)) { debug_message("Error while calling master::flag(\"%s\"), aborting ...", argv[i] + 2); exit(-1); } push_constant_string(argv[i] + 2); (void) apply_master_ob(APPLY_FLAG, 1); if (MudOS_is_being_shut_down) { debug_message("Shutdown by master object.\n"); exit(0); } pop_context(&econ); continue; case 'e': e_flag++; continue; case 'p': external_port[0].port = atoi(argv[i] + 2); continue; case 'd': #ifdef DEBUG d_flag++; #else debug_message("Driver must be compiled with DEBUG on to use -d.\n"); #endif case 'c': comp_flag++; continue; case 't': t_flag++; continue; default: debug_message("Unknown flag: %s\n", argv[i]); exit(-1); } } } if (MudOS_is_being_shut_down) exit(1); if (strlen(DEFAULT_FAIL_MESSAGE)) default_fail_message = DEFAULT_FAIL_MESSAGE; else default_fail_message = "What?"; #ifdef PACKAGE_MUDLIB_STATS restore_stat_files(); #endif #ifdef PACKAGE_SOCKETS init_sockets(); /* initialize efun sockets */ #endif preload_objects(e_flag); #ifdef SIGFPE signal(SIGFPE, sig_fpe); #endif #ifdef TRAP_CRASHES #ifdef SIGUSR1 signal(SIGUSR1, sig_usr1); #endif signal(SIGTERM, sig_term); signal(SIGINT, sig_int); #ifndef DEBUG #if defined(SIGABRT) && !defined(LATTICE) signal(SIGABRT, sig_abrt); #endif #ifdef SIGIOT signal(SIGIOT, sig_iot); #endif #ifdef SIGHUP signal(SIGHUP, sig_hup); #endif #ifdef SIGBUS signal(SIGBUS, sig_bus); #endif #ifndef LATTICE signal(SIGSEGV, sig_segv); signal(SIGILL, sig_ill); #endif #endif /* DEBUG */ #endif backend(); return 0; }
//-------------------------- // // ( ) Copy block // ( ) Copy block (repeated) // ( ) Move block // ( ) Clear block // ( ) Flip block // ( ) Mirror block // ( ) Paint block // ( ) Copy to... // ( ) Copy to... // ( ) Save as MZM // // _OK_ _Cancel_ // //-------------------------- boolean select_block_command(struct world *mzx_world, struct block_info *block, enum editor_mode mode) { int dialog_result; struct element *elements[3]; struct dialog di; int selection = 0; const char *radio_button_strings[] = { "Copy block", "Copy block (repeated)", "Move block", "Clear block", "Flip block", "Mirror block", "Paint block", NULL, NULL, "Save as MZM" }; switch(mode) { default: case EDIT_BOARD: radio_button_strings[7] = "Copy to overlay"; radio_button_strings[8] = "Copy to vlayer"; break; case EDIT_OVERLAY: radio_button_strings[7] = "Copy to board"; radio_button_strings[8] = "Copy to vlayer"; break; case EDIT_VLAYER: radio_button_strings[7] = "Copy to board"; radio_button_strings[8] = "Copy to overlay"; break; } // Prevent previous keys from carrying through. force_release_all_keys(); set_context(CTX_BLOCK_CMD); elements[0] = construct_radio_button(2, 2, radio_button_strings, 10, 21, &selection); elements[1] = construct_button(5, 13, "OK", 0); elements[2] = construct_button(15, 13, "Cancel", -1); construct_dialog(&di, "Choose block command", 26, 3, 29, 16, elements, 3, 0); dialog_result = run_dialog(mzx_world, &di); pop_context(); destruct_dialog(&di); // Prevent UI keys from carrying through. force_release_all_keys(); if(dialog_result) { block->selected = false; return false; } // Translate selection to a real block command. block->selected = true; block->command = BLOCK_CMD_NONE; block->src_mode = mode; block->dest_mode = mode; switch(selection) { case 0: block->command = BLOCK_CMD_COPY; break; case 1: block->command = BLOCK_CMD_COPY_REPEATED; break; case 2: block->command = BLOCK_CMD_MOVE; break; case 3: block->command = BLOCK_CMD_CLEAR; break; case 4: block->command = BLOCK_CMD_FLIP; break; case 5: block->command = BLOCK_CMD_MIRROR; break; case 6: block->command = BLOCK_CMD_PAINT; break; case 7: { block->command = BLOCK_CMD_COPY; switch(mode) { case EDIT_BOARD: block->dest_mode = EDIT_OVERLAY; break; case EDIT_OVERLAY: case EDIT_VLAYER: block->dest_mode = EDIT_BOARD; break; } break; } case 8: { block->command = BLOCK_CMD_COPY; switch(mode) { case EDIT_BOARD: case EDIT_OVERLAY: block->dest_mode = EDIT_VLAYER; break; case EDIT_VLAYER: block->dest_mode = EDIT_OVERLAY; break; } break; } case 9: block->command = BLOCK_CMD_SAVE_MZM; break; } return true; }
bool solver_enumerationt::iterate(invariantt &_inv) { tpolyhedra_domaint::templ_valuet &inv = static_cast<tpolyhedra_domaint::templ_valuet &>(_inv); bool improved = false; literalt activation_literal = new_context(); exprt inv_expr = tpolyhedra_domain.to_pre_constraints(inv); debug() << "pre-inv: " << from_expr(ns,"",inv_expr) << eom; #ifndef DEBUG_FORMULA solver << or_exprt(inv_expr, literal_exprt(activation_literal)); #else debug() << "literal " << activation_literal << eom; literalt l = solver.convert(or_exprt(inv_expr, literal_exprt(activation_literal))); if(!l.is_constant()) { debug() << "literal " << l << ": " << from_expr(ns,"",or_exprt(inv_expr, literal_exprt(activation_literal))) <<eom; formula.push_back(l); } #endif exprt::operandst strategy_cond_exprs; tpolyhedra_domain.make_not_post_constraints(inv, strategy_cond_exprs, strategy_value_exprs); #ifndef DEBUG_FORMULA solver << or_exprt(disjunction(strategy_cond_exprs), literal_exprt(activation_literal)); #else exprt expr_act= or_exprt(disjunction(strategy_cond_exprs), literal_exprt(activation_literal)); l = solver.convert(expr_act); if(!l.is_constant()) { debug() << "literal " << l << ": " << from_expr(ns,"", expr_act) <<eom; formula.push_back(l); } #endif debug() << "solve(): "; #ifdef DEBUG_FORMULA bvt whole_formula = formula; whole_formula.insert(whole_formula.end(),activation_literals.begin(),activation_literals.end()); solver.set_assumptions(whole_formula); #endif if(solve() == decision_proceduret::D_SATISFIABLE) { debug() << "SAT" << eom; #if 0 for(unsigned i=0; i<whole_formula.size(); i++) { debug() << "literal: " << whole_formula[i] << " " << solver.l_get(whole_formula[i]) << eom; } for(unsigned i=0; i<tpolyhedra_domain.template_size(); i++) { exprt c = tpolyhedra_domain.get_row_constraint(i,inv[i]); debug() << "cond: " << from_expr(ns, "", c) << " " << from_expr(ns, "", solver.get(c)) << eom; debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ.pre_guards[i]) << " " << from_expr(ns, "", solver.get(tpolyhedra_domain.templ.pre_guards[i])) << eom; debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ.post_guards[i]) << " " << from_expr(ns, "", solver.get(tpolyhedra_domain.templ.post_guards[i])) << eom; } for(replace_mapt::const_iterator it=renaming_map.begin(); it!=renaming_map.end(); ++it) { debug() << "replace_map (1st): " << from_expr(ns, "", it->first) << " " << from_expr(ns, "", solver.get(it->first)) << eom; debug() << "replace_map (2nd): " << from_expr(ns, "", it->second) << " " << from_expr(ns, "", solver.get(it->second)) << eom; } #endif tpolyhedra_domaint::templ_valuet new_value; tpolyhedra_domain.initialize(new_value); for(unsigned row=0;row<tpolyhedra_domain.template_size(); row++) { tpolyhedra_domaint::row_valuet v = simplify_const(solver.get(strategy_value_exprs[row])); tpolyhedra_domain.set_row_value(row,v,new_value); debug() << "value: " << from_expr(ns,"",v) << eom; } tpolyhedra_domain.join(inv,new_value); improved = true; } else { debug() << "UNSAT" << eom; #ifdef DEBUG_FORMULA for(unsigned i=0; i<whole_formula.size(); i++) { if(solver.is_in_conflict(whole_formula[i])) debug() << "is_in_conflict: " << whole_formula[i] << eom; else debug() << "not_in_conflict: " << whole_formula[i] << eom; } #endif } pop_context(); return improved; }
static void call_heart_beat() { object_t *ob; heart_beat_t *curr_hb; error_context_t econ; #ifdef WIN32 static long Win32Thread = -1; #endif heart_beat_flag = 0; #ifdef SIGALRM signal(SIGALRM, sigalrm_handler); #endif #ifdef HAS_UALARM ualarm(HEARTBEAT_INTERVAL, 0); #else # ifdef WIN32 if (Win32Thread == -1) Win32Thread = _beginthread( /* This shouldn't be necessary b/c alarm_loop is already declared as this. Microsoft lossage? -Beek */ (void (__cdecl *)(void *)) alarm_loop, 256, 0); # else alarm(SYSV_HEARTBEAT_INTERVAL); /* defined in config.h */ # endif #endif current_interactive = 0; if ((num_hb_to_do = num_hb_objs)) { num_hb_calls++; heart_beat_index = 0; save_context(&econ); while (!heart_beat_flag) { ob = (curr_hb = &heart_beats[heart_beat_index])->ob; DEBUG_CHECK(!(ob->flags & O_HEART_BEAT), "Heartbeat not set in object on heartbeat list!"); DEBUG_CHECK(ob->flags & O_SWAPPED, "Heartbeat in swapped object.\n"); /* is it time to do a heart beat ? */ curr_hb->heart_beat_ticks--; if (ob->prog->heart_beat != 0) { if (curr_hb->heart_beat_ticks < 1) { object_t *new_command_giver; curr_hb->heart_beat_ticks = curr_hb->time_to_heart_beat; current_heart_beat = ob; new_command_giver = ob; #ifndef NO_SHADOWS while (new_command_giver->shadowing) new_command_giver = new_command_giver->shadowing; #endif #ifndef NO_ADD_ACTION if (!(new_command_giver->flags & O_ENABLE_COMMANDS)) new_command_giver = 0; #endif #ifdef PACKAGE_MUDLIB_STATS add_heart_beats(&ob->stats, 1); #endif eval_cost = max_cost; if (SETJMP(econ.context)) { restore_context(&econ); } else { save_command_giver(new_command_giver); call_direct(ob, ob->prog->heart_beat - 1, ORIGIN_DRIVER, 0); pop_stack(); /* pop the return value */ restore_command_giver(); } current_object = 0; } } if (++heart_beat_index == num_hb_to_do) break; } pop_context(&econ); if (heart_beat_index < num_hb_to_do) perc_hb_probes = 100 * (float) heart_beat_index / num_hb_to_do; else perc_hb_probes = 100.0; heart_beat_index = num_hb_to_do = 0; } current_prog = 0; current_heart_beat = 0; look_for_objects_to_swap(); call_out(); #ifdef PACKAGE_MUDLIB_STATS mudlib_stats_decay(); #endif } /* call_heart_beat() */
static void __check_for_updates(struct world *mzx_world, struct config_info *conf) { int cur_host; char *update_host; bool try_next_host = true; bool ret = false; set_context(CTX_UPDATER); if(conf->update_host_count < 1) { error("No updater hosts defined! Aborting.", 1, 8, 0); goto err_out; } if(!swivel_current_dir(true)) goto err_out; for(cur_host = 0; (cur_host < conf->update_host_count) && try_next_host; cur_host++) { char **list_entries, buffer[LINE_BUF_LEN], *url_base, *value; struct manifest_entry *removed, *replaced, *added, *e; int i = 0, entries = 0, buf_len, result; char update_branch[LINE_BUF_LEN]; const char *version = VERSION; int list_entry_width = 0; enum host_status status; struct host *h = NULL; unsigned int retries; FILE *f; // Acid test: Can we write to this directory? f = fopen_unsafe(UPDATES_TXT, "w+b"); if(!f) { error("Failed to create \"" UPDATES_TXT "\". Check permissions.", 1, 8, 0); goto err_chdir; } update_host = conf->update_hosts[cur_host]; if(!reissue_connection(conf, &h, update_host)) goto err_host_destroy; for(retries = 0; retries < MAX_RETRIES; retries++) { // Grab the file containing the names of the current Stable and Unstable status = host_recv_file(h, "/" UPDATES_TXT, f, "text/plain"); rewind(f); if(status == HOST_SUCCESS) break; if(!reissue_connection(conf, &h, update_host)) goto err_host_destroy; } if(retries == MAX_RETRIES) { snprintf(widget_buf, WIDGET_BUF_LEN, "Failed to download \"" UPDATES_TXT "\" (err=%d).\n", status); widget_buf[WIDGET_BUF_LEN - 1] = 0; error(widget_buf, 1, 8, 0); goto err_host_destroy; } snprintf(update_branch, LINE_BUF_LEN, "Current-%s", conf->update_branch_pin); // Walk this list (of two, hopefully) while(true) { char *m = buffer, *key; value = NULL; // Grab a single line from the manifest if(!fgets(buffer, LINE_BUF_LEN, f)) break; key = strsep(&m, ":\n"); if(!key) break; value = strsep(&m, ":\n"); if(!value) break; if(strcmp(key, update_branch) == 0) break; } fclose(f); unlink(UPDATES_TXT); /* There was no "Current-XXX: Version" found; we cannot proceed with the * update because we cannot compute an update URL below. */ if(!value) { error("Failed to identify applicable update version.", 1, 8, 0); goto err_host_destroy; } /* There's likely to be a space prepended to the version number. * Skip it here. */ if(value[0] == ' ') value++; /* We found the latest update version, but we should check to see if that * matches the version we're already using. The user may choose to receive * "stability" updates for their current major version, or upgrade to the * newest one. */ if(strcmp(value, version) != 0) { struct element *elements[6]; struct dialog di; buf_len = snprintf(widget_buf, WIDGET_BUF_LEN, "A new major version is available (%s)", value); widget_buf[WIDGET_BUF_LEN - 1] = 0; elements[0] = construct_label((55 - buf_len) >> 1, 2, widget_buf); elements[1] = construct_label(2, 4, "You can continue to receive updates for the version\n" "installed (if available), or you can upgrade to the\n" "newest major version (recommended)."); elements[2] = construct_label(2, 8, "If you do not upgrade, this question will be asked\n" "again the next time you run the updater.\n"); elements[3] = construct_button(9, 11, "Upgrade", 0); elements[4] = construct_button(21, 11, "Update Old", 1); elements[5] = construct_button(36, 11, "Cancel", 2); construct_dialog(&di, "New Major Version", 11, 6, 55, 14, elements, 6, 3); result = run_dialog(mzx_world, &di); destruct_dialog(&di); // User pressed Escape, abort all updates if(result < 0 || result == 2) { try_next_host = false; goto err_host_destroy; } // User pressed Upgrade, use new major if(result == 0) version = value; } /* We can now compute a unique URL base for the updater. This will * be composed of a user-selected version and a static platform-archicture * name. */ url_base = cmalloc(LINE_BUF_LEN); snprintf(url_base, LINE_BUF_LEN, "/%s/" PLATFORM, version); debug("Update base URL: %s\n", url_base); /* The call to manifest_get_updates() destroys any existing manifest * file in this directory. Since we still allow user to abort after * this call, and downloading the updates may fail, we copy the * old manifest to a backup location and optionally restore it later. */ if(!backup_original_manifest()) { error("Failed to back up manifest. Check permissions.", 1, 8, 0); try_next_host = false; goto err_free_url_base; } for(retries = 0; retries < MAX_RETRIES; retries++) { bool m_ret; m_hide(); draw_window_box(3, 11, 76, 13, DI_MAIN, DI_DARK, DI_CORNER, 1, 1); write_string("Computing manifest deltas (added, replaced, deleted)..", 13, 12, DI_TEXT, 0); update_screen(); m_ret = manifest_get_updates(h, url_base, &removed, &replaced, &added); clear_screen(32, 7); m_show(); update_screen(); if(m_ret) break; if(!reissue_connection(conf, &h, update_host)) goto err_roll_back_manifest; } if(retries == MAX_RETRIES) { error("Failed to compute update manifests", 1, 8, 0); goto err_roll_back_manifest; } // At this point, we have a successful manifest, so we won't need another host try_next_host = false; if(!removed && !replaced && !added) { struct element *elements[3]; struct dialog di; elements[0] = construct_label(2, 2, "This client is already current."); elements[1] = construct_button(7, 4, "OK", 0); elements[2] = construct_button(13, 4, "Try next host", 1); construct_dialog(&di, "No Updates", 22, 9, 35, 6, elements, 3, 1); result = run_dialog(mzx_world, &di); destruct_dialog(&di); if((result == 1) && (cur_host < conf->update_host_count)) try_next_host = true; goto err_free_update_manifests; } for(e = removed; e; e = e->next, entries++) list_entry_width = MAX(list_entry_width, 2 + (int)strlen(e->name)+1+1); for(e = replaced; e; e = e->next, entries++) list_entry_width = MAX(list_entry_width, 2 + (int)strlen(e->name)+1+1); for(e = added; e; e = e->next, entries++) list_entry_width = MAX(list_entry_width, 2 + (int)strlen(e->name)+1+1); // We don't want the listbox to be too wide list_entry_width = MIN(list_entry_width, 60); list_entries = cmalloc(entries * sizeof(char *)); for(e = removed; e; e = e->next, i++) { list_entries[i] = cmalloc(list_entry_width); snprintf(list_entries[i], list_entry_width, "- %s", e->name); list_entries[i][list_entry_width - 1] = 0; } for(e = replaced; e; e = e->next, i++) { list_entries[i] = cmalloc(list_entry_width); snprintf(list_entries[i], list_entry_width, "* %s", e->name); list_entries[i][list_entry_width - 1] = 0; } for(e = added; e; e = e->next, i++) { list_entries[i] = cmalloc(list_entry_width); snprintf(list_entries[i], list_entry_width, "+ %s", e->name); list_entries[i][list_entry_width - 1] = 0; } draw_window_box(19, 1, 59, 4, DI_MAIN, DI_DARK, DI_CORNER, 1, 1); write_string(" Task Summary ", 33, 1, DI_TITLE, 0); write_string("ESC - Cancel [+] Add [-] Delete", 21, 2, DI_TEXT, 0); write_string("ENTER - Proceed [*] Replace ", 21, 3, DI_TEXT, 0); result = list_menu((const char **)list_entries, list_entry_width, NULL, 0, entries, ((80 - (list_entry_width + 9)) >> 1) + 1, 4); for(i = 0; i < entries; i++) free(list_entries[i]); free(list_entries); clear_screen(32, 7); update_screen(); if(result < 0) goto err_free_update_manifests; /* Defer deletions until we restart; any of these files may still be * in use by this (old) process. Reduce the number of entries by the * number of removed items for the progress meter below. */ for(e = removed; e; e = e->next, entries--) delete_hook(e->name); /* Since the operations for adding and replacing a file are identical, * we modify the replaced list and tack on the added list to the end. * * Either list may be NULL; in the case that `replaced' is NULL, simply * re-assign the `added' pointer. `added' being NULL has no effect. * * Later, we need only free the replaced list (see below). */ if(replaced) { for(e = replaced; e->next; e = e->next) ; e->next = added; } else replaced = added; cancel_update = false; host_set_callbacks(h, NULL, recv_cb, cancel_cb); i = 1; for(e = replaced; e; e = e->next, i++) { for(retries = 0; retries < MAX_RETRIES; retries++) { char name[72]; bool m_ret; if(!check_create_basedir(e->name)) goto err_free_delete_list; final_size = (long)e->size; m_hide(); snprintf(name, 72, "%s (%ldb) [%u/%u]", e->name, final_size, i, entries); meter(name, 0, final_size); update_screen(); m_ret = manifest_entry_download_replace(h, url_base, e, delete_hook); clear_screen(32, 7); m_show(); update_screen(); if(m_ret) break; if(cancel_update) { error("Download was cancelled; update aborted.", 1, 8, 0); goto err_free_delete_list; } if(!reissue_connection(conf, &h, update_host)) goto err_free_delete_list; host_set_callbacks(h, NULL, recv_cb, cancel_cb); } if(retries == MAX_RETRIES) { snprintf(widget_buf, WIDGET_BUF_LEN, "Failed to download \"%s\" (after %d attempts).", e->name, retries); widget_buf[WIDGET_BUF_LEN - 1] = 0; error(widget_buf, 1, 8, 0); goto err_free_delete_list; } } if(delete_list) { f = fopen_unsafe(DELETE_TXT, "wb"); if(!f) { error("Failed to create \"" DELETE_TXT "\". Check permissions.", 1, 8, 0); goto err_free_delete_list; } for(e = delete_list; e; e = e->next) { fprintf(f, "%08x%08x%08x%08x%08x%08x%08x%08x %lu %s\n", e->sha256[0], e->sha256[1], e->sha256[2], e->sha256[3], e->sha256[4], e->sha256[5], e->sha256[6], e->sha256[7], e->size, e->name); } fclose(f); } try_next_host = false; ret = true; err_free_delete_list: manifest_list_free(&delete_list); delete_list = delete_p = NULL; err_free_update_manifests: manifest_list_free(&removed); manifest_list_free(&replaced); err_roll_back_manifest: restore_original_manifest(ret); err_free_url_base: free(url_base); err_host_destroy: host_destroy(h); pop_context(); } //end host for loop err_chdir: swivel_current_dir_back(true); err_out: /* At this point we found updates and we successfully updated * to them. Reload the program with the original argv. */ if(ret) { const void *argv = process_argv; struct element *elements[2]; struct dialog di; elements[0] = construct_label(2, 2, "This client will now attempt to restart itself."); elements[1] = construct_button(23, 4, "OK", 0); construct_dialog(&di, "Update Successful", 14, 9, 51, 6, elements, 2, 1); run_dialog(mzx_world, &di); destruct_dialog(&di); execv(process_argv[0], argv); perror("execv"); error("Attempt to invoke self failed!", 1, 8, 0); return; } }
HRON_PRELUDE static void scanner_statetransition ( secret__scanner_state * ss , scanner_state from , scanner_state to , scanner_state_transition sst ) { HRON_UNUSED(from); assert(ss); switch (sst) { case SST_From_Indention__To_Indention: ++ss->parser_state.indention; break; } switch (to) { case SS_PreProcessorTag: case SS_EmptyTag: case SS_CommentTag: case SS_ValueTag: case SS_ValueLine: case SS_ObjectTag: ss->result = SR_Done; break; case SS_EndOfValueLine: ss->parser_state.value__line(ss->parser_state.payload, ss->current_line, ss->parser_state.expected_indent, ss->current_line_end); break; case SS_EndOfPreProcessorTag: ss->parser_state.preprocessor(ss->parser_state.payload, ss->current_line, ss->parser_state.indention + 1, ss->current_line_end); break; case SS_EndOfCommentTag: ss->parser_state.comment(ss->parser_state.payload, ss->current_line, ss->parser_state.indention + 1, ss->current_line_end); break; case SS_EndOfEmptyTag: if (ss->parser_state.is_building_value) { ss->parser_state.value__line(ss->parser_state.payload, empty, 0, 0); } else { ss->parser_state.empty(ss->parser_state.payload, ss->current_line, 0, ss->current_line_end); } break; case SS_EndOfObjectTag: pop_context(ss); ss->parser_state.object__begin(ss->parser_state.payload, ss->current_line, ss->parser_state.indention + 1, ss->current_line_end); ss->parser_state.expected_indent = ss->parser_state.indention + 1; break; case SS_EndOfValueTag: pop_context(ss); ss->parser_state.is_building_value = 1; ss->parser_state.value__begin(ss->parser_state.payload, ss->current_line, ss->parser_state.indention + 1, ss->current_line_end); ss->parser_state.expected_indent = ss->parser_state.indention + 1; break; case SS_Error: ss->result = SS_Error; ss->parser_state.error(ss->parser_state.payload, ss->parser_state.line_no, ss->current_line, ss->current_line_begin, ss->current_line_end, "General"); break; case SS_WrongTagError: ss->result = SS_Error; ss->parser_state.error(ss->parser_state.payload, ss->parser_state.line_no, ss->current_line, ss->current_line_begin, ss->current_line_end, "WrongTag"); break; case SS_NonEmptyTagError: ss->result = SS_Error; ss->parser_state.error(ss->parser_state.payload, ss->parser_state.line_no, ss->current_line, ss->current_line_begin, ss->current_line_end, "NonEmptyTag"); break; } }
int error(const char *string, unsigned int type, unsigned int options, unsigned int code) { const char *type_name; int t1 = 9, ret = 0; char temp[5]; int x; // Find the name of this error type. if(type >= sizeof(error_type_names) / sizeof(*error_type_names)) type = 0; type_name = error_type_names[type]; // If graphics couldn't initialize, print the error to stderr and abort. if(!has_video_initialized()) { fprintf(stderr, "%s%s\n", type_name, string); exit(-1); } // Window set_context(code >> 8); m_hide(); save_screen(); dialog_fadein(); draw_window_box(1, 10, 78, 14, 76, 64, 72, 1, 1); // Add title and error name x = 40 - (int)strlen(type_name)/2; write_string(type_name, x, 10, 78, 0); write_string(string, 40 - ((Uint32)strlen(string) / 2), 11, 79, 0); // Add options write_string("Press", 4, 13, 78, 0); if(options & ERROR_OPT_FAIL) { write_string(", F for Fail", t1, 13, 78, 0); t1 += 12; } if(options & ERROR_OPT_RETRY) { write_string(", R to Retry", t1, 13, 78, 0); t1 += 12; } if(options & ERROR_OPT_EXIT) { write_string(", E to Exit", t1, 13, 78, 0); t1 += 11; } if(options & ERROR_OPT_OK) { write_string(", O for OK", t1, 13, 78, 0); t1 += 10; } draw_char('.', 78, t1, 13); draw_char(':', 78, 9, 13); // Add code if not 0 if(code != 0) { write_string(" Debug code:0000h ", 30, 14, 64, 0); sprintf(temp, "%x", code); write_string(temp, 46 - (Uint32)strlen(temp), 14, 64, 0); } update_screen(); // Get key do { wait_event(); t1 = get_key(keycode_internal); //Process switch(t1) { case IKEY_f: fail: if(!(options & ERROR_OPT_FAIL)) break; ret = ERROR_OPT_FAIL; break; case IKEY_r: retry: if(!(options & ERROR_OPT_RETRY)) break; ret = ERROR_OPT_RETRY; break; case IKEY_e: exit: if(!(options & ERROR_OPT_EXIT)) break; ret = ERROR_OPT_EXIT; break; case IKEY_o: ok: if(!(options & ERROR_OPT_OK)) break; ret = ERROR_OPT_OK; break; case IKEY_h: if(!(options & ERROR_OPT_HELP)) break; // Call help break; case IKEY_ESCAPE: // Escape. Order of options this applies to- // Fail, Ok, Retry, Exit. if(options & ERROR_OPT_FAIL ) goto fail; if(options & ERROR_OPT_OK ) goto ok; if(options & ERROR_OPT_RETRY) goto retry; goto exit; case IKEY_RETURN: // Enter. Order of options this applies to- // OK, Retry, Fail, Exit. if(options & ERROR_OPT_OK ) goto ok; if(options & ERROR_OPT_RETRY) goto retry; if(options & ERROR_OPT_FAIL ) goto fail; goto exit; } } while(ret == 0); pop_context(); // Restore screen and exit appropriately dialog_fadeout(); restore_screen(); m_show(); if(ret == ERROR_OPT_EXIT) // Exit the program { platform_quit(); exit(-1); } return ret; }
/* Actions to be taken when a whole line of input has been processed */ ELEMENT * end_line (ELEMENT *current) { char *end_command = 0; enum command_id end_id; // 2621 /* If empty line, start a new paragraph. */ if (last_contents_child (current) && last_contents_child (current)->type == ET_empty_line) { debug ("END EMPTY LINE"); if (current->type == ET_paragraph) /* 2625 */ { ELEMENT *e; /* Remove empty_line element. */ e = pop_element_from_contents (current); current = end_paragraph (current); /* Add empty_line to higher-level element. */ add_to_element_contents (current, e); } //else if () // in menu_entry_description else if (!in_no_paragraph_contexts (current_context ())) { current = end_paragraph (current); } } // 2667 /* The end of the line of a menu. */ else if (current->type == ET_menu_entry_name || current->type == ET_menu_entry_node) { ELEMENT *end_comment; int empty_menu_entry_node = 0; if (current->type == ET_menu_entry_node) { ELEMENT *last = last_contents_child (current); if (current->contents.number > 0 && (last->cmd == CM_c || last->cmd == CM_comment)) { end_comment = pop_element_from_contents (current); } /* If contents empty or is all whitespace. */ if (current->contents.number == 0 || (current->contents.number == 1 && last->text.end > 0 && !last->text.text[strspn (last->text.text, whitespace_chars)])) { empty_menu_entry_node = 1; if (end_comment) add_to_element_contents (current, end_comment); } } // 2689 /* Abort the menu entry if there is no destination node given. */ if (empty_menu_entry_node || current->type == ET_menu_entry_name) { } else // 2768 { debug ("MENU ENTRY END LINE"); current = current->parent; current = enter_menu_entry_node (current); if (end_comment) add_to_element_contents (current, end_comment); } } /* Is it a def line 2778 */ else if (current->parent && current->parent->type == ET_def_line) { enum element_type def_command; if (pop_context () != ct_def) { abort (); } #if 0 /* current->parent is a ET_def_line, and current->parent->parent the def command. */ def_command = current->parent->parent->cmd; // strip a trailing x parse_def (def_command, current->contents); #endif current = current->parent->parent; current = begin_preformatted (current); } // 2872 /* End of a line starting a block. */ else if (current->type == ET_block_line_arg) { enum context c; // pop and check context_stack c = pop_context (); if (c != ct_line) { // bug abort (); } // 2881 if (current->parent->cmd == CM_multitable) { /* Parse prototype row */ // But not @columnfractions, I assume? } if (current->parent->cmd == CM_float) // 2943 { } current = current->parent; //2965 /* Don't consider empty argument of block @-command as argument, reparent them as contents. */ if (current->args.list[0]->contents.number > 0 && current->args.list[0]->contents.list[0]->type == ET_empty_line_after_command) { ELEMENT *e; e = current->args.list[0]->contents.list[0]; insert_into_contents (current, e, 0); // TODO: Free lists? current->args.number = 0; } if (command_flags(current) & CF_blockitem) // 2981 { if (current->cmd == CM_enumerate) { } else if (item_line_command (current->cmd)) // 3002 { // check command_as_argument registered in 'extra', and // that it accepts arguments in braces } if (current->cmd == CM_itemize) // 3019 { // check that command_as_argument is alone on the line } // check if command_as_argument isn't an accent command /* 3052 - if no command_as_argument given, default to @bullet for @itemize, and @asis for @table. */ { ELEMENT *bi = new_element (ET_before_item); add_to_element_contents (current, bi); current = bi; } } /* CF_blockitem */ // 3077 if (command_flags(current) & CF_menu) { /* Start reading a menu. Processing will continue in handle_menu in menus.c. */ ELEMENT *menu_comment = new_element (ET_menu_comment); add_to_element_contents (current, menu_comment); current = menu_comment; debug ("MENU COMMENT OPEN"); push_context (ct_preformatted); } current = begin_preformatted (current); } /* after an "@end verbatim" 3090 */ else if (current->contents.number && last_contents_child(current)->type == ET_empty_line_after_command /* The Perl version gets the command with the 'command' key in 'extra'. */ && contents_child_by_index(current, -2) && contents_child_by_index(current, -2)->cmd == CM_verbatim) { // I don't know what this means. raw command is @html etc.? /* if we are after a @end verbatim, we must restart a preformatted if needed, since there is no @end command explicitly associated to raw commands it won't be done elsewhere. */ current = begin_preformatted (current); } /* if it's a misc line arg 3100 */ else if (current->type == ET_misc_line_arg) { int cmd_id, arg_type; enum context c; isolate_last_space (current, 0); current = current->parent; cmd_id = current->cmd; if (!cmd_id) abort (); arg_type = command_data(cmd_id).data; /* Check 'line' is top of the context stack */ c = pop_context (); if (c != ct_line) { /* error */ abort (); } // 3114 debug ("MISC END %s", command_data(cmd_id).cmdname); if (arg_type > 0) { /* arg_type is number of args */ // parse_line_command_args // save in 'misc_args' extra key } else if (arg_type == MISC_text) /* 3118 */ { char *text; /* argument string has to be parsed as Texinfo. This calls convert in Common/Text.pm on the first element of current->args. */ /* however, this makes it impossible to decouple the parser and output stages... Any use of Texinfo::Convert is problematic. */ if (current->args.number > 0) text = text_convert (current->args.list[0]); else text = "foo"; if (!strcmp (text, "")) { /* 3123 warning - missing argument */ abort (); } else { if (current->cmd == CM_end) /* 3128 */ { char *line = text; /* Set end_command - used below. */ end_command = read_command_name (&line); /* Check argument meets format of a Texinfo command (alphanumberic character followed by alphanumeric characters or hyphens. */ /* Check if argument is a block Texinfo command. */ end_id = lookup_command (end_command); if (end_id == -1 || !(command_data(end_id).flags & CF_block)) { /* error - unknown @end */ } else { debug ("END BLOCK %s", end_command); /* 3140 Handle conditional block commands (e.g. @ifinfo) */ /* If we are in a non-ignored conditional, there is not an element for the block in the tree; it is recorded in the conditional stack. Pop it and check it is the same as the one given in the @end line. */ if (command_data(end_id).data == BLOCK_conditional) { if (conditional_number > 0) { enum command_id popped; popped = pop_conditional_stack (); if (popped != end_id) abort (); } } } } else if (current->cmd == CM_include) /* 3166 */ { debug ("Include %s", text); input_push_file (text); } else if (current->cmd == CM_documentencoding) /* 3190 */ { } else if (current->cmd == CM_documentlanguage) /* 3223 */ { } } } else if (current->cmd == CM_node) /* 3235 */ { int i; ELEMENT *arg; ELEMENT *first_arg; /* Construct 'nodes_manuals' array. This would be an 'extra' reference to an array that doesn't exist anywhere else. */ /* This sets the 'node_content' and 'normalized' keys on each element in 'nodes_manuals'. */ //parse_node_manual (); /* In Perl a copy of the argument list is taken and the empty space arguments are removed with trim_spaces_comment_from_content. */ first_arg = current->args.list[0]; arg = new_element (ET_NONE); arg->parent_type = route_not_in_tree; for (i = 0; i < first_arg->contents.number; i++) { if (first_arg->contents.list[i]->type != ET_empty_spaces_after_command && first_arg->contents.list[i]->type != ET_spaces_at_end) { /* FIXME: Is this safe to serialize? */ /* For example, if there are extra keys in the elements under each argument? They may not be set in a copy. Hopefully there aren't many extra keys set on commands in node names. */ add_to_element_contents (arg, first_arg->contents.list[i]); } } add_extra_key_contents (current, "node_content", arg); /* Also set 'normalized' here. The normalized labels are actually the keys of "labels_information($parser)". */ /*Check that the node name doesn't have a filename element for referring to an external manual (_check_internal_node), and that it is not empty (_check_empty_node). */ //check_node_label (); /* This sets 'node_content' and 'normalized' on the node, among other things (which were already set in parse_node_manual). */ register_label (current, arg); current_node = current; } else if (current->cmd == CM_listoffloats) /* 3248 */ { } else { /* All the other "line" commands" */ } current = current->parent; /* 3285 */ if (end_command) /* Set above */ { /* more processing of @end */ ELEMENT *end_elt; debug ("END COMMAND %s", end_command); /* Reparent the "@end" element to be a child of the block element. */ end_elt = pop_element_from_contents (current); /* 3289 If not a conditional */ if (command_data(end_id).data != BLOCK_conditional) { ELEMENT *closed_command; /* This closes tree elements (e.g. paragraphs) until we reach end_command. It can print an error if another block command is found first. */ current = close_commands (current, end_id, &closed_command, 0); /* 3292 */ if (!closed_command) abort (); // 3335 close_command_cleanup (closed_command); // 3301 INLINE_INSERTCOPYING add_to_element_contents (closed_command, end_elt); // 3321 // 3324 ET_menu_comment if (close_preformatted_command (end_id)) current = begin_preformatted (current); } } /* 3340 */ else { if (close_preformatted_command (cmd_id)) current = begin_preformatted (current); } /* 3346 included file */ /* 3350 */ if (cmd_id == CM_setfilename && (current_node || current_section)) { /* warning */ abort (); } /* 3355 columnfractions */ else if (cmd_id == CM_columnfractions) { ELEMENT *before_item; // check if in multitable // pop and check context stack current = current->parent; before_item = new_element (ET_before_item); add_to_element_contents (current, before_item); current = before_item; } else if (command_data(cmd_id).flags & CF_root) /* 3380 */ { current = last_contents_child (current); /* 3383 Destroy all contents (why do we do this?) */ while (last_contents_child (current)) destroy_element (pop_element_from_contents (current)); /* Set 'associated_section' extra key for a node. */ if (cmd_id != CM_node && cmd_id != CM_part) { if (current_node) { if (!lookup_extra_key (current_node, "associated_section")) { add_extra_key_element (current_node, "associated_section", current); add_extra_key_element (current, "associated_node", current_node); } } // "current parts" - 3394 current_section = current; } } /* 3416 */ } // something to do with an empty line /* 3419 */ //if () /* 'line' or 'def' at top of "context stack" */ { /* Recurse. */ } return current; } /* end_line 3487 */