// --------------------------------------------------------------------- string smopen() { string c=cmd.getid(); string p=cmd.getparms(); if (c=="edit") term->vieweditor(); if (c=="edit2") { if (note==0) return smerror("no edit window open"); note->on_winotherAct_triggered(); } if (c=="edit" || c=="edit2") return ""; if (c!="tab") { return smerror("unrecognized sm command: open " + c); } term->vieweditor(); if (p.empty()) note->newtemp(); else { QString f=s2q(smgetscript(p)); if (!cfexist(f)) return smerror("file not found: " + q2s(f)); note->fileopen(f); } rc=-1; return i2s(note->editIndex()); }
void smfree(struct mempool *mp, void *ptr) { struct memnode *mn, *pmn; if (!ptr) return; if (!(mn = find_mn(mp, ptr))) { smerror("SMALLOC: bad pointer passed to smfree()\n"); return; } if (!mn->used) { smerror("SMALLOC: attempt to free the not allocated region (double-free)\n"); return; } assert(mn->size > 0); #if SM_COMMIT_SUPPORT if (mp->uncommit) mp->uncommit(mn->mem_area, mn->size); #endif mn->used = 0; if (mn->next && !mn->next->used) { /* merge with next */ assert(mn->next->mem_area >= mn->mem_area); mntruncate(mn, mn->size + mn->next->size); } pmn = mn->prev; if (pmn && !pmn->used) { /* merge with prev */ assert(pmn->mem_area <= mn->mem_area); mntruncate(pmn, pmn->size + mn->size); mn = pmn; } }
// --------------------------------------------------------------------- string smfocus() { string p=cmd.getparms(); if (p.empty()) return smerror("sm focus needs additional parameters"); if (p=="term") term->smact(); else if (p=="edit") { if (note==0) return smerror("No active edit window"); if (note->editIndex()==-1) return ""; note->activateWindow(); note->raise(); note->repaint(); } else if (p=="edit2") { if (note2==0 || note2->editIndex()==-1) return smerror("No active edit2 window"); setnote(note2); note->activateWindow(); note->raise(); note->repaint(); } else return smerror("unrecognized sm command: focus " + p); return ""; }
// --------------------------------------------------------------------- string smsave() { string p=cmd.getparms(); if (note==0) return smerror("No active edit window"); if (p.empty()) return smerror("sm save parameter not given"); if (p=="edit") return smsaveactive(); if (p=="tabs") return smsaveall(); return smerror("sm save parameter should be 'edit' or 'tabs': " + p); }
// --------------------------------------------------------------------- string smgetwin(string p) { rc=-2; if (p=="term") return smgetwin1(tedit); if (p=="edit") { if (note==0) return smerror("No active edit window"); return smgetwin2(note); } if (note2==0) return smerror("No active edit2 window"); return smgetwin2(note2); }
// --------------------------------------------------------------------- string smactive() { string p=cmd.getparms(); QStringList opt=qsplit(p); if (note==0 || note->editIndex()<0) return smerror ("No active edit window"); if (opt[0]!="tab") return smerror ("unrecognized sm command parameters: " + p); int ndx=opt[1].toInt(); if (ndx<0 || ndx>=note->count()) return smerror ("invalid tab index: " + p); note->setindex(ndx); return ""; }
// --------------------------------------------------------------------- string smreplace() { string c=cmd.getid(); string p=cmd.getparms(); if (note==0 || note->editIndex()<0) return smerror ("No active edit window"); if (c!="edit") return smerror("unrecognized sm command: replace " + c); if (p.empty()) return smerror("replace needs 2 parameters: edit filename"); QString f=s2q(smgetscript(p)); if (!cfexist(f)) return smerror("file not found: " + q2s(f)); note->filereplace(f); return""; }
// --------------------------------------------------------------------- string sm(string c) { rc=0; if (c=="act") return smact(); if (c=="active") return smactive(); if (c=="close") return smclose(); if (c=="focus") return smfocus(); if (c=="font") return smfont(); if (c=="get") return smget(); if (c=="html") return smhtml(); if (c=="new") return smopen(); if (c=="open") return smopen(); if (c=="profont") return smprofont(); if (c=="replace") return smreplace(); if (c=="save") return smsave(); if (c=="set") return smset(); else if (c=="prompt") return smprompt(); cmd.getparms(); return smerror("unrecognized sm command: " + c); }
// --------------------------------------------------------------------- string smgettabs(QString p) { Note *n; if (p=="edit") { if (note==0) return smerror("No active edit window"); n=note; } else if (p=="edit2") { if (note2==0) return smerror("No active edit2 window"); n=note2; } else return smerror("sm get tabs needs edit or edit2 parameter"); rc=-2; return n->gettabstate(); }
// --------------------------------------------------------------------- string smsetinputlog(string c,string q) { if (c!="text") return smerror("unrecognized sm command: set inputlog " + c + "..." ); dlog_set(s2q(q)); return ""; }
int smget_area_size(struct mempool *mp, void *ptr) { struct memnode *mn; if (!(mn = find_mn(mp, ptr))) { smerror("SMALLOC: bad pointer passed to smget_area_size()\n"); return -1; } return mn->size; }
// --------------------------------------------------------------------- // set vertical scroll string smsetscroll(Bedit *e, string q) { if (!e) return""; QList<int> s=qsl2intlist(qsplit(q)); if (s.size()!= 1) return smerror("sm set scroll should have a single parameter of scroll size"); e->settop(s[0]); return""; }
void *smalloc(struct mempool *mp, size_t size) { struct memnode *mn; if (!size) { smerror("SMALLOC: zero-sized allocation attempted\n"); return NULL; } if (!(mn = smfind_free_area(mp, size))) { smerror("SMALLOC: Out Of Memory on alloc, requested=%zu\n", size); return NULL; } #if SM_COMMIT_SUPPORT if (mp->commit && !mp->commit(mn->mem_area, size)) return NULL; #endif mn->used = 1; mntruncate(mn, size); assert(mn->size == size); memset(mn->mem_area, 0, size); return mn->mem_area; }
// --------------------------------------------------------------------- string smset() { string p=cmd.getid(); if (p.empty()) return smerror("sm set parameters not given"); string c=cmd.getid(); if (c.empty()) return smerror("sm set " + p + " parameters not given"); string q=cmd.getparms(); if (p=="inputlog") return smsetinputlog(c,q); if (p=="term") { if (c=="text") return smsettext(p,q); if (c=="xywh") return smsetxywh(p,q); return smerror("command applies only to an edit window: " + c); } Bedit *e; if (p=="edit") { if (note==0) return smerror("No active edit window"); e=(Bedit *)note->editPage(); } else if (p=="edit2") { if (note2==0) return smerror("No active edit2 window"); e=(Bedit *)note2->editPage(); } else return smerror("unrecognized sm command: set " + p); if (e==0 && (c=="scroll" || c=="select" || c=="text")) return smerror("no edit window for sm command: set " + c); if (c=="scroll") return smsetscroll(e,q); if (c=="select") return smsetselect(e,q); if (c=="text") return smsettext(p,q); if (c=="xywh") return smsetxywh(p,q); return smerror("unrecognized sm command: set " + p + " " + q); }
// --------------------------------------------------------------------- string smsetselect(Bedit *e, string q) { if (!e) return""; QList<int> s=qsl2intlist(qsplit(q)); if (s.size()!= 2) return smerror("sm set select should have begin and end parameters"); int m=e->toPlainText().size(); if (s[1]==-1) s[1]=m; s[1]=qMin(m,s[1]); s[0]=qMin(s[0],s[1]); e->setselect(s[0],s[1]-s[0]); return""; }
// --------------------------------------------------------------------- string smclose() { string c=cmd.getid(); string p=cmd.getparms(); if (c=="tab") { if (note==0 || note->editIndex()<0) return smerror ("No active edit window"); int ndx=s2q(p).toInt(); if (ndx<0 || ndx>=note->count()) return smerror ("invalid tab index: " + p); note->tabclose(ndx); } else if (c=="edit") { if (note==0) return smerror ("No edit window"); note->close(); } else if (c=="edit2") { if (note2==0) return smerror ("No edit2 window"); note2->close(); } else return smerror ("unrecognized sm command parameters: " + p); return ""; }
// --------------------------------------------------------------------- string smget() { string p=cmd.getparms(); if (p.size()==0) return smerror("sm get needs additional parameters"); if (p=="active") return smgetactive(); if (p=="term" || p=="edit" || p=="edit2") return smgetwin(p); if (p=="termcwh") return smgettermcwh(); if (p=="inputlog") return smgetinputlog(); if (p=="xywh") return smgetxywh(); QStringList s=qsplit(p); if (s[0]=="tabs") { if(s.size()<=1) return smerror("sm command requires another parameter: get tabs"); else return smgettabs(s[1]); } return smerror("unrecognized sm command: get " + p); }
// --------------------------------------------------------------------- string smprofont() { string p=cmd.getparms(); if (!p.empty()) { Font *fnt = new Font(p); if (fnt->error) { delete fnt; return smerror("unrecognized sm command: font " + p); } else { QApplication::setFont(fnt->font); delete fnt; } } else QApplication::setFont(config.DefProFont); return ""; }
static struct memnode *find_mn(struct mempool *mp, unsigned char *ptr) { struct memnode *mn; if (!POOL_USED(mp)) { smerror("SMALLOC: unused pool passed\n"); return NULL; } for (mn = &mp->mn; mn->next; mn = mn->next) { if (mn->mem_area > ptr) return NULL; if (mn->mem_area == ptr) { return mn; } } return NULL; }
// --------------------------------------------------------------------- string smfont() { string p=cmd.getparms(); if (!p.empty()) { Font *fnt = new Font(p); if (fnt->error) { delete fnt; return smerror("unrecognized sm command: font " + p); } else { config.Font=fnt->font; delete fnt; fontset(config.Font); } } else fontset(config.DefFont); return ""; }
void *smrealloc(struct mempool *mp, void *ptr, size_t size) { struct memnode *mn, *pmn; if (!ptr) return smalloc(mp, size); if (!(mn = find_mn(mp, ptr))) { smerror("SMALLOC: bad pointer passed to smrealloc()\n"); return NULL; } if (!mn->used) { smerror("SMALLOC: attempt to realloc the not allocated region\n"); return NULL; } if (size == 0) { smfree(mp, ptr); return NULL; } if (size == mn->size) return ptr; if (size < mn->size) { /* shrink */ #if SM_COMMIT_SUPPORT if (mp->uncommit) mp->uncommit(mn->mem_area + size, mn->size - size); #endif mntruncate(mn, size); } else { /* grow */ struct memnode *nmn = mn->next; if (nmn && !nmn->used && mn->size + nmn->size >= size) { /* expand */ #if SM_COMMIT_SUPPORT if (mp->commit && !mp->commit(nmn->mem_area, size - mn->size)) return NULL; #endif memset(nmn->mem_area, 0, size - mn->size); mntruncate(mn, size); } else { pmn = mn->prev; if (pmn && !pmn->used && pmn->size + mn->size + (nmn->used ? 0 : nmn->size) >= size) { /* move */ #if SM_COMMIT_SUPPORT if (mp->commit) { size_t psize = min(size, pmn->size); if (!mp->commit(pmn->mem_area, psize)) return NULL; if (size > pmn->size + mn->size && !mp->commit(nmn->mem_area, size - pmn->size - mn->size)) { if (mp->uncommit) mp->uncommit(pmn->mem_area, psize); return NULL; } } #endif pmn->used = 1; memmove(pmn->mem_area, mn->mem_area, mn->size); memset(pmn->mem_area + mn->size, 0, size - mn->size); mn->used = 0; #if SM_COMMIT_SUPPORT if (size < pmn->size + mn->size) { size_t overl = size > pmn->size ? size - pmn->size : 0; if (mp->uncommit) mp->uncommit(mn->mem_area + overl, mn->size - overl); } #endif if (!nmn->used) mntruncate(mn, mn->size + nmn->size); mntruncate(pmn, size); return pmn->mem_area; } else { /* relocate */ void *new_ptr = smalloc(mp, size); if (!new_ptr) { smerror("SMALLOC: Out Of Memory on realloc, requested=%zu\n", size); return NULL; } memcpy(new_ptr, mn->mem_area, mn->size); smfree(mp, mn->mem_area); return new_ptr; } } } assert(mn->size == size); return mn->mem_area; }
/* * Main procedure. Process arguments and then * transfer control to the main command processing loop * in the routine commands. We are entered as either "ex", "edit" or "vi" * and the distinction is made here. Actually, we are "vi" if * there is a 'v' in our name, and "edit" if there is a 'd' in our * name. For edit we just diddle options; for vi we actually * force an early visual command, setting the external initev so * the q command in visual doesn't give command mode. */ int main(int ac, char **av) { #if 0 char *erpath = EXSTRINGS; #endif register char *cp; register int c; bool recov = 0; bool ivis = any('v', av[0]); bool itag = 0; bool fast = 0; #ifdef TRACE register char *tracef; #endif /* * Immediately grab the tty modes so that we wont * get messed up if an interrupt comes in quickly. */ gTTY(1); normf = tty; #if 0 /* * For debugging take files out of . if name is a.out. * If a 'd' in our name, then set options for edit. */ if (av[0][0] == 'a') erpath += 9; #endif if (ivis) { options[MAGIC].odefault = value(MAGIC) = 0; options[BEAUTIFY].odefault = value(BEAUTIFY) = 1; } else if (any('d', av[0])) { value(OPEN) = 0; value(REPORT) = 1; value(MAGIC) = 0; } /* * Open the error message file. */ draino(); #if 0 erfile = open(erpath, 0); if (erfile < 0) { flush(); exit(1); } #endif pstop(); /* * Initialize interrupt handling. */ oldhup = signal(SIGHUP, SIG_IGN); if (oldhup == SIG_DFL) signal(SIGHUP, onhup); oldquit = signal(SIGQUIT, SIG_IGN); ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL; if (signal(SIGTERM, SIG_IGN) == SIG_DFL) signal(SIGTERM, onhup); /* * Initialize end of core pointers. * Normally we avoid breaking back to fendcore after each * file since this can be expensive (much core-core copying). * If your system can scatter load processes you could do * this as ed does, saving a little core, but it will probably * not often make much difference. */ #ifdef UNIX_SBRK fendcore = (line *) sbrk(0); endcore = fendcore - 2; #else # define LINELIMIT 0x8000 fendcore = malloc(LINELIMIT * sizeof(line *)); endcore = fendcore + LINELIMIT - 1; #endif /* * Process flag arguments. */ ac--, av++; while (ac && av[0][0] == '-') { c = av[0][1]; if (c == 0) { hush = 1; value(AUTOPRINT) = 0; fast++; } else switch (c) { #ifdef TRACE case 'T': if (av[0][2] == 0) tracef = "trace"; else { tracef = tttrace; tracef[8] = av[0][2]; if (tracef[8]) tracef[9] = av[0][3]; else tracef[9] = 0; } trace = fopen(tracef, "w"); if (trace == NULL) ex_printf("Trace create error\n"); setbuf(trace, tracbuf); break; #endif #ifdef LISP case 'l': value(LISP) = 1; value(SHOWMATCH) = 1; break; #endif case 'r': recov++; break; case 't': if (ac > 1 && av[1][0] != '-') { ac--, av++; itag = 1; /* BUG: should check for too long tag. */ CP(lasttag, av[0]); } break; case 'v': globp = ""; ivis = 1; break; default: smerror("Unknown option %s\n", av[0]); break; } ac--, av++; } if (ac && av[0][0] == '+') { firstln = getn(av[0] + 1); if (firstln == 0) firstln = 20000; ac--, av++; } /* * If we are doing a recover and no filename * was given, then execute an exrecover command with * the -r option to type out the list of saved file names. * Otherwise set the remembered file name to the first argument * file name so the "recover" initial command will find it. */ if (recov) { if (ac == 0) { die++; setrupt(); execl(EXRECOVER, "exrecover", "-r", NULL); filioerr(EXRECOVER); exit(1); } CP(savedfile, *av); av++, ac--; } /* * Initialize the argument list. */ argv0 = av; argc0 = ac; args0 = av[0]; erewind(); /* * Initialize a temporary file (buffer) and * set up terminal environment. Read user startup commands. */ init(); if (setexit() == 0) { setrupt(); intty = isatty(0); if (fast || !intty) setterm("dumb"); else { gettmode(); if ((cp = getenv("TERM")) != 0) setterm(cp); if ((cp = getenv("HOME")) != 0) source(strcat(strcpy(genbuf, cp), "/.exrc"), 1); } } /* * Initial processing. Handle tag, recover, and file argument * implied next commands. If going in as 'vi', then don't do * anything, just set initev so we will do it later (from within * visual). */ if (setexit() == 0) { if (recov) globp = "recover"; else if (itag) globp = ivis ? "tag" : "tag|p"; else if (argc) globp = "next"; if (ivis) initev = globp; else if (globp) { inglobal = 1; commands(1, 1); inglobal = 0; } } /* * Vi command... go into visual. * Strange... everything in vi usually happens * before we ever "start". */ if (ivis) { /* * Don't have to be upward compatible with stupidity * of starting editing at line $. */ if (dol > zero) dot = one; globp = "visual"; if (setexit() == 0) commands(1, 1); } /* * Clear out trash in state accumulated by startup, * and then do the main command loop for a normal edit. * If you quit out of a 'vi' command by doing Q or ^\, * you also fall through to here. */ ungetchar(0); globp = 0; initev = 0; setlastchar('\n'); setexit(); commands(0, 0); cleanup(1); return 0; }
/* * Main procedure. Process arguments and then * transfer control to the main command processing loop * in the routine commands. We are entered as either "ex", "edit", "vi" * or "view" and the distinction is made here. Actually, we are "vi" if * there is a 'v' in our name, "view" is there is a 'w', and "edit" if * there is a 'd' in our name. For edit we just diddle options; * for vi we actually force an early visual command. */ int main(int ac, char **av) { #ifndef VMUNIX char *erpath = EXSTRINGS; #endif register char *cp; register int c; bool recov = 0; bool ivis; bool itag = 0; bool fast = 0; #ifdef TRACE register char *tracef; #endif /* * Immediately grab the tty modes so that we wont * get messed up if an interrupt comes in quickly. */ gTTY(1); #ifndef USG3TTY normf = tty.sg_flags; #else normf = tty; #endif ppid = getpid(); /* * Defend against d's, v's, w's, and a's in directories of * path leading to our true name. */ av[0] = tailpath(av[0]); /* * Figure out how we were invoked: ex, edit, vi, view. */ ivis = any('v', av[0]); /* "vi" */ if (any('w', av[0])) /* "view" */ value(READONLY) = 1; if (any('d', av[0])) { /* "edit" */ value(OPEN) = 0; value(REPORT) = 1; value(MAGIC) = 0; } #ifndef VMUNIX /* * For debugging take files out of . if name is a.out. */ if (av[0][0] == 'a') erpath = tailpath(erpath); #endif /* * Open the error message file. */ draino(); #ifndef VMUNIX erfile = open(erpath+4, O_RDONLY); if (erfile < 0) { erfile = open(erpath, O_RDONLY); } #endif pstop(); /* * Initialize interrupt handling. */ oldhup = signal(SIGHUP, SIG_IGN); if (oldhup == SIG_DFL) signal(SIGHUP, onhup); oldquit = signal(SIGQUIT, SIG_IGN); ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL; if (signal(SIGTERM, SIG_IGN) == SIG_DFL) signal(SIGTERM, onhup); #ifdef SIGEMT if (signal(SIGEMT, SIG_IGN) == SIG_DFL) signal(SIGEMT, onemt); #endif /* * Initialize end of core pointers. * Normally we avoid breaking back to fendcore after each * file since this can be expensive (much core-core copying). * If your system can scatter load processes you could do * this as ed does, saving a little core, but it will probably * not often make much difference. */ #ifdef UNIX_SBRK fendcore = (line *) sbrk(0); endcore = fendcore - 2; #else # define LINELIMIT 0x8000 fendcore = malloc(LINELIMIT * sizeof(line *)); endcore = fendcore + LINELIMIT - 1; #endif /* * Process flag arguments. */ ac--, av++; while (ac && av[0][0] == '-') { c = av[0][1]; if (c == 0) { hush = 1; value(AUTOPRINT) = 0; fast++; } else switch (c) { case 'R': value(READONLY) = 1; break; #ifdef TRACE case 'T': if (av[0][2] == 0) tracef = "trace"; else { tracef = tttrace; tracef[8] = av[0][2]; if (tracef[8]) tracef[9] = av[0][3]; else tracef[9] = 0; } trace = fopen(tracef, "w"); if (trace == NULL) ex_printf("Trace create error\n"); setbuf(trace, tracbuf); break; #endif #ifdef LISPCODE case 'l': value(LISP) = 1; value(SHOWMATCH) = 1; break; #endif case 'r': recov++; break; case 't': if (ac > 1 && av[1][0] != '-') { ac--, av++; itag = 1; /* BUG: should check for too long tag. */ CP(lasttag, av[0]); } break; case 'v': ivis = 1; break; case 'w': defwind = 0; if (av[0][2] == 0) defwind = 3; else for (cp = &av[0][2]; isdigit((int)*cp); cp++) defwind = 10*defwind + *cp - '0'; break; #ifdef CRYPT case 'x': /* -x: encrypted mode */ xflag = 1; break; #endif default: smerror("Unknown option %s\n", av[0]); break; } ac--, av++; } #ifdef SIGTSTP if (!hush && signal(SIGTSTP, SIG_IGN) == SIG_DFL) signal(SIGTSTP, onsusp), dosusp++; #endif if (ac && av[0][0] == '+') { firstpat = &av[0][1]; ac--, av++; } #ifdef CRYPT if(xflag){ key = getpass(KEYPROMPT); kflag = crinit(key, perm); } #endif /* * If we are doing a recover and no filename * was given, then execute an exrecover command with * the -r option to type out the list of saved file names. * Otherwise set the remembered file name to the first argument * file name so the "recover" initial command will find it. */ if (recov) { if (ac == 0) { ppid = 0; setrupt(); execl(EXRECOVER, "exrecover", "-r", NULL); filioerr(EXRECOVER); ex_exit(1); } CP(savedfile, *av); av++, ac--; } /* * Initialize the argument list. */ argv0 = av; argc0 = ac; args0 = av[0]; erewind(); /* * Initialize a temporary file (buffer) and * set up terminal environment. Read user startup commands. */ if (setexit() == 0) { setrupt(); intty = isatty(0); value(PROMPT) = intty; if ((cp = getenv("SHELL"))) CP(shell, cp); if (fast || !intty) setterm("dumb"); else { gettmode(); if ((cp = getenv("TERM")) != 0 && *cp) setterm(cp); } } if (setexit() == 0 && !fast && intty) { if ((globp = getenv("EXINIT")) && *globp) commands(1,1); else { globp = 0; if ((cp = getenv("HOME")) != 0 && *cp) source(strcat(strcpy(genbuf, cp), "/.exrc"), 1); } } init(); /* moved after prev 2 chunks to fix directory option */ /* * Initial processing. Handle tag, recover, and file argument * implied next commands. If going in as 'vi', then don't do * anything, just set initev so we will do it later (from within * visual). */ if (setexit() == 0) { if (recov) globp = "recover"; else if (itag) globp = ivis ? "tag" : "tag|p"; else if (argc) globp = "next"; if (ivis) initev = globp; else if (globp) { inglobal = 1; commands(1, 1); inglobal = 0; } } /* * Vi command... go into visual. * Strange... everything in vi usually happens * before we ever "start". */ if (ivis) { /* * Don't have to be upward compatible with stupidity * of starting editing at line $. */ if (dol > zero) dot = one; globp = "visual"; if (setexit() == 0) commands(1, 1); } /* * Clear out trash in state accumulated by startup, * and then do the main command loop for a normal edit. * If you quit out of a 'vi' command by doing Q or ^\, * you also fall through to here. */ seenprompt = 1; ungetchar(0); globp = 0; initev = 0; setlastchar('\n'); setexit(); commands(0, 0); cleanup(1); return 0; }