struct high_syntax *load_syntax_subr(unsigned char *name, unsigned char *subr, struct high_param *params) { struct high_syntax *syntax; /* New syntax table */ /* Find syntax table */ /* Already loaded? */ for (syntax = syntax_list; syntax; syntax = syntax->next) { if (syntax_match(syntax, name, subr, params)) { return syntax; } } /* Create new one */ syntax = joe_malloc(sizeof(struct high_syntax)); syntax->name = zdup(name); syntax->subr = subr ? zdup(subr) : 0; syntax->params = params; syntax->next = syntax_list; syntax->nstates = 0; syntax->color = 0; syntax->states = joe_malloc(sizeof(struct high_state *) * (syntax->szstates = 64)); syntax->ht_states = htmk(syntax->szstates); iz_cmd(&syntax->default_cmd); syntax->default_cmd.reset = 1; syntax->stack_base = 0; syntax_list = syntax; if (load_dfa(syntax)) { /* dump_syntax(syntax); */ return syntax; } else { if (syntax_list == syntax) { syntax_list = syntax_list->next; } else { struct high_syntax *syn; for (syn = syntax_list; syn->next != syntax; syn = syn->next); syn->next = syntax->next; } htrm(syntax->ht_states); joe_free(syntax->name); joe_free(syntax->states); joe_free(syntax); return 0; } }
static struct high_state *find_state(struct high_syntax *syntax, unsigned char *name) { struct high_state *state; /* Find state */ state = htfind(syntax->ht_states, name); /* It doesn't exist, so create it */ if (!state) { int y; state = joe_malloc(sizeof(struct high_state)); state->name = zdup(name); state->no = syntax->nstates; state->color = FG_WHITE; /* Expand the state table if necessary */ if (syntax->nstates == syntax->szstates) { syntax->states = joe_realloc(syntax->states, sizeof(struct high_state *) * (syntax->szstates *= 2)); } syntax->states[syntax->nstates++] = state; for (y = 0; y != 256; ++y) { state->cmd[y] = &syntax->default_cmd; } state->delim = 0; htadd(syntax->ht_states, state->name, state); } return state; }
/* Opens new bw with startup log */ int ushowlog(BW *bw) { if (startup_log) { B *copied; BW *newbw; void *object; W *w; if (uduptw(bw)) { return -1; } copied = bcpy(startup_log->bof, startup_log->eof); copied->name = zdup(USTR "* Startup Log *"); copied->internal = 1; newbw = (BW *) maint->curwin->object; object = newbw->object; w = newbw->parent; bwrm(newbw); w->object = (void *) (newbw = bwmk(w, copied, 0)); wredraw(newbw->parent); newbw->object = object; return 0; } return 1; }
void addcmd(unsigned char *s, MACRO *m) { CMD *cmd = (CMD *) joe_malloc(sizeof(CMD)); if (!cmdhash) izcmds(); cmd->name = zdup(s); cmd->flag = 0; cmd->func = NULL; cmd->m = m; cmd->arg = 1; cmd->negarg = NULL; htadd(cmdhash, cmd->name, cmd); }
KMAP *kmap_getcontext(unsigned char *name) { struct context *c; for (c = contexts; c; c = c->next) if (!zcmp(c->name, name)) return c->kmap; c = (struct context *) joe_malloc(sizeof(struct context)); c->next = contexts; c->name = zdup(name); contexts = c; return c->kmap = mkkmap(); }
void parse_color_def(struct high_color **color_list, unsigned char *p, unsigned char *name, int line) { unsigned char bf[256]; if (!parse_tows(&p, bf)) { struct high_color *color, *gcolor; /* Find color */ color = find_color(*color_list, bf, name); /* If it doesn't exist, create it */ if (!color) { color = joe_malloc(sizeof(struct high_color)); color->name = zdup(bf); color->color = 0; color->next = *color_list; *color_list = color; } else { i_printf_2((char *)joe_gettext(_("%s %d: Class already defined\n")), name, line); } /* Find it in global list */ if (color_list != &global_colors && (gcolor = find_color(global_colors, bf, name))) { color->color = gcolor->color; } else { /* Parse color definition */ while (parse_ws(&p, '#'), !parse_ident(&p, bf, sizeof(bf))) { color->color |= meta_color(bf); } } } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing class name\n")), name, line); } }
void parse_options(struct high_syntax *syntax, struct high_cmd *cmd, FILE *f, unsigned char *p, int parsing_strings, unsigned char *name, int line) { unsigned char buf[1024]; unsigned char bf[256]; unsigned char bf1[256]; while (parse_ws(&p, '#'), !parse_ident(&p, bf, sizeof(bf))) { if (!zcmp(bf, USTR "buffer")) { cmd->start_buffering = 1; } else if (!zcmp(bf, USTR "hold")) { cmd->stop_buffering = 1; } else if (!zcmp(bf, USTR "save_c")) { cmd->save_c = 1; } else if (!zcmp(bf, USTR "save_s")) { cmd->save_s = 1; } else if (!zcmp(bf, USTR "recolor")) { parse_ws(&p, '#'); if (!parse_char(&p, '=')) { parse_ws(&p, '#'); if (parse_int(&p, &cmd->recolor)) { i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line); } } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line); } } else if (!zcmp(bf, USTR "call")) { parse_ws(&p, '#'); if (!parse_char(&p, '=')) { parse_ws(&p, '#'); if (!parse_char(&p, '.')) { zcpy(bf, syntax->name); goto subr; } else if (parse_ident(&p, bf, sizeof(bf))) { i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line); } else { if (!parse_char(&p, '.')) { subr: if (parse_ident(&p, bf1, sizeof(bf1))) { i_printf_2((char *)joe_gettext(_("%s %d: Missing subroutine name\n")), name, line); } cmd->call = load_syntax_subr(bf, bf1, parse_params(syntax->params, &p, name, line)); } else { cmd->call = load_syntax_subr(bf, 0, parse_params(syntax->params, &p, name, line)); } } } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line); } } else if (!zcmp(bf, USTR "return")) { cmd->rtn = 1; } else if (!zcmp(bf, USTR "reset")) { cmd->reset = 1; } else if (!parsing_strings && (!zcmp(bf, USTR "strings") || !zcmp(bf, USTR "istrings"))) { if (bf[0] == 'i') { cmd->ignore = 1; } while (fgets((char *)buf, 1023, f)) { ++line; p = buf; parse_ws(&p, '#'); if (*p) { if (!parse_field(&p, USTR "done")) { break; } if (parse_string(&p, bf, sizeof(bf)) >= 0) { parse_ws(&p, '#'); if (cmd->ignore) { lowerize(bf); } if (!parse_ident(&p, bf1, sizeof(bf1))) { struct high_cmd *kw_cmd = mkcmd(); kw_cmd->noeat = 1; kw_cmd->new_state = find_state(syntax, bf1); if (!zcmp(bf, USTR "&")) { cmd->delim = kw_cmd; } else { if (!cmd->keywords) { cmd->keywords = htmk(64); } htadd(cmd->keywords, zdup(bf), kw_cmd); } parse_options(syntax, kw_cmd, f, p, 1, name, line); } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing state name\n")), name, line); } } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing string\n")), name, line); } } } } else if (!zcmp(bf, USTR "noeat")) { cmd->noeat = 1; } else if (!zcmp(bf, USTR "mark")) { cmd->start_mark = 1; } else if (!zcmp(bf, USTR "markend")) { cmd->stop_mark = 1; } else if (!zcmp(bf, USTR "recolormark")) { cmd->recolor_mark = 1; } else { i_printf_2((char *)joe_gettext(_("%s %d: Unknown option\n")), name, line); } } }
struct high_param *parse_params(struct high_param *current_params, unsigned char **ptr, unsigned char *name, int line) { unsigned char *p = *ptr; unsigned char bf[256]; struct high_param *params; struct high_param **param_ptr; /* Propagate currently defined parameters */ param_ptr = ¶ms; while (current_params) { *param_ptr = joe_malloc(sizeof(struct high_param)); (*param_ptr)->name = zdup(current_params->name); param_ptr = &(*param_ptr)->next; current_params = current_params->next; } *param_ptr = 0; parse_ws(&p, '#'); if (!parse_char(&p, '(')) { for (;;) { parse_ws(&p, '#'); if (!parse_char(&p, ')')) { break; } else if (!parse_char(&p, '-')) { if (!parse_ident(&p, bf, sizeof(bf))) { int cmp = 0; param_ptr = ¶ms; /* Parameters are sorted */ while (*param_ptr && (cmp = zcmp(bf, (*param_ptr)->name)) > 0) { param_ptr = &(*param_ptr)->next; } if (*param_ptr && !cmp) { /* Remove this parameter */ struct high_param *param = *param_ptr; *param_ptr = param->next; joe_free(param); } } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing parameter name\n")), name, line); } } else if (!parse_ident(&p, bf, sizeof(bf))) { int cmp = 0; param_ptr = ¶ms; /* Keep parameters sorted */ while (*param_ptr && (cmp = zcmp(bf, (*param_ptr)->name)) > 0) { param_ptr = &(*param_ptr)->next; } /* Discard duplicates */ if (!*param_ptr || cmp) { struct high_param *param = joe_malloc(sizeof(struct high_param)); param->name = zdup(bf); param->next = *param_ptr; *param_ptr = param; } } else { i_printf_2((char *)joe_gettext(_("%s %d: Missing )\n")), name, line); break; } } } *ptr = p; return params; }
static int load_po(FILE *f) { char buf[1024]; char msgid[1024]; char msgstr[1024]; char bf[8192]; struct charmap *po_map = locale_map; int preload_flag = 0; msgid[0] = 0; msgstr[0] = 0; while (preload_flag || fgets(buf,SIZEOF(buf)-1,f)) { const char *p; preload_flag = 0; p = buf; parse_ws(&p, '#'); if (!parse_field(&p, "msgid")) { ptrdiff_t ofst = 0; ptrdiff_t len; msgid[0] = 0; parse_ws(&p, '#'); while ((len = parse_string(&p, msgid + ofst, SIZEOF(msgid)-ofst)) >= 0) { preload_flag = 0; ofst += len; parse_ws(&p, '#'); if (!*p) { if (fgets(buf,SIZEOF(buf) - 1,f)) { p = buf; preload_flag = 1; parse_ws(&p, '#'); } else { goto bye; } } } } else if (!parse_field(&p, "msgstr")) { ptrdiff_t ofst = 0; ptrdiff_t len; msgstr[0] = 0; parse_ws(&p, '#'); while ((len = parse_string(&p, msgstr + ofst, SIZEOF(msgstr)-ofst)) >= 0) { preload_flag = 0; ofst += len; parse_ws(&p, '#'); if (!*p) { if (fgets(buf,SIZEOF(buf) - 1,f)) { p = buf; preload_flag = 1; parse_ws(&p, '#'); } else { break; } } } if (msgid[0] && msgstr[0]) { /* Convert to locale character map */ my_iconv(bf, SIZEOF(bf), locale_map,msgstr,po_map); /* Add to hash table */ htadd(gettext_ht, zdup(msgid), zdup(bf)); } else if (!msgid[0] && msgstr[0]) { char *tp = zstr(msgstr, "charset="); if (tp) { /* Copy character set name up to next delimiter */ int x; tp += SIZEOF("charset=") - 1; while (*tp == ' ' || *tp == '\t') ++tp; for (x = 0; tp[x] && tp[x] !='\n' && tp[x] != '\r' && tp[x] != ' ' && tp[x] != '\t' && tp[x] != ';' && tp[x] != ','; ++x) msgid[x] = tp[x]; msgid[x] = 0; po_map = find_charmap(msgid); if (!po_map) po_map = locale_map; } } } } bye: fclose(f); return 0; }
int main(int argc, char **real_argv, char **envv) { CAP *cap; unsigned char **argv = (unsigned char **)real_argv; struct stat sbuf; unsigned char *s; unsigned char *t; long time_rc; unsigned char *run; #ifdef __MSDOS__ unsigned char *rundir; #endif SCRN *n; int opened = 0; int omid; int backopt; int c; joe_locale(); mainenv = (unsigned char **)envv; vmem = vtmp(); startup_log = bfind_scratch(USTR "* Startup Log *"); startup_log->internal = 1; #ifdef __MSDOS__ _fmode = O_BINARY; zlcpy(stdbuf, sizeof(stdbuf), argv[0]); joesep(stdbuf); run = namprt(stdbuf); rundir = dirprt(stdbuf); for (c = 0; run[c]; ++c) if (run[c] == '.') { run = vstrunc(run, c); break; } #else run = namprt(argv[0]); #endif if ((s = (unsigned char *)getenv("LINES")) != NULL) sscanf((char *)s, "%d", &lines); if ((s = (unsigned char *)getenv("COLUMNS")) != NULL) sscanf((char *)s, "%d", &columns); if ((s = (unsigned char *)getenv("BAUD")) != NULL) sscanf((char *)s, "%u", (unsigned *)&Baud); if (getenv("DOPADDING")) dopadding = 1; if (getenv("NOXON")) noxon = 1; if ((s = (unsigned char *)getenv("JOETERM")) != NULL) joeterm = s; #ifndef __MSDOS__ if (!(cap = my_getcap(NULL, 9600, NULL, NULL))) { logerror_0((char *)joe_gettext(_("Couldn't load termcap/terminfo entry\n"))); goto exit_errors; } #endif #ifdef __MSDOS__ s = vsncpy(NULL, 0, sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } vsrm(s); s = vsncpy(NULL, 0, sv(rundir)); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } #else /* Name of system joerc file. Try to find one with matching language... */ /* Try full language: like joerc.de_DE */ t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc.")); t = vsncpy(sv(t), sz(locale_msgs)); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else { /* Try generic language: like joerc.de */ if (locale_msgs[0] && locale_msgs[1] && locale_msgs[2]=='_') { vsrm(t); t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc.")); t = vsncpy(sv(t), locale_msgs, 2); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else goto nope; } else { nope: vsrm(t); /* Try Joe's bad english */ t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc")); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else time_rc = 0; } } /* User's joerc file */ s = (unsigned char *)getenv("HOME"); if (s) { s = vsncpy(NULL, 0, sz(s)); s = vsncpy(sv(s), sc("/.")); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); if (!stat((char *)s,&sbuf)) { if (sbuf.st_mtime < time_rc) { logmessage_2((char *)joe_gettext(_("Warning: %s is newer than your %s.\n")),t,s); } } c = procrc(cap, s); if (c == 0) { vsrm(t); goto donerc; } if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } } vsrm(s); s = t; c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } /* Try built-in joerc */ s = vsncpy(NULL, 0, sc("*")); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c != 0 && c != 1) { /* If *fancyjoerc not present, use *joerc which is always there */ s = vstrunc(s, 0); s = vsncpy(sv(s),sc("*joerc")); c = procrc(cap, s); } if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } #endif logerror_1((char *)joe_gettext(_("Couldn't open '%s'\n")), s); goto exit_errors; return 1; donerc: if (validate_rc()) { logerror_0((char *)joe_gettext(_("rc file has no :main key binding section or no bindings. Bye.\n"))); goto exit_errors; } { unsigned char buf[10]; int x; zlcpy(buf, sizeof(buf), USTR "\"`\" ` "); type_backtick = mparse(0, buf, &x, 0); } shell_kbd = mkkbd(kmap_getcontext(USTR "shell")); if (!isatty(fileno(stdin))) idleout = 0; for (c = 1; argv[c]; ++c) { if (argv[c][0] == '-') { if (argv[c][1]) switch (glopt(argv[c] + 1, argv[c + 1], NULL, 1)) { case 0: logerror_1((char *)joe_gettext(_("Unknown option '%s'\n")), argv[c]); break; case 1: break; case 2: ++c; break; } else idleout = 0; } } /* initialize mouse support */ if (xmouse && (s=(unsigned char *)getenv("TERM")) && strstr((char *)s,"xterm")) usexmouse=1; if (!(n = nopen(cap))) goto exit_errors; maint = screate(n); load_state(); /* It would be better if this ran uedit() to load files */ /* The business with backopt is to load the file first, then apply file * local options afterwords */ /* orphan is not compatible with exemac()- macros need a window to exist */ for (c = 1, backopt = 0; argv[c]; ++c) if (argv[c][0] == '+' && argv[c][1]>='0' && argv[c][1]<='9') { if (!backopt) backopt = c; } else if (argv[c][0] == '-' && argv[c][1]) { if (!backopt) backopt = c; if (glopt(argv[c] + 1, argv[c + 1], NULL, 0) == 2) ++c; } else { B *b = bfind(argv[c]); BW *bw = NULL; int er = berror; /* This is too annoying */ /* set_current_dir(argv[c],1); */ setup_history(&filehist); append_history(filehist,sz(argv[c])); /* wmktw inserts the window before maint->curwin */ if (!orphan || !opened) { bw = wmktw(maint, b); if (er) msgnwt(bw->parent, joe_gettext(msgs[-er])); } else { long line; b->orphan = 1; b->oldcur = pdup(b->bof, USTR "main"); pline(b->oldcur, get_file_pos(b->name)); p_goto_bol(b->oldcur); line = b->oldcur->line - (maint->h - 1) / 2; if (line < 0) line = 0; b->oldtop = pdup(b->oldcur, USTR "main"); pline(b->oldtop, line); p_goto_bol(b->oldtop); } if (bw) { long lnum = 0; bw->o.readonly = bw->b->rdonly; if (backopt) { while (backopt != c) { if (argv[backopt][0] == '+') { sscanf((char *)(argv[backopt] + 1), "%ld", &lnum); ++backopt; } else { if (glopt(argv[backopt] + 1, argv[backopt + 1], &bw->o, 0) == 2) backopt += 2; else backopt += 1; lazy_opts(bw->b, &bw->o); } } } bw->b->o = bw->o; bw->b->rdonly = bw->o.readonly; /* Put cursor in window, so macros work properly */ maint->curwin = bw->parent; /* Execute macro */ if (er == -1 && bw->o.mnew) exmacro(bw->o.mnew,1); if (er == 0 && bw->o.mold) exmacro(bw->o.mold,1); /* Hmm... window might not exist any more... depends on what macro does... */ if (lnum > 0) pline(bw->cursor, lnum - 1); else pline(bw->cursor, get_file_pos(bw->b->name)); p_goto_bol(bw->cursor); /* Go back to first window so windows are in same order as command line */ if (opened) wnext(maint); } opened = 1; backopt = 0; } if (opened) { wshowall(maint); omid = mid; mid = 1; dofollows(); mid = omid; } else { BW *bw = wmktw(maint, bfind(USTR "")); if (bw->o.mnew) exmacro(bw->o.mnew,1); } maint->curwin = maint->topwin; if (logerrors) { B *copied = bcpy(startup_log->bof, startup_log->eof); BW *bw = wmktw(maint, copied); copied->name = zdup(startup_log->name); copied->internal = 1; maint->curwin = bw->parent; wshowall(maint); } if (help) { help_on(maint); } if (!nonotice) { joe_snprintf_3(msgbuf,JOE_MSGBUFSIZE,joe_gettext(_("\\i** Joe's Own Editor v%s ** (%s) ** Copyright %s 2015 **\\i")),VERSION,locale_map->name,(locale_map->type ? "©" : "(C)")); msgnw(((BASE *)lastw(maint)->object)->parent, msgbuf); } if (!idleout) { if (!isatty(fileno(stdin)) && modify_logic(maint->curwin->object, ((BW *)maint->curwin->object)->b)) { /* Start shell going in first window */ unsigned char **a; unsigned char *cmd; a = vamk(10); cmd = vsncpy(NULL, 0, sc("/bin/sh")); a = vaadd(a, cmd); cmd = vsncpy(NULL, 0, sc("-c")); a = vaadd(a, cmd); cmd = vsncpy(NULL, 0, sc("/bin/cat")); a = vaadd(a, cmd); cstart (maint->curwin->object, USTR "/bin/sh", a, NULL, NULL, 0, 1, NULL, 0); } } edloop(0); save_state(); /* Delete all buffer so left over locks get eliminated */ brmall(); vclose(vmem); nclose(n); if (noexmsg) { if (notite) fprintf(stderr, "\n"); } else { if (exmsg) fprintf(stderr, "\n%s\n", exmsg); else if (notite) fprintf(stderr, "\n"); } return 0; exit_errors: /* Write out error log to console if we are exiting with errors. */ if (startup_log && startup_log->eof->byte) bsavefd(startup_log->bof, 2, startup_log->eof->byte); return 1; }