static void pp_define_object_macro(struct lexer *lexer, const char *name) { struct dynarr *darr = store_token_until_newline(lexer); // simple check for: #define x x case. // a real example is in: /usr/include/bits/confname.h // // the ultimate way to sovle the (indirectly) referring itself obj/func macro is // constructing the macro expanding tree if (dynarr_size(darr) == 1) { union token *tok = dynarr_get(darr, 0); if (tok->tok_tag == TOK_IDENTIFIER && strcmp(tok->id.s, name) == 0) { token_destroy(*tok); free(tok); dynarr_destroy(darr); red("ignore identity obj macro %s", name); return; } } struct macro *macro = obj_macro_init(darr); define_macro(lexer, name, macro); #if DUMP_MACRO // fprintf(stderr, "%s define the macro %s\n", lexer->cstream->path, name); macro_dump(lexer, name, macro); #endif }
/* * not support '...' yet */ static void pp_define_func_macro(struct lexer *lexer, const char *name) { expect(lexer, TOK_LPAREN); struct dynarr *paramlist = dynarr_init(); union token tok = lexer_next_token(lexer); if (tok.tok_tag != TOK_RPAREN) { while (true) { assume(tok, TOK_IDENTIFIER); dynarr_add(paramlist, tok.id.s); tok = lexer_next_token(lexer); if (tok.tok_tag == TOK_RPAREN) { break; } else { assume(tok, TOK_COMMA); } tok = lexer_next_token(lexer); } } struct dynarr *darr = store_token_until_newline(lexer); struct macro *macro = func_macro_init(paramlist, darr); define_macro(lexer, name, macro); #if DUMP_MACRO macro_dump(lexer, name, macro); #endif }
/* * Interact with "macros" * * Note that the macro "action" must be defined before the trigger. * * Could use some helpful instructions on this page. XXX XXX XXX */ void do_cmd_macros(void) { s32b i; char tmp[1024]; char buf[1024]; s32b mode; /* Roguelike */ if (rogue_like_commands) { mode = KEYMAP_MODE_ROGUE; } /* Original */ else { mode = KEYMAP_MODE_ORIG; } /* Enter "icky" mode */ character_icky++; /* Save screen */ Term_save(); /* Process requests until done */ while (1) { /* Clear screen */ Term_clear(); /* Describe */ prt("Interact with Macros", 2, 0); /* Describe that action */ prt("Current action (if any) shown below:", 20, 0); /* Analyze the current action */ ascii_to_text(buf, macro__buf); /* Display the current action */ prt(buf, 22, 0); /* Selections */ prt("(1) Load a user pref file", 4, 5); #ifdef ALLOW_MACROS prt("(2) Append macros to a file", 5, 5); prt("(3) Query a macro", 6, 5); prt("(4) Create a macro", 7, 5); prt("(5) Remove a macro", 8, 5); prt("(6) Append keymaps to a file", 9, 5); prt("(7) Query a keymap", 10, 5); prt("(8) Create a keymap", 11, 5); prt("(9) Remove a keymap", 12, 5); prt("(0) Enter a new action", 13, 5); #endif /* ALLOW_MACROS */ /* Prompt */ prt("Command: ", 16, 0); /* Get a command */ i = inkey(); /* Leave */ if (i == ESCAPE) break; /* Load a 'macro' file */ else if (i == '1') { /* Prompt */ prt("Command: Load a user pref file", 16, 0); /* Prompt */ prt("File: ", 18, 0); /* Default filename */ strnfmt(tmp, 1024, "%s.prf", player_name); /* Ask for a file */ if (!askfor_aux(tmp, 80)) continue; /* Process the given filename */ if (0 != process_pref_file(tmp)) { /* Prompt */ msg_print("Could not load file!"); } } #ifdef ALLOW_MACROS /* Save macros */ else if (i == '2') { /* Prompt */ prt("Command: Append macros to a file", 16, 0); /* Prompt */ prt("File: ", 18, 0); /* Default filename */ strnfmt(tmp, 1024, "%s.prf", player_name); /* Ask for a file */ if (!askfor_aux(tmp, 80)) continue; /* Dump the macros */ (void)macro_dump(tmp); /* Prompt */ msg_print("Appended macros."); } /* Query a macro */ else if (i == '3') { s32b k; /* Prompt */ prt("Command: Query a macro", 16, 0); /* Prompt */ prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, TRUE); /* Acquire action */ k = macro_find_exact(buf); /* Nothing found */ if (k < 0) { /* Prompt */ msg_print("Found no macro."); } /* Found one */ else { /* Obtain the action */ strcpy(macro__buf, macro__act[k]); /* Analyze the current action */ ascii_to_text(buf, macro__buf); /* Display the current action */ prt(buf, 22, 0); /* Prompt */ msg_print("Found a macro."); } } /* Create a macro */ else if (i == '4') { /* Prompt */ prt("Command: Create a macro", 16, 0); /* Prompt */ prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, TRUE); /* Clear */ clear_from(20); /* Prompt */ prt("Action: ", 20, 0); /* Convert to text */ ascii_to_text(tmp, macro__buf); /* Get an encoded action */ if (askfor_aux(tmp, 80)) { /* Convert to ascii */ text_to_ascii(macro__buf, tmp); /* Link the macro */ macro_add(buf, macro__buf); /* Prompt */ msg_print("Added a macro."); } } /* Remove a macro */ else if (i == '5') { /* Prompt */ prt("Command: Remove a macro", 16, 0); /* Prompt */ prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, TRUE); /* Link the macro */ macro_add(buf, buf); /* Prompt */ msg_print("Removed a macro."); } /* Save keymaps */ else if (i == '6') { /* Prompt */ prt("Command: Append keymaps to a file", 16, 0); /* Prompt */ prt("File: ", 18, 0); /* Default filename */ strnfmt(tmp, 1024, "%s.prf", player_name); /* Ask for a file */ if (!askfor_aux(tmp, 80)) continue; /* Dump the macros */ (void)keymap_dump(tmp); /* Prompt */ msg_print("Appended keymaps."); } /* Query a keymap */ else if (i == '7') { cptr act; /* Prompt */ prt("Command: Query a keymap", 16, 0); /* Prompt */ prt("Keypress: ", 18, 0); /* Get a keymap trigger */ do_cmd_macro_aux_keymap(buf); /* Look up the keymap */ act = keymap_act[mode][(byte)(buf[0])]; /* Nothing found */ if (!act) { /* Prompt */ msg_print("Found no keymap."); } /* Found one */ else { /* Obtain the action */ strcpy(macro__buf, act); /* Analyze the current action */ ascii_to_text(buf, macro__buf); /* Display the current action */ prt(buf, 22, 0); /* Prompt */ msg_print("Found a keymap."); } } /* Create a keymap */ else if (i == '8') { /* Prompt */ prt("Command: Create a keymap", 16, 0); /* Prompt */ prt("Keypress: ", 18, 0); /* Get a keymap trigger */ do_cmd_macro_aux_keymap(buf); /* Clear */ clear_from(20); /* Prompt */ prt("Action: ", 20, 0); /* Convert to text */ ascii_to_text(tmp, macro__buf); /* Get an encoded action */ if (askfor_aux(tmp, 80)) { /* Convert to ascii */ text_to_ascii(macro__buf, tmp); /* Free old keymap */ string_free(keymap_act[mode][(byte)(buf[0])]); /* Make new keymap */ keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf); /* Prompt */ msg_print("Added a keymap."); } } /* Remove a keymap */ else if (i == '9') { /* Prompt */ prt("Command: Remove a keymap", 16, 0); /* Prompt */ prt("Keypress: ", 18, 0); /* Get a keymap trigger */ do_cmd_macro_aux_keymap(buf); /* Free old keymap */ string_free(keymap_act[mode][(byte)(buf[0])]); /* Make new keymap */ keymap_act[mode][(byte)(buf[0])] = NULL; /* Prompt */ msg_print("Removed a keymap."); } /* Enter a new action */ else if (i == '0') { /* Prompt */ prt("Command: Enter a new action", 16, 0); /* Go to the correct location */ Term_gotoxy(0, 22); /* Hack -- limit the value */ tmp[80] = '\0'; /* Get an encoded action */ if (!askfor_aux(buf, 80)) continue; /* Extract an action */ text_to_ascii(macro__buf, buf); } #endif /* ALLOW_MACROS */ /* Oops */ else { /* Oops */ bell(); } /* Flush messages */ msg_print(NULL); } /* Load screen */ Term_load(); /* Leave "icky" mode */ character_icky--; }