void meUndoAddReplaceBgn(meLine *elinep, meUShort elineo) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { meUndoNode *nn ; int len ; if(elinep == frameCur->bufferCur->baseLine) { elinep = meLineGetPrev(elinep) ; elineo = meLineGetLength(elinep) ; } if(elinep == frameCur->windowCur->dotLine) len = elineo - frameCur->windowCur->dotOffset ; else { meLine *ll = frameCur->windowCur->dotLine ; len = meLineGetLength(ll) - frameCur->windowCur->dotOffset + elineo+1 ; while((ll = meLineGetNext(ll)) != elinep) len += meLineGetLength(ll)+1 ; } if((nn = meUndoCreateNode(sizeof(meUndoNode)+len)) != NULL) { meLine *ll = frameCur->windowCur->dotLine ; meUByte *dd=nn->str, *ss=ll->text+frameCur->windowCur->dotOffset ; nn->type |= meUNDO_DELETE ; /* This should be zero because added on the end call. */ nn->count = 0; if(elinep == frameCur->windowCur->dotLine) { for(; len ; len--) *dd++ = *ss++ ; } else { len = meLineGetLength(ll) - frameCur->windowCur->dotOffset ; for(; len ; len--) *dd++ = *ss++ ; *dd++ = meCHAR_NL ; while((ll = meLineGetNext(ll)) != elinep) { len = meLineGetLength(ll) ; ss = ll->text ; for(; len ; len--) *dd++ = *ss++ ; *dd++ = meCHAR_NL ; } ss = ll->text ; for(; elineo ; elineo--) *dd++ = *ss++ ; } *dd = '\0' ; } } }
int insMacro(int f, int n) { meWindow *wp ; register meLine *lp, *slp ; meMacro *mac ; meUByte buf[meBUF_SIZE_MAX] ; meInt nol, lineNo, len ; int ii ; meStrcpy(buf,"define-macro ") ; if((mac=userGetMacro(buf+13, meBUF_SIZE_MAX-13)) == NULL) return false ; if((ii=bufferSetEdit()) <= 0) /* Check we can change the buffer */ return ii ; frameCur->windowCur->dotOffset = 0 ; slp = frameCur->windowCur->dotLine ; lineNo = frameCur->windowCur->dotLineNo ; nol = addLine(slp,buf) ; len = meStrlen(buf) + 9 ; lp = meLineGetNext(mac->hlp); /* First line. */ while (lp != mac->hlp) { nol += addLine(slp,lp->text) ; len += meLineGetLength(lp) + 1 ; lp = meLineGetNext(lp); } nol += addLine(slp,(meUByte *)"!emacro") ; frameCur->bufferCur->lineCount += nol ; meFrameLoopBegin() ; for (wp=loopFrame->windowList; wp!=NULL; wp=wp->next) { if (wp->buffer == frameCur->bufferCur) { if(wp->dotLineNo >= lineNo) wp->dotLineNo += nol ; if(wp->markLineNo >= lineNo) wp->markLineNo += nol ; wp->updateFlags |= WFMAIN|WFMOVEL ; } } meFrameLoopEnd() ; #if MEOPT_UNDO meUndoAddInsChars(len) ; #endif return true ; }
/* macroHelpDefine: * Set up a macro help definition */ int macroHelpDefine(int f, int n) { meUByte name[meBUF_SIZE_MAX] ; meUByte sect[20] ; if((lpStoreBp=helpBufferFind()) == NULL) return meABORT ; if(meGetString((meUByte *)"Enter name", MLCOMMAND, 0, name+4, meBUF_SIZE_MAX-4) <= 0) return false ; sect[0] = '\0' ; if(meGetString((meUByte *)"Enter section", 0, 0, sect, 20) == meABORT) return false ; /* and set the macro store pointers to it */ lpStore = meLineGetNext(lpStoreBp->baseLine) ; name[0] = '!' ; name[1] = (f) ? '0'+n:' ' ; if(sect[0] == '\0') { name[2] = ' ' ; name[3] = ' ' ; } else { name[2] = sect[0] ; name[3] = (sect[1] == '\0') ? ' ':sect[1] ; } addLine(lpStore,name) ; lpStoreBp->lineCount++ ; mcStore = 2 ; return true ; }
void helpBufferReset(meBuffer *bp) { meModeClear(bp->mode,MDEDIT) ; meModeSet(bp->mode,MDVIEW) ; bp->dotLine = meLineGetNext(bp->baseLine) ; bp->dotOffset = 0 ; bp->dotLineNo = 0 ; bp->vertScroll = 0 ; bp->markLine = NULL ; resetBufferWindows(bp) ; }
/* * This routine figures out the * bounds of the region in the current window, and * fills in the fields of the "meRegion" structure pointed * to by "rp". Because the dot and mark are usually very * close together, we scan outward from dot looking for * mark. This should save time. Return a standard code. * Callers of this routine should be prepared to get * an "meABORT" status; we might make this have the * conform thing later. */ int getregion(register meRegion *rp) { meLine *lp, *elp; long size; if (frameCur->windowCur->markLine == NULL) return noMarkSet() ; if(frameCur->windowCur->dotLine == frameCur->windowCur->markLine) { rp->line = frameCur->windowCur->dotLine; if (frameCur->windowCur->dotOffset < frameCur->windowCur->markOffset) { rp->offset = frameCur->windowCur->dotOffset; rp->size = (long)(frameCur->windowCur->markOffset-frameCur->windowCur->dotOffset); } else { rp->offset = frameCur->windowCur->markOffset; rp->size = (long)(frameCur->windowCur->dotOffset-frameCur->windowCur->markOffset); } rp->lineNo = frameCur->windowCur->dotLineNo; return meTRUE ; } if(frameCur->windowCur->dotLineNo < frameCur->windowCur->markLineNo) { elp = frameCur->windowCur->markLine ; lp = frameCur->windowCur->dotLine ; rp->lineNo = frameCur->windowCur->dotLineNo ; rp->offset = frameCur->windowCur->dotOffset ; size = frameCur->windowCur->dotOffset ; size = frameCur->windowCur->markOffset + meLineGetLength(lp) - size - frameCur->windowCur->dotLineNo + frameCur->windowCur->markLineNo ; } else { elp = frameCur->windowCur->dotLine ; lp = frameCur->windowCur->markLine ; rp->lineNo = frameCur->windowCur->markLineNo ; rp->offset = frameCur->windowCur->markOffset ; size = frameCur->windowCur->markOffset ; size = frameCur->windowCur->dotOffset + meLineGetLength(lp) - size + frameCur->windowCur->dotLineNo - frameCur->windowCur->markLineNo ; } rp->line = lp ; while((lp=meLineGetNext(lp)) != elp) size += meLineGetLength(lp) ; rp->size = size ; return meTRUE ; }
/* * Upper case region. Zap all of the lower * case characters in the region to upper case. Use * the region code to set the limits. Scan the buffer, * doing the changes. Call "lineSetChanged" to ensure that * redisplay is done in all buffers. Bound to * "C-X C-U". */ int upperRegion(int f, int n) { meLine *line ; int loffs ; long lline ; register char c; register int s; meRegion region; if((s=getregion(®ion)) <= 0) return (s); if((s=bufferSetEdit()) <= 0) /* Check we can change the buffer */ return s ; line = frameCur->windowCur->dotLine ; loffs = frameCur->windowCur->dotOffset ; lline = frameCur->windowCur->dotLineNo ; frameCur->windowCur->dotLine = region.line ; frameCur->windowCur->dotOffset = region.offset ; frameCur->windowCur->dotLineNo = region.lineNo ; while (region.size--) { if((c = meLineGetChar(frameCur->windowCur->dotLine, frameCur->windowCur->dotOffset)) == '\0') { frameCur->windowCur->dotLine = meLineGetNext(frameCur->windowCur->dotLine); frameCur->windowCur->dotOffset = 0; frameCur->windowCur->dotLineNo++ ; } else { if(isLower(c)) { lineSetChanged(WFMAIN); #if MEOPT_UNDO meUndoAddRepChar() ; #endif c = toggleCase(c) ; meLineSetChar(frameCur->windowCur->dotLine, frameCur->windowCur->dotOffset, c); } (frameCur->windowCur->dotOffset)++ ; } } frameCur->windowCur->dotLine = line ; frameCur->windowCur->dotOffset = loffs ; frameCur->windowCur->dotLineNo = lline ; return meTRUE ; }
void meUndoAddDelChars(meInt numChars) { meUndoNode *nn ; if(numChars < 0) numChars = 0 ; if(meModeTest(frameCur->bufferCur->mode,MDUNDO) && ((nn = meUndoCreateNode(sizeof(meUndoNode)+numChars)) != NULL)) { meLine *ll = frameCur->windowCur->dotLine ; int len ; meUByte *dd=nn->str, *ss=ll->text+frameCur->windowCur->dotOffset ; nn->type |= meUNDO_DELETE ; nn->count = 0; if((len = meLineGetLength(ll) - frameCur->windowCur->dotOffset) < numChars) { for(;;) { numChars-=len+1 ; for(; len ; len--) *dd++ = *ss++ ; ll = meLineGetNext(ll) ; ss = ll->text ; /* A bit of a bodge here to cope with the bogus last line * If the last but 1 line's '\n' is about to be removed * don't actually store the '\n' as this is automatically * added by the system */ if((numChars == 0) && (ll == frameCur->bufferCur->baseLine)) break ; *dd++ = meCHAR_NL ; if(numChars <= (len=meLineGetLength(ll))) break ; } } for(; numChars ; numChars--) *dd++ = *ss++ ; *dd = '\0' ; } }
static int yankRectangleKill(struct meKill *pklist, int soff, int notLast) { meUByte *off, *ss, *tt, *dd=NULL, cc ; int ii, jj, kk, lsspc, lespc, ldel, linsc, coff ; meKillNode *killp ; killp = pklist->kill ; while (killp != NULL) { ss = killp->data ; while(*ss != '\0') { tt = ss ; while(((cc = *ss) != '\0') && (cc != meCHAR_NL)) ss++ ; ii = (size_t) ss - (size_t) tt ; windCurLineOffsetEval(frameCur->windowCur) ; off = frameCur->windowCur->dotCharOffset->text ; ldel = lsspc = lespc = 0 ; coff = 0 ; jj = 0 ; kk = frameCur->windowCur->dotLine->length ; while(jj < kk) { if(coff == soff) break ; if((coff+off[jj]) > soff) { /* if its a tab we can remove the tab and replace with spaces */ if(meLineGetChar(frameCur->windowCur->dotLine,jj) == meCHAR_TAB) { ldel = 1 ; lespc = off[jj] - soff + coff ; } break ; } coff += off[jj++] ; } lsspc = soff - coff ; linsc = ii + lsspc + lespc - ldel ; frameCur->windowCur->dotOffset = jj ; /* Make space for the characters */ if((dd = lineMakeSpace(linsc)) == NULL) return meABORT ; lineSetChanged(WFMOVEC|WFMAIN) ; #if MEOPT_UNDO if(ldel > 0) { *dd = meCHAR_TAB ; frameCur->windowCur->dotOffset = jj ; meUndoAddDelChars(ldel) ; } #endif /* add the starting spaces */ while(--lsspc >= 0) *dd++ = ' ' ; while(--ii >= 0) *dd++ = *tt++ ; /* add the ending spaces (only if we've deleted a TAB), * preserve dd so the end point is correct */ tt = dd ; while(--lespc >= 0) *tt++ = ' ' ; #if MEOPT_UNDO if(ldel > 0) { frameCur->windowCur->dotOffset += linsc+ldel ; meUndoAddReplaceEnd(linsc+ldel) ; } else meUndoAddInsChars(linsc) ; #endif if(*ss == meCHAR_NL) ss++ ; frameCur->windowCur->dotLineNo++ ; frameCur->windowCur->dotLine = meLineGetNext(frameCur->windowCur->dotLine); frameCur->windowCur->dotOffset = 0; } killp = killp->next; } if((dd != NULL) && !notLast) { frameCur->windowCur->dotLineNo-- ; frameCur->windowCur->dotLine = meLineGetPrev(frameCur->windowCur->dotLine); frameCur->windowCur->dotOffset = ((size_t) dd - (size_t) meLineGetText(frameCur->windowCur->dotLine)) ; } return meTRUE ; }
int killRectangle(int f, int n) { meUByte *kstr ; meInt slno, elno, size ; int soff, eoff, coff, llen, dotPos ; if (frameCur->windowCur->markLine == NULL) return noMarkSet() ; if(frameCur->windowCur->dotLine == frameCur->windowCur->markLine) return killRegion(f,n) ; if(bufferSetEdit() <= 0) /* Check we can change the buffer */ return meFALSE ; eoff = getcwcol() ; /* remember we have swapped */ windowSwapDotAndMark(0,1) ; soff = getcwcol() ; if(soff > eoff) { llen = eoff ; eoff = soff ; soff = llen ; } llen = eoff - soff ; if((dotPos=frameCur->windowCur->dotLineNo > frameCur->windowCur->markLineNo)) windowSwapDotAndMark(0,1) ; slno = frameCur->windowCur->dotLineNo ; elno = frameCur->windowCur->markLineNo ; /* calculate the maximum length */ size = (elno - slno + 1) * (llen + 1) ; /* sort out the kill buffer */ if((lastflag != meCFKILL) && (thisflag != meCFKILL)) killSave(); if((kstr = killAddNode(size)) == NULL) return meFALSE ; thisflag = meCFKILL; for(;;) { meUByte *off, cc ; int lspc=0, ii, jj, kk, ll ; windCurLineOffsetEval(frameCur->windowCur) ; off = frameCur->windowCur->dotCharOffset->text ; coff = 0 ; ii = 0 ; kk = frameCur->windowCur->dotLine->length ; while(ii < kk) { if(coff == soff) break ; if((coff+off[ii]) > soff) { lspc = soff - coff ; /* as we can convert tabs to spaces, adjust the offset */ if(meLineGetChar(frameCur->windowCur->dotLine,ii) == meCHAR_TAB) off[ii] -= lspc ; coff = soff ; break ; } coff += off[ii++] ; } jj = ii ; if(coff < soff) { /* line too short to even get to the start point */ lspc = soff - coff ; memset(kstr,' ',llen) ; kstr += llen ; } else { while(jj < kk) { if(coff == eoff) break ; if((ll = off[jj]) != 0) { cc = meLineGetChar(frameCur->windowCur->dotLine,jj) ; if((coff+ll) > eoff) { /* as we can convert tabs to spaces, delete and convert */ if(cc == meCHAR_TAB) { lspc += coff + ll - eoff ; jj++ ; } break ; } coff += ll ; if(cc == meCHAR_TAB) { /* convert tabs to spaces for better column support */ do *kstr++ = ' ' ; while(--ll > 0) ; } else *kstr++ = cc ; } jj++ ; } if(coff < eoff) { /* line too short to get to the end point, fill with spaces */ coff = eoff - coff ; memset(kstr,' ',coff) ; kstr += coff ; } } *kstr++ = '\n' ; frameCur->windowCur->dotOffset = ii ; if((jj -= ii) > 0) { #if MEOPT_UNDO meUndoAddDelChars(jj) ; #endif mldelete(jj,NULL) ; } if(lspc) { if(lineInsertChar(lspc,' ') <= 0) { *kstr = '\0' ; return meFALSE ; } #if MEOPT_UNDO if(jj > 0) meUndoAddReplaceEnd(lspc) ; else meUndoAddInsChars(lspc) ; #endif } if(frameCur->windowCur->dotLineNo == elno) break ; /* move on to the next line */ frameCur->windowCur->dotLineNo++ ; frameCur->windowCur->dotLine = meLineGetNext(frameCur->windowCur->dotLine); frameCur->windowCur->dotOffset = 0; } *kstr = '\0' ; if(dotPos) windowSwapDotAndMark(0,1) ; return meTRUE ; }
/* * Copy all of the characters in the * region to the kill buffer. Don't move dot * at all. This is a bit like a kill region followed * by a yank. Bound to "M-W". */ int copyRegion(int f, int n) { meRegion region ; meLine *line; meUByte *ss, *dd ; meInt left, ii, ret ; #if MEOPT_NARROW meUShort eoffset ; meLine *markLine, *dotLine, *elp ; meInt markLineNo, dotLineNo, expandNarrows=meFALSE ; meUShort markOffset, dotOffset ; #endif if(getregion(®ion) <= 0) return meFALSE ; left = region.size ; line = region.line ; #if MEOPT_NARROW if((n & 0x01) && (frameCur->bufferCur->narrow != NULL) && (frameCur->windowCur->dotLine != frameCur->windowCur->markLine)) { /* expand narrows that are within the region */ expandNarrows = meTRUE ; dotLine = frameCur->windowCur->dotLine ; dotLineNo = frameCur->windowCur->dotLineNo ; dotOffset = frameCur->windowCur->dotOffset ; markLine = frameCur->windowCur->markLine ; markLineNo = frameCur->windowCur->markLineNo ; markOffset = frameCur->windowCur->markOffset ; if(line == dotLine) { elp = markLine ; eoffset = markOffset ; } else { elp = dotLine ; eoffset = dotOffset ; } left += meBufferRegionExpandNarrow(frameCur->bufferCur,&line,region.offset,elp,eoffset,0) ; if(((frameCur->windowCur->dotLine != dotLine) && dotOffset) || ((frameCur->windowCur->markLine != markLine) && markOffset)) { ret = mlwrite(MWABORT,(meUByte *)"[Bad region definition]") ; goto copy_region_exit ; } } #endif if(lastflag != meCFKILL) /* Kill type command. */ killSave(); if(left == 0) { thisflag = meCFKILL ; ret = meTRUE ; goto copy_region_exit ; } if((dd = killAddNode(left)) == NULL) { ret = meFALSE ; goto copy_region_exit ; } if((ii = region.offset) == meLineGetLength(line)) goto add_newline ; /* Current offset. */ ss = line->text+ii ; ii = meLineGetLength(line) - ii ; goto copy_middle ; while(left) { ss = line->text ; ii = meLineGetLength(line) ; copy_middle: /* Middle of line. */ if(ii > left) { ii = left ; left = 0 ; } else left -= ii ; while(ii--) *dd++ = *ss++ ; add_newline: if(left != 0) { *dd++ = meCHAR_NL ; line = meLineGetNext(line); left-- ; } } thisflag = meCFKILL ; ret = meTRUE ; copy_region_exit: #if MEOPT_NARROW if(expandNarrows) { meBufferCollapseNarrowAll(frameCur->bufferCur) ; frameCur->windowCur->dotLine = dotLine ; frameCur->windowCur->dotLineNo = dotLineNo ; frameCur->windowCur->dotOffset = dotOffset ; frameCur->windowCur->markLine = markLine ; frameCur->windowCur->markLineNo = markLineNo ; frameCur->windowCur->markOffset = markOffset ; } #endif return ret ; }
static int findHelpItem(meUByte *item, int silent) { meWindow *wp ; meBuffer *bp, *hbp ; meLine *lp, *elp ; int sectLen, itemLen, ii ; meUByte *ss, cc, sect[5] ; itemLen = meStrlen(item) ; if((item[itemLen-1] == ')') && ((item[(ii=itemLen-3)] == '(') || (item[(ii=itemLen-4)] == '(') )) { sectLen = itemLen-ii-2 ; meStrcpy(sect,item+ii) ; itemLen = ii ; item[itemLen] = '\0' ; } else { sectLen = 0 ; sect[0] = '\0' ; sect[1] = '\0' ; } if((hbp=helpBufferFind()) == NULL) return meABORT ; elp = hbp->baseLine ; try_again: lp = meLineGetNext(elp) ; while(lp != elp) { if((lp->text[0] == '!') && (!sectLen || ((sect[1] == lp->text[2]) && (((sectLen == 1) && (lp->text[3] == ' ')) || (sect[2] == lp->text[3]))))) { if((cc=lp->text[1]) == ' ') { ii = meLineGetLength(lp) - 4 ; if(ii != itemLen) ii = -1 ; } else { ii = cc - '0' ; if(ii > itemLen) ii = -1 ; } if((ii > 0) && !meStrncmp(item,lp->text+4,ii)) break ; } lp = meLineGetNext(lp) ; } if(lp == elp) { meMacro *mac ; if(!meModeTest(hbp->mode,MDLOCK)) { if(helpBufferLoad(hbp) == meABORT) return meABORT ; goto try_again ; } if((getMacroTypeS(item) == TKCMD) && ((ii = decode_fncname(item,1)) >= CK_MAX) && ((mac = getMacro(ii)) != NULL) && (mac->hlp->flag & meMACRO_FILE)) { meModeClear(hbp->mode,MDVIEW) ; if(mac->fname != NULL) execFile(mac->fname,0,1) ; else execFile(mac->name,0,1) ; helpBufferReset(hbp) ; if(!(mac->hlp->flag & meMACRO_FILE)) goto try_again ; } if(!silent) mlwrite(MWABORT,(meUByte *)"[Can't find help on %s%s]",item,sect); return meABORT ; } if((wp = meWindowPopup(BhelpN,BFND_CREAT|BFND_CLEAR|WPOP_USESTR,NULL)) == NULL) return false ; if((sectLen == 0) && (lp->text[2] != ' ')) { ss = sect ; *ss++ = '(' ; *ss++ = lp->text[2] ; if(lp->text[3] != ' ') *ss++ = lp->text[3] ; *ss++ = ')' ; *ss = '\0' ; } bp = wp->buffer ; /* Add the header */ { meUByte buff[meBUF_SIZE_MAX] ; sprintf((char *)buff,"\033cD%s%s\033cA",lp->text+4,sect) ; addLineToEob(bp,buff) ; addLineToEob(bp,(meUByte *)"\n\033lsMicroEmacs\033lm[Home]\033le \033lsCommand G\033lm[Commands]\033le \033lsVariable \033lm[Variables]\033le \033lsMacro Lan\033lm[Macro-Dev]\033le \033lsGlobal G\033lm[Glossary]\033le") ; memset(buff,boxChars[BCEW],78) ; buff[78] = '\n' ; buff[79] = '\0' ; addLineToEob(bp,buff) ; } while(((lp=meLineGetNext(lp)) != elp) && (lp->text[0] == '!')) ; while((lp != elp) && ((cc=lp->text[0]) != '!')) { if(cc == '|') { if(meStrcmp(item,lp->text+1)) lp = meLineGetNext(lp) ; } else if(cc == '$') { if(lp->text[1] == 'a') { if(sect[1] == '5') { meUByte line[meBUF_SIZE_MAX], *ss ; if((ss = getval(item)) != NULL) { addLineToEob(bp,(meUByte *)"\n\n\033cEVALUE\033cA\n") ; meStrcpy(line," \"") ; meStrncpy(line+5,ss,meBUF_SIZE_MAX-13) ; line[meBUF_SIZE_MAX-2] = '\0' ; meStrcat(line,"\"") ; addLineToEob(bp,line) ; } } if(sect[1] == '2') { if((ii = decode_fncname(item,1)) >= 0) { meBind *ktp ; meUByte line[meBUF_SIZE_MAX], *ss ; addLineToEob(bp,(meUByte *)"\n\n\033cEBINDINGS\033cA\n") ; meStrcpy(line," ") ; ss = line+4 ; for(ktp = &keytab[0] ; ktp->code != ME_INVALID_KEY ; ktp++) { if(ktp->index == ii) { *ss++ = '"' ; meGetStringFromKey(ktp->code,ss); ss += meStrlen(ss) ; *ss++ = '"' ; *ss++ = ' ' ; } } if(ss == line+4) meStrcpy(ss,"none") ; else *ss = '\0' ; addLineToEob(bp,line) ; } } } } else addLineToEob(bp,lp->text) ; lp = meLineGetNext(lp) ; } /* Add the footer */ { meUByte buff[meBUF_SIZE_MAX] ; buff[0] = '\n' ; memset(buff+1,boxChars[BCEW],78) ; sprintf((char *)buff+79,"\n\033lsCopyright\033lm%s\033le",meCopyright) ; addLineToEob(bp,buff) ; } bp->dotLine = meLineGetNext(bp->baseLine); bp->dotOffset = 0 ; bp->dotLineNo = 0 ; meModeClear(bp->mode,MDEDIT) ; /* don't flag this as a change */ meModeSet(bp->mode,MDVIEW) ; /* put this buffer view mode */ resetBufferWindows(bp) ; /* Update the window */ mlerase(MWCLEXEC); /* clear the mode line */ return true ; }
int meUndo(int f, int n) { if(n < -1) { #ifndef NDEBUG if(n == -4) { meUndoNode *nn ; FILE *undoFp=NULL ; if(undoFp == NULL) undoFp = fopen("undo.log","w+") ; fprintf(undoFp,"[Undo stack for %s]\n",frameCur->bufferCur->name) ; nn=frameCur->bufferCur->undoHead ; while(nn != NULL) { if(meUndoIsLineSort(nn)) { fprintf(undoFp,"Undo 0x%02x %p %ld %ld:",nn->type,nn->next, nn->udata.lineSort[0],nn->count) ; for(n=0 ; n<nn->count ; n++) fprintf(undoFp," %ld",nn->udata.lineSort[n+1]) ; fprintf(undoFp,"\n") ; } #if MEOPT_NARROW else if(meUndoIsNarrow(nn)) { meUndoNarrow *nun = (meUndoNarrow *) nn ; fprintf(undoFp,"Undo 0x%02x %p Nrrw %x %ld %ld %d [%s]\n",nun->type,nun->next, nun->name,nun->count,nun->udata.dotp,nun->markupCmd,nun->str) ; } #endif else { fprintf(undoFp,"Undo 0x%02x %p %ld (%ld,%d) [%s]\n",nn->type,nn->next,nn->count, nn->udata.dotp,nn->doto,nn->str) ; if(meUndoIsReplace(nn)) { for(n=0 ; n<nn->doto ; n++) fprintf(undoFp,"(%d,%d) ",nn->udata.pos[n][0],nn->udata.pos[n][1]) ; fprintf(undoFp,"\n") ; } } nn = nn->next ; } fprintf(undoFp,"---------------\n") ; fflush(undoFp) ; } else #endif undoContFlag++ ; } else if(!meModeTest(frameCur->bufferCur->mode,MDUNDO)) return ctrlg(meFALSE,1) ; else if(n < 0) meUndoRemove(frameCur->bufferCur) ; else { static meUndoNode *cun ; static meInt ccount ; static meUShort cdoto ; if((lastflag != meCFUNDO) && ((cun = frameCur->bufferCur->undoHead) != NULL)) { cdoto = cun->doto ; ccount = cun->count ; } for(;;) { meInt count, cont ; if((cun == NULL) || ((n <= 0) && !meModeTest(frameCur->bufferCur->mode,MDEDIT))) break ; if(bufferSetEdit() <= 0) /* Check we can change the buffer */ return meABORT ; cont=0 ; if(cun->type & meUNDO_SPECIAL) { if(meUndoIsSetEdit(cun)) { if(!(cun->type & meUNDO_UNSET_EDIT)) { autowriteremove(frameCur->bufferCur) ; meModeClear(frameCur->bufferCur->mode,MDEDIT) ; frameAddModeToWindows(WFMODE) ; /* update ALL mode lines */ } } else if(meUndoIsLineSort(cun)) { meLine *ln, *eln, **list ; meInt *lineSort, *undoInfo, dddd ; lineSort = cun->udata.lineSort ; windowGotoLine(meTRUE,(*lineSort++) + 1) ; if((list = meMalloc(cun->count * sizeof(meLine *))) == NULL) return meABORT ; undoInfo = meUndoAddLineSort(cun->count) ; eln = frameCur->windowCur->dotLine ; ln = meLineGetPrev(eln) ; for(count=0 ; count<cun->count ; eln=meLineGetNext(eln),count++) { list[*lineSort++] = eln ; eln->prev = (meLine *) count ; } for(count=0 ; count<cun->count ; ln=meLineGetNext(ln),count++) { if(undoInfo != NULL) { dddd = (meInt) list[count]->prev ; *undoInfo++ = dddd ; } ln->next = list[count] ; list[count]->prev = ln ; } ln->next = eln ; eln->prev = ln ; frameCur->windowCur->dotLine = list[0] ; meFree(list) ; } #if MEOPT_NARROW else if(meUndoIsNarrow(cun)) { meUndoNarrow *nun = (meUndoNarrow *) cun ; meInt name ; name = nun->name ; windowGotoLine(meTRUE,nun->udata.dotp+1) ; if(nun->type & meUNDO_NARROW_ADD) { meNarrow *nrrw ; nrrw = frameCur->bufferCur->narrow ; while(nrrw->name != name) nrrw = nrrw->next ; frameCur->bufferCur->dotLine = frameCur->windowCur->dotLine ; frameCur->bufferCur->dotLineNo = frameCur->windowCur->dotLineNo ; frameCur->bufferCur->dotOffset = 0 ; meBufferRemoveNarrow(frameCur->bufferCur,nrrw, (nun->markupCmd > 0) ? nun->str:NULL,1) ; } else { meLine *slp ; slp = frameCur->windowCur->dotLine ; windowGotoLine(meTRUE,ccount+1) ; meBufferCreateNarrow(frameCur->bufferCur,slp,frameCur->windowCur->dotLine, nun->udata.dotp,ccount,name,nun->scheme, (nun->markupFlag) ? nun->str:NULL,nun->markupCmd,1) ; } } #endif if(cun->type & meUNDO_CONTINUE) cont=1 ; goto meUndoNext ; } if(cun->type & meUNDO_REPLACE) { windowGotoLine(meTRUE,cun->udata.pos[cdoto-1][0]+1) ; count = cun->udata.pos[cdoto-1][1] ; if(count < 0) { cont = 1 ; count = -1 - count ; } frameCur->windowCur->dotOffset = (meUShort) count ; } else { if(cun->type & meUNDO_CONTINUE) cont = 1 ; windowGotoLine(meTRUE,cun->udata.dotp+1) ; frameCur->windowCur->dotOffset = cdoto ; } if(cun->type & meUNDO_SINGLE) { ccount-- ; count = 1 ; } else count = ccount ; if(cun->type & meUNDO_INSERT) { meWindowBackwardChar(frameCur->windowCur,count) ; if((count == 1)) meUndoAddDelChar() ; else meUndoAddDelChars(count) ; mldelete(count,NULL) ; } if(cun->type & meUNDO_DELETE) { /* When dealing with long lines this loop becomes infinitly * long because of the number of times that the line is * re-allocated - pre-allocate the line length first. In order * to reduce the processing overhead then we find the longest * strings and then add them back in in one go, this ensures * that we only ever re-allocate the line once. * Jon - 99/12/12. */ meUByte *ss, cc ; ss = cun->str ; /* Deal with a single character undo */ if(cun->type & meUNDO_SINGLE) { ss += ccount ; if((cc = *ss++) == meCHAR_NL) lineInsertNewline(meBUFINSFLAG_UNDOCALL); else if (cc != '\0') lineInsertChar(1, cc); meUndoAddInsChar() ; } else { /* Deal with a multiple character undo. */ count = bufferInsertText(ss,meBUFINSFLAG_UNDOCALL) ; if(count > 0) meUndoAddInsChars(count) ; } } if((cun->type & meUNDO_SINGLE) && (ccount > 0)) { if(cun->type & meUNDO_FORWARD) cdoto++ ; else if(cun->type & meUNDO_INSERT) cdoto-- ; } else if(cun->type & meUNDO_REPLACE) { cdoto-- ; if(!cdoto) goto meUndoNext ; } else { meUndoNext: if((cun = cun->next) != NULL) { cdoto = cun->doto ; ccount = cun->count ; } } if(!cont && (--n == 0)) break ; } thisflag = meCFUNDO ; } return meTRUE ; }
/* * Parse the file and import into the registry. */ static void parseFile(meRegNode *rnp, meLine *hlp) { meLine *lp; /* Current line pointer */ meRegNode *cnp; /* Current node pointer */ meRegNode *lnp; /* Last node pointer */ meUByte *lsp; /* Current line string pointer */ meUByte buf [meTOKENBUF_SIZE_MAX]; /* Local parse buffer */ int level = 0; /* Nesting depth */ int needValue = 0; /* Need a value flag */ cnp = rnp; /* Current node pointer */ lnp = NULL; /* No last node pointer */ lp = meLineGetNext(hlp) ; /* Initial line pointer */ lsp = lp->text ; /* Initial line string pointer */ lineNo = 1; /* Initial line number */ /* Read in the file until all processed. */ while (lp != hlp) { lsp = token(lsp,buf) ; switch (buf[0]) { case '\0': /* end of line, move to next */ case ';': /* comment to the end of line, move to next */ lp = meLineGetNext(lp) ; /* Initial line pointer */ lsp = lp->text ; /* Initial line string pointer */ lineNo++ ; /* Initial line number */ break ; case '"': if (needValue) { /* Link the value to the name */ meStrrep(&lnp->value,buf+1) ; needValue = 0; } else { /* Allocate a new node and link to the tree */ if ((lnp = rnodeFind (cnp,buf+1)) == NULL) { if ((lnp = rnodeNew (buf+1)) != NULL) rnodeLink (cnp, lnp); } } break; case '{': if ((lnp == NULL) || needValue) { mlwrite(MWWAIT,(meUByte *)"[Registry error: unexpected '{' %s:%d]", rnp->value, lineNo); return ; } level++; cnp = lnp; lnp = NULL; break; case '}': if(needValue || (level <= 0)) { mlwrite(MWWAIT,(meUByte *)"[Registry error: mismatched '}' %s:%d]", rnp->value, lineNo); return ; } cnp = cnp->parent; /* Back up a level */ lnp = NULL; level--; break; case '=': if(needValue || (lnp == NULL)) { mlwrite(MWWAIT,(meUByte *)"[Registry error: expected <name>=<value> %s:%d]", rnp->value, lineNo); return ; } needValue = 1; break; default: if(!isDigit(buf[0]) || needValue || (lnp == NULL)) { mlwrite(MWWAIT,(meUByte *)"[Registry error: unexpected token \"%s\":%d]", buf,lineNo); return ; } lnp->mode |= meAtoi(buf) ; } } /* End of file. Check for unmatched braces. */ if (level > 0) mlwrite(MWWAIT,(meUByte *)"[Registry error: mismatched '}' at EOF. %d levels open %s:%d]", level, rnp->value, lineNo); }
/* * listRegistry * List the contents of the registry. */ int listRegistry (int f, int n) { meBuffer *bp; /* Buffer pointer */ meWindow *wp; /* Window associated with buffer */ meRegNode *rnp, *cnp, *nnp ; /* Draw the nodes */ meUByte vstrbuf [meBUF_SIZE_MAX]; /* Vertical string buffer */ meUByte *bn, buf[meBUF_SIZE_MAX*2]; /* Working line buffer */ int level = 0; /* Depth in the registry */ int len; /* Length of the string */ rnp = &root; if((n & 0x02) != 0) { if(meGetString((meUByte *)"Registry Path",0, 0, buf, meBUF_SIZE_MAX) == meABORT) return meABORT; /* Find the node */ if((rnp = regFind(rnp,buf)) == NULL) return mlwrite(MWCLEXEC|MWABORT,(meUByte *)"[Cannot find node %s]",buf); } if((n & 0x01) == 0) { /* prompt for and get the new buffer name */ if((len = getBufferName((meUByte *) "Buffer", 0, 0, buf)) <= 0) return len ; bn = buf ; } else bn = BregistryN ; /* Find the buffer and vapour the old one */ if((wp = meWindowPopup(bn,BFND_CREAT|BFND_CLEAR|WPOP_USESTR,NULL)) == NULL) return meFALSE; bp = wp->buffer ; /* Point to the buffer */ /* Recurse the children of the node and write to file */ do { /* get the current node's first drawn child */ cnp = rnp->child ; while((cnp != NULL) && (cnp->mode & meREGMODE_INVISIBLE)) cnp = cnp->next ; /* get the current node's next drawn sibling */ nnp = rnp->next ; while((nnp != NULL) && (nnp->mode & meREGMODE_INVISIBLE)) nnp = nnp->next ; /* Add continuation bars if we are at a child level */ if((len = level) != 0) meStrncpy (buf, vstrbuf, len); /* Add connection bars for siblings */ if(level && (nnp != NULL)) buf [len++] = boxChars[BCNES] ; else buf [len++] = boxChars[BCNE]; /* Add continuation barss for children */ if (rnp->mode & meREGMODE_INTERNAL) buf[len++] = '!'; else if (cnp == NULL) buf[len++] = boxChars[BCEW]; else if (rnp->mode & meREGMODE_HIDDEN) buf[len++] = '+'; else buf[len++] = '-'; buf[len++] = ' '; /* Add the name of the node */ buf[len++] = '"'; len = expandexp(-1,rnp->name,(meBUF_SIZE_MAX*2)-7,len,buf,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO) ; buf[len++] = '"'; /* Add the value */ if ((rnp->value != NULL) && !(rnp->mode & meREGMODE_INTERNAL)) { buf[len++] = ' '; buf[len++] = '='; buf[len++] = ' '; buf[len++] = '"'; len = expandexp(-1,rnp->value,(meBUF_SIZE_MAX*2)-2,len,buf,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO) ; buf[len++] = '"'; } /* Add the string to the print buffer */ buf[len] = '\0'; addLineToEob(bp,buf); /* Descend child */ if((cnp != NULL) && !(rnp->mode & (meREGMODE_HIDDEN|meREGMODE_INTERNAL))) { vstrbuf[level] = (level && (nnp != NULL)) ? boxChars[BCNS] : ' ' ; level++; rnp = cnp ; continue ; } /* Ascend the tree */ while((nnp == NULL) && (--level >= 0) && ((rnp = rnp->parent) != NULL)) { /* Move to next drawn sibling */ nnp = rnp->next ; while((nnp != NULL) && (nnp->mode & meREGMODE_INVISIBLE)) nnp = nnp->next ; } rnp = nnp ; } while((level > 0) && (rnp != NULL)) ; /* Set up the buffer for display */ bp->dotLine = meLineGetNext(bp->baseLine); bp->dotOffset = 0 ; bp->dotLineNo = 0 ; meModeSet(bp->mode,MDVIEW) ; meModeClear(bp->mode,MDAUTOSV) ; meModeClear(bp->mode,MDUNDO) ; resetBufferWindows(bp) ; return meTRUE; }