static void handle_error_msg(struct compiler *c, char *str) { int i, len; for (i = 0; str[i]; i++) { if (str[i] == '\n') { str[i] = 0; break; } if (str[i] == '\t') str[i] = ' '; } len = i; if (len == 0) return; for (i = 0; i < c->error_formats.count; i++) { const struct error_format *p = c->error_formats.ptrs[i]; PTR_ARRAY(m); if (!regexp_exec_sub(&p->re, str, len, &m, 0)) continue; if (!p->ignore) { struct message *msg = new_message(m.ptrs[p->msg_idx]); msg->file = p->file_idx < 0 ? NULL : xstrdup(m.ptrs[p->file_idx]); msg->u.location.line = p->line_idx < 0 ? 0 : atoi(m.ptrs[p->line_idx]); msg->u.location.column = p->column_idx < 0 ? 0 : atoi(m.ptrs[p->column_idx]); add_message(msg); } ptr_array_free(&m); return; } add_message(new_message(str)); }
static void run_command(const struct command *cmds, char **av) { const struct command *cmd = find_command(cmds, av[0]); const char *pf; char **args; if (!cmd) { PTR_ARRAY(array); const char *alias_name = av[0]; const char *alias_value = find_alias(alias_name); struct error *err = NULL; int i; if (alias_value == NULL) { error_msg("No such command or alias: %s", alias_name); return; } if (!parse_commands(&array, alias_value, &err)) { error_msg("Parsing alias %s: %s", alias_name, err->msg); error_free(err); ptr_array_free(&array); return; } /* remove NULL */ array.count--; for (i = 1; av[i]; i++) ptr_array_add(&array, xstrdup(av[i])); ptr_array_add(&array, NULL); run_commands(cmds, &array); ptr_array_free(&array); return; } if (config_file && cmds == commands && !allowed_command(cmd->name)) { error_msg("Command %s not allowed in config file.", cmd->name); return; } // By default change can't be merged with previous on. // Any command can override this by calling begin_change() again. begin_change(CHANGE_MERGE_NONE); current_command = cmd; args = av + 1; pf = parse_args(args, cmd->flags, cmd->min_args, cmd->max_args); if (pf) cmd->cmd(pf, args); current_command = NULL; end_change(); }
void handle_command(const struct command *cmds, const char *cmd) { struct error *err = NULL; PTR_ARRAY(array); if (!parse_commands(&array, cmd, &err)) { error_msg("%s", err->msg); error_free(err); ptr_array_free(&array); return; } run_commands(cmds, &array); ptr_array_free(&array); }
int main(int argc, char *argv[]) { const char *term = getenv("TERM"); const char *home = getenv("HOME"); const char *tag = NULL; const char *rc = NULL; const char *command = NULL; char *command_history_filename; char *search_history_filename; char *editor_dir; bool read_rc = true; int i; if (!home) home = ""; home_dir = xstrdup(home); for (i = 1; i < argc; i++) { const char *opt = argv[i]; if (opt[0] != '-' || !opt[1]) break; if (!opt[2]) { switch (opt[1]) { case 'R': read_rc = false; continue; case 't': tag = opt_arg(opt, argv[++i]); continue; case 'r': rc = opt_arg(opt, argv[++i]); continue; case 'c': command = opt_arg(opt, argv[++i]); continue; case 'V': printf("%s %s\nWritten by Timo Hirvonen\n", program, version); return 0; } if (opt[1] == '-') { i++; break; } } printf("Usage: %s [-R] [-V] [-c command] [-t tag] [-r rcfile] [file]...\n", argv[0]); return 1; } if (!isatty(1)) { fprintf(stderr, "stdout doesn't refer to a terminal\n"); return 1; } if (term == NULL || term[0] == 0) { fprintf(stderr, "TERM not set\n"); return 1; } switch (term_init(term)) { case -1: fprintf(stderr, "terminal is hardcopy\n"); return 1; case -2: fprintf(stderr, "terminal could not be found\n"); return 1; case -3: fprintf(stderr, "terminfo database could not be found\n"); return 1; } // create this early. needed if lock-files is true editor_dir = editor_file(""); mkdir(editor_dir, 0755); free(editor_dir); setlocale(LC_CTYPE, ""); charset = nl_langinfo(CODESET); if (streq(charset, "UTF-8")) term_utf8 = true; exec_builtin_rc(builtin_rc); fill_builtin_colors(); // NOTE: syntax_changed() uses window. should possibly create window after reading rc window = new_window(); root_frame = new_root_frame(window); if (read_rc) { if (rc) { read_config(commands, rc, true); } else { char *filename = editor_file("rc"); if (read_config(commands, filename, false)) { free(filename); filename = xsprintf("%s/rc", pkgdatadir); read_config(commands, filename, true); } free(filename); } } update_all_syntax_colors(); sort_aliases(); /* Terminal does not generate signals for control keys. */ set_signal_handler(SIGINT, SIG_IGN); set_signal_handler(SIGQUIT, SIG_IGN); set_signal_handler(SIGPIPE, SIG_IGN); /* Terminal does not generate signal for ^Z but someone can send * us SIGTSTP nevertheless. SIGSTOP can't be caught. */ set_signal_handler(SIGTSTP, handle_sigtstp); set_signal_handler(SIGCONT, handle_sigcont); set_signal_handler(SIGWINCH, handle_sigwinch); load_file_history(); command_history_filename = editor_file("command-history"); search_history_filename = editor_file("search-history"); history_load(&command_history, command_history_filename, command_history_size); history_load(&search_history, search_history_filename, search_history_size); if (search_history.count) search_set_regexp(search_history.ptrs[search_history.count - 1]); /* Initialize terminal but don't update screen yet. Also display * "Press any key to continue" prompt if there were any errors * during reading configuration files. */ term_raw(); if (nr_errors) { any_key(); clear_error(); } editor_status = EDITOR_RUNNING; for (; i < argc; i++) window_open_buffer(window, argv[i], false, NULL); if (window->views.count == 0) window_open_empty_buffer(window); set_view(window->views.ptrs[0]); if (command || tag) resize(); if (command) handle_command(commands, command); if (tag) { PTR_ARRAY(array); ptr_array_add(&array, xstrdup("tag")); ptr_array_add(&array, xstrdup(tag)); ptr_array_add(&array, NULL); run_commands(commands, &array); ptr_array_free(&array); } resize(); main_loop(); ui_end(); // unlock files and add files to file history remove_frame(root_frame); history_save(&command_history, command_history_filename); history_save(&search_history, search_history_filename); free(command_history_filename); free(search_history_filename); save_file_history(); return 0; }