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 ; }
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 ; }
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 ; }
/* * regSave * Save the registry back to file */ int regSave(meRegNode *rnp, meUByte *fname, int mode) { meRegNode *rr ; meInt ss=meTRUE, level=0, lineCount, charCount ; meUInt flags ; if(mode & meREGMODE_FROOT) { /* Find the filename */ if ((fname == NULL) || (fname[0] == '\0')) { fname = NULL; if(rnp->mode & meREGMODE_FROOT) fname = rnp->value; /* Use the default file name */ if(fname == NULL) return mlwrite(MWABORT|MWPAUSE,(meUByte *)"Registry: No file name specified on save"); } flags = meRWFLAG_WRITE ; if(mode & meREGMODE_BACKUP) flags |= meRWFLAG_BACKUP ; if(mode & meREGMODE_CRYPT) { meUByte s1[meBUF_SIZE_MAX], *s2 ; int len ; meCrypt(NULL,0); meStrcpy(s1,getFileBaseName(fname)) ; len = meStrlen(s1) + 1 ; meCrypt(s1,len) ; if((s2=meUserName) == NULL) s2 = (meUByte *) "" ; meStrcpy(s1+len,s2) ; meCrypt(s1,len+meStrlen(s1+len)+1) ; flags |= meRWFLAG_CRYPT ; } /* Open the file */ if(ffWriteFileOpen(fname,flags,NULL) <= 0) return meABORT ; /* Add a recognition string to the header */ if(!(mode & meREGMODE_CRYPT)) ss = ffWriteFileWrite(12,(meUByte *) ";-!- erf -!-",1) ; } else { mode &= ~meREGMODE_CRYPT ; lineCount = 0 ; charCount = 0 ; } /* Recurse the children of the node and write to file */ rr = rnp->child ; while((ss > 0) && (rr != NULL)) { meUByte buff[4096] ; int len ; /* Print the node */ if((len = level) != 0) memset(buff,' ',len) ; buff[len++] = '"' ; len = expandexp(-1,rr->name,4096-11,len,buff,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO|meEXPAND_PRINTABLE) ; buff[len++] = '"' ; if (rr->mode & (meREGMODE_HIDDEN|meREGMODE_INTERNAL)) { buff[len++] = ' ' ; buff[len++] = '0' + (rr->mode & (meREGMODE_HIDDEN|meREGMODE_INTERNAL)) ; } if (rr->value != NULL) { buff[len++] = ' ' ; buff[len++] = '=' ; buff[len++] = ' ' ; buff[len++] = '"' ; len = expandexp(-1,rr->value,4096-4,len,buff,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO|meEXPAND_PRINTABLE) ; buff[len++] = '"' ; } /* write open '{' if it has children */ if (rr->child != NULL) { buff[len++] = ' ' ; buff[len++] = '{' ; } if((mode & meREGMODE_FROOT) == 0) { buff[len] = '\0' ; if((ss = addLine(frameCur->windowCur->dotLine,buff)) <= 0) break ; lineCount += ss ; charCount += len + 1 ; } else if((ss = ffWriteFileWrite(len,buff,1)) <= 0) break ; /* Descend child */ if (rr->child != NULL) { rr = rr->child; level++; continue; } /* Ascend the tree */ for (;;) { /* Move to sibling */ if (rr->next != NULL) { rr = rr->next; break; } if (rr->parent != NULL) { if (--level < 0) { rr = NULL; break; } rr = rr->parent; /* as we are assending the tree, at least the first 'level' * number of chars in buffer must be ' 's so just splat in the '}' */ len = level ; buff[len++] = '}' ; if((mode & meREGMODE_FROOT) == 0) { buff[len] = '\0' ; if((ss = addLine(frameCur->windowCur->dotLine,buff)) <= 0) break ; lineCount += ss ; charCount += len + 1 ; } else if((ss = ffWriteFileWrite(len,buff,1)) <= 0) break ; } } } if(mode & meREGMODE_FROOT) { if(ffWriteFileClose(fname,meRWFLAG_WRITE,NULL) <= 0) return meABORT ; rnp->mode &= ~meREGMODE_CHANGE; } else { meWindow *wp ; level = frameCur->windowCur->dotLineNo ; frameCur->bufferCur->lineCount += lineCount ; meFrameLoopBegin() ; for(wp=loopFrame->windowList; wp!=NULL; wp=wp->next) { if (wp->buffer == frameCur->bufferCur) { if(wp->dotLineNo >= level) wp->dotLineNo += lineCount ; if(wp->markLineNo >= level) wp->markLineNo += lineCount ; wp->updateFlags |= WFMAIN|WFMOVEL ; } } meFrameLoopEnd() ; frameCur->windowCur->dotOffset = 0 ; #if MEOPT_UNDO meUndoAddInsChars(charCount) ; #endif if(ss <= 0) return mlwrite(MWABORT|MWPAUSE,(meUByte *)"[Failed to write registry %s]",fname) ; } return meTRUE ; }