import parse-define.patch
[nedit-bw.git] / define_macro.patch
blobade71d703596b0759bed3f9ae3bf3f31dce2b096
1 ---
3 doc/help.etx | 5 ++
4 source/highlightData.c | 2 -
5 source/macro.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++
6 source/parse.y | 2 -
7 4 files changed, 104 insertions(+), 2 deletions(-)
9 diff --quilt old/source/macro.c new/source/macro.c
10 --- old/source/macro.c
11 +++ new/source/macro.c
12 @@ -440,10 +440,13 @@ static int dictsaveMS(WindowInfo *window
13 static int dictappendMS(WindowInfo *window, DataValue *argList, int nArgs,
14 DataValue *result, char **errMsg);
15 static int dictiselementMS(WindowInfo *window, DataValue *argList, int nArgs,
16 DataValue *result, char **errMsg);
18 +static int defineMS(WindowInfo *window, DataValue *argList, int nArgs,
19 + DataValue *result, char **errMsg);
21 /* Built-in subroutines and variables for the macro language */
22 static const BuiltInSubrName MacroSubrs[] = {
23 { "length", lengthMS },
24 { "get_range", getRangeMS },
25 { "t_print", tPrintMS },
26 @@ -506,10 +509,11 @@ static const BuiltInSubrName MacroSubrs[
27 { "dict_insert", dictinsertMS },
28 { "dict_complete", dictcompleteMS },
29 { "dict_save", dictsaveMS },
30 { "dict_append", dictappendMS },
31 { "dict_is_element", dictiselementMS },
32 + { "define", defineMS },
33 { NULL, NULL } /* sentinel */
36 static const BuiltInSubrName SpecialVars[] = {
37 { "$cursor", cursorMV },
38 @@ -3606,10 +3610,103 @@ static int callMS(WindowInfo *window, Da
39 return False;
41 return OverlayRoutineFromSymbol(sym, nArgs, 1);
44 +/*
45 + * define(func_name, func_body[, "override"])
46 + */
47 +static int defineMS(WindowInfo *window, DataValue *argList, int nArgs,
48 + DataValue *result, char **errMsg)
50 + char stringStorage[3][TYPE_INT_STR_SIZE(int)];
51 + char *name = NULL;
52 + char *body = NULL;
53 + char *bodysave = NULL;
54 + char *stoppedAt = NULL;
55 + char *namePtr;
56 + char *override = NULL;
57 + Program *prog;
58 + Symbol *sym;
59 + DataValue subrPtr;
61 + if (nArgs < 2 || nArgs > 3) {
62 + return wrongNArgsErr(errMsg);
63 + }
64 + if (!readStringArg(argList[0], &name, stringStorage[0], errMsg)) {
65 + return False;
66 + }
67 + if (!readStringArg(argList[1], &body, stringStorage[1], errMsg)) {
68 + return False;
69 + }
70 + if (nArgs > 2) {
71 + if (!readStringArg(argList[2], &override, stringStorage[2], errMsg)) {
72 + return False;
73 + }
74 + if (strcmp(override, "override")) {
75 + *errMsg = "Unknown parameter for subroutine %s";
76 + return False;
77 + }
78 + }
80 + /* check function name */
81 + if (strlen(name) > MAX_SYM_LEN ||
82 + (!isalpha((unsigned char)name[0]) && !name[0] != '$')) {
83 + *errMsg = "subroutine name is not a valid identifier";
84 + return False;
85 + }
86 + namePtr = name + 1;
87 + while (isalnum((unsigned char)*namePtr) || *namePtr == '_')
88 + namePtr++;
89 + if (*namePtr) {
90 + *errMsg = "subroutine name is not a valid identifier";
91 + return False;
92 + }
94 + /* add a terminating newline */
95 + bodysave = XtMalloc(strlen(body) + 2);
96 + if (!bodysave) {
97 + *errMsg = "Internal error";
98 + return False;
99 + }
100 + strcpy(bodysave, body);
101 + strcat(bodysave, "\n");
103 + /* Parse the macro and report errors if it fails */
104 + prog = ParseMacro(bodysave, errMsg, &stoppedAt, False, name);
105 + if (!prog) {
106 + ParseError(window->macroCmdData ? window->shell : NULL,
107 + bodysave, stoppedAt, name, *errMsg);
108 + XtFree(bodysave);
109 + return False;
111 + XtFree(bodysave);
113 + sym = LookupSymbol(name);
114 + if (sym) {
115 + if (!override) {
116 + FreeProgram(prog);
117 + *errMsg = "Try to override existing function.";
118 + return False;
119 + } else {
120 + if (sym->type != MACRO_FUNCTION_SYM) {
121 + FreeProgram(prog);
122 + *errMsg = "Try to override a non macro function.";
123 + return False;
125 + FreeProgram(sym->value.val.prog);
126 + sym->value.val.prog = prog;
128 + } else {
129 + subrPtr.tag = NO_TAG;
130 + subrPtr.val.prog = prog;
131 + sym = InstallSymbol(name, MACRO_FUNCTION_SYM, subrPtr);
134 + return True;
137 /* T Balinski */
138 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
139 DataValue *result, char **errMsg)
141 macroCmdInfo *cmdData;
142 diff --quilt old/source/highlightData.c new/source/highlightData.c
143 --- old/source/highlightData.c
144 +++ new/source/highlightData.c
145 @@ -549,11 +549,11 @@ static char *DefaultPatternSets[] = {
146 README:\"NEdit Macro syntax highlighting patterns, version 2.6, maintainer Thorsten Haude, nedit at thorstenhau.de\":::Flag::D\n\
147 Comment:\"#\":\"$\"::Comment::\n\
148 Built-in Misc Vars:\"(?<!\\Y)\\$(?:active_pane|args|calltip_ID|column|cursor|display_width|empty_array|file_name|file_path|language_mode|line|locked|max_font_width|min_font_width|modified|n_display_lines|n_panes|rangeset_list|read_only|selection_(?:start|end|left|right)|server_name|text_length|top_line|transient|VERSION|NEDIT_HOME)>\":::Identifier::\n\
149 Built-in Pref Vars:\"(?<!\\Y)\\$(?:auto_indent|em_tab_dist|file_format|font_name|font_name_bold|font_name_bold_italic|font_name_italic|highlight_syntax|incremental_backup|incremental_search_line|make_backup_copy|match_syntax_based|overtype_mode|show_line_numbers|show_matching|statistics_line|tab_dist|use_tabs|wrap_margin|wrap_text)>\":::Identifier2::\n\
150 Built-in Special Vars:\"(?<!\\Y)\\$(?:[1-9]|list_dialog_button|n_args|read_status|search_end|shell_cmd_status|string_dialog_button|sub_sep)>\":::String1::\n\
151 - Built-in Subrs:\"<(?:append_file|beep|call|calltip|clipboard_to_string|dialog|filename_dialog|dict_(?:insert|complete|save|append|is_element)|focus_window|get_character|get_matching|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|highlight_calltip_line|kill_calltip|length|list_dialog|max|min|rangeset_(?:add|create|destroy|get_by_name|includes|info|invert|range|set_color|set_mode|set_name|subtract)|read_file|replace_in_string|replace_range|replace_selection|replace_substring|search|search_string|select|select_rectangle|set_cursor_pos|set_transient|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
152 + Built-in Subrs:\"<(?:append_file|beep|call|calltip|clipboard_to_string|define|dialog|filename_dialog|dict_(?:insert|complete|save|append|is_element)|focus_window|get_character|get_matching|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|highlight_calltip_line|kill_calltip|length|list_dialog|max|min|rangeset_(?:add|create|destroy|get_by_name|includes|info|invert|range|set_color|set_mode|set_name|subtract)|read_file|replace_in_string|replace_range|replace_selection|replace_substring|search|search_string|select|select_rectangle|set_cursor_pos|set_transient|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
153 Menu Actions:\"<(?:new(?:_tab|_opposite)?|open|open-dialog|open_dialog|open-selected|open_selected|close|save|save-as|save_as|save-as-dialog|save_as_dialog|revert-to-saved|revert_to_saved|revert_to_saved_dialog|include-file|include_file|include-file-dialog|include_file_dialog|load-macro-file|load_macro_file|load-macro-file-dialog|load_macro_file_dialog|load-tags-file|load_tags_file|load-tags-file-dialog|load_tags_file_dialog|unload_tags_file|load_tips_file|load_tips_file_dialog|unload_tips_file|print|print-selection|print_selection|exit|undo|redo|delete|select-all|select_all|shift-left|shift_left|shift-left-by-tab|shift_left_by_tab|shift-right|shift_right|shift-right-by-tab|shift_right_by_tab|find|find-dialog|find_dialog|find-again|find_again|find-selection|find_selection|find_incremental|start_incremental_find|replace|replace-dialog|replace_dialog|replace-all|replace_all|replace-in-selection|replace_in_selection|replace-again|replace_again|replace_find|replace_find_same|replace_find_again|goto-line-number|goto_line_number|goto-line-number-dialog|goto_line_number_dialog|goto-selected|goto_selected|mark|mark-dialog|mark_dialog|goto-mark|goto_mark|goto-mark-dialog|goto_mark_dialog|match|select_to_matching|goto_matching|find-definition|find_definition|show_tip|split-pane|split_pane|close-pane|close_pane|detach_document(?:_dialog)?|move_document_dialog|(?:next|previous|last)_document|uppercase|lowercase|fill-paragraph|fill_paragraph|control-code-dialog|control_code_dialog|filter-selection-dialog|filter_selection_dialog|filter-selection|filter_selection|execute-command|execute_command|execute-command-dialog|execute_command_dialog|execute-command-line|execute_command_line|shell-menu-command|shell_menu_command|macro-menu-command|macro_menu_command|bg_menu_command|post_window_bg_menu|post_tab_context_menu|beginning-of-selection|beginning_of_selection|end-of-selection|end_of_selection|repeat_macro|repeat_dialog|raise_window|focus_pane|set_statistics_line|set_incremental_search_line|set_show_line_numbers|set_auto_indent|set_wrap_text|set_wrap_margin|set_highlight_syntax|set_make_backup_copy|set_incremental_backup|set_show_matching|set_match_syntax_based|set_overtype_mode|set_locked|set_tab_dist|set_em_tab_dist|set_use_tabs|set_fonts|set_language_mode)(?=\\s*\\()\":::Subroutine::\n\
154 Text Actions:\"<(?:self-insert|self_insert|grab-focus|grab_focus|extend-adjust|extend_adjust|extend-start|extend_start|extend-end|extend_end|secondary-adjust|secondary_adjust|secondary-or-drag-adjust|secondary_or_drag_adjust|secondary-start|secondary_start|secondary-or-drag-start|secondary_or_drag_start|process-bdrag|process_bdrag|move-destination|move_destination|move-to|move_to|move-to-or-end-drag|move_to_or_end_drag|end_drag|copy-to|copy_to|copy-to-or-end-drag|copy_to_or_end_drag|exchange|process-cancel|process_cancel|paste-clipboard|paste_clipboard|copy-clipboard|copy_clipboard|cut-clipboard|cut_clipboard|copy-primary|copy_primary|cut-primary|cut_primary|newline|newline-and-indent|newline_and_indent|newline-no-indent|newline_no_indent|delete-selection|delete_selection|delete-previous-character|delete_previous_character|delete-next-character|delete_next_character|delete-previous-word|delete_previous_word|delete-next-word|delete_next_word|delete-to-start-of-line|delete_to_start_of_line|delete-to-end-of-line|delete_to_end_of_line|forward-character|forward_character|backward-character|backward_character|key-select|key_select|process-up|process_up|process-down|process_down|process-shift-up|process_shift_up|process-shift-down|process_shift_down|process-home|process_home|forward-word|forward_word|backward-word|backward_word|forward-paragraph|forward_paragraph|backward-paragraph|backward_paragraph|beginning-of-line|beginning_of_line|end-of-line|end_of_line|beginning-of-file|beginning_of_file|end-of-file|end_of_file|next-page|next_page|previous-page|previous_page|page-left|page_left|page-right|page_right|toggle-overstrike|toggle_overstrike|scroll-up|scroll_up|scroll-down|scroll_down|scroll_left|scroll_right|scroll-to-line|scroll_to_line|select-all|select_all|deselect-all|deselect_all|focusIn|focusOut|process-return|process_return|process-tab|process_tab|insert-string|insert_string|mouse_pan)(?=\\s*\\()\":::Subroutine::\n\
155 Macro Hooks:\"<(?:(?:pre|post)_(?:open|save)|cursor_moved|modified|(?:losing_)?focus)_hook(?=\\s*\\()\":::Subroutine1::\n\
156 Keyword:\"<(?:break|continue|define|delete|else|for|if|in|return|typeof|while)>\":::Keyword::\n\
157 Braces:\"[{}\\[\\]]\":::Keyword::\n\
158 diff --quilt old/doc/help.etx new/doc/help.etx
159 --- old/doc/help.etx
160 +++ new/doc/help.etx
161 @@ -2688,10 +2688,15 @@ Macro Subroutines
163 **clipboard_to_string()**
164 Returns the contents of the clipboard as a macro string. Returns empty
165 string on error.
167 +**define( name, body [, "override"] )**
168 + Defines a new function with name ~name~ and the macro code in ~body~.
169 + If the ~"override"~ option is given the new symbol overrides previously
170 + defined functions.
172 **dialog( message, btn_1_label, btn_2_label, ... )**
173 Pop up a dialog for querying and presenting information to the user. First
174 argument is a string to show in the message area of the dialog.
175 Additional optional arguments represent labels for buttons to appear along
176 the bottom of the dialog. Returns the number of the button pressed (the
177 diff --quilt old/source/parse.y new/source/parse.y
178 --- old/source/parse.y
179 +++ new/source/parse.y
180 @@ -872,11 +872,11 @@ static int yylex(void)
181 if (!strcmp(symName, "continue")) return CONTINUE;
182 if (!strcmp(symName, "return")) return RETURN;
183 if (!strcmp(symName, "in")) return IN;
184 if (!strcmp(symName, "$args")) return ARG_LOOKUP;
185 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
186 - if (!strcmp(symName, "define")) return DEFINE;
187 + if (!strcmp(symName, "define") && follow_non_whitespace('(', SYMBOL, DEFINE) == DEFINE) return DEFINE;
188 if (!strcmp(symName, "typeof")) return TYPEOF;
189 if (nextSymIsField) {
190 nextSymIsField = 0;
191 yylval.sym = InstallStringConstSymbol(symName);
192 return FIELD;