int helpCommand(int f, int n) { meUByte *ss, buf[meBUF_SIZE_MAX] ; if(meGetString((meUByte *)"Help on command", MLCOMMAND, 0, buf, meBUF_SIZE_MAX-10) <= 0) return false ; ss = buf + meStrlen(buf) ; meStrcpy(ss,"(2)") ; if(findHelpItem(buf,1) > 0) return true ; meStrcpy(ss,"(3)") ; return findHelpItem(buf,0) ; }
/* Note the return value for this is: * meABORT - there was a major failure (i.e. couldn't open the file) * meFALSE - user quit * meTRUE - succeded * this is used by the exit function which ignore the major failures */ static int regTestSave(meRegNode *sroot, int flags) { /* if its not a file or not changed or the changes are to be discarded * then nothing to do */ if(!(sroot->mode & meREGMODE_FROOT) || !(sroot->mode & meREGMODE_CHANGE) || (sroot->mode & meREGMODE_DISCARD)) return meTRUE ; if((flags & 0x01) && !(sroot->mode & meREGMODE_AUTO)) { meUByte prompt[meBUF_SIZE_MAX] ; int ret ; meStrcpy(prompt,(sroot->value != NULL) ? sroot->value:sroot->name) ; meStrcat(prompt,": Save registry") ; if((ret = mlyesno(prompt)) == meABORT) { ctrlg(meFALSE,1) ; return meFALSE ; } if(ret == meFALSE) return meTRUE ; } return regSave(sroot,NULL,sroot->mode) ; }
void meUndoAddUnnarrow(meInt sln, meInt eln, meInt name, meScheme scheme, meInt markupCmd, meLine *markupLine) { meUndoNarrow *nn ; int ll ; ll = (markupLine) ? meLineGetLength(markupLine):0 ; if((frameCur->bufferCur->undoHead != NULL) && ((nn = (meUndoNarrow*) meUndoCreateNode(sizeof(meUndoNarrow)+ll)) != NULL)) { nn->type |= meUNDO_SPECIAL|meUNDO_NARROW ; nn->udata.dotp = sln ; nn->count = eln ; nn->name = name ; nn->scheme = scheme ; nn->markupCmd = markupCmd ; if(markupLine != NULL) { nn->markupFlag = meTRUE ; meStrcpy(nn->str,meLineGetText(markupLine)) ; } else nn->markupFlag = meFALSE ; } }
int nameKbdMacro(int f, int n) { meUByte buf[meBUF_SIZE_MAX] ; int ss ; if (kbdmode != meSTOP) return mlwrite(MWABORT,(meUByte *)"Macro already active!"); if(lkbdlen <= 0) return mlwrite(MWABORT,(meUByte *)"No macro defined!") ; if((ss=macroDefine(false, true)) > 0) { meStrcpy(buf,"execute-string \"") ; n = expandexp(lkbdlen,lkbdptr,meBUF_SIZE_MAX-2,16,buf,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO|meEXPAND_PRINTABLE) ; meStrcpy(buf+n,"\"") ; addLine(lpStore,buf) ; } mcStore = 0 ; lpStore = NULL ; return ss ; }
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 ; }
/* * rnodeNew * Allocate and initialise a new node */ static meRegNode * rnodeNew (meUByte *name) { meRegNode *np; /* Pointer to the node */ int len; /* Length of the string */ /* Get the length of the node name */ len = meStrlen(name) ; /* Allocate space for the node and copy in the node name */ if ((np = (meRegNode *) meMalloc(sizeof(meRegNode) + len)) == NULL) return NULL; memset(np, 0, sizeof(meRegNode)); meStrcpy(np->name,name) ; return (np); }
/* * saveRegistry * Save the registry to a file. * * Note the return value for this is: * meABORT - there was a major failure (i.e. couldn't open the file) * meFALSE - user quit * meTRUE - succeded * this is used by the exit function which ignore the major failures */ int saveRegistry (int f, int n) { meUByte filebuf [meBUF_SIZE_MAX]; meUByte rootbuf [128]; meRegNode *rnp; meInt mode ; if(n & 0x2) { rnp = root.child ; while (rnp != NULL) { if((f=regTestSave(rnp,n)) <= 0) return f ; rnp = rnp->next ; } return meTRUE ; } /* Get the input from the command line */ if(meGetString((meUByte *)"Save registry root",0, 0, rootbuf, 128) == meABORT) return meFALSE; /* Find the root */ if((rnp = regFind (&root, rootbuf)) == NULL) return mlwrite(MWCLEXEC|MWABORT,(meUByte *)"[Cannot find node %s]",rootbuf); mode = rnp->mode & ~meREGMODE_FROOT ; if((n & 4) == 0) { if(rnp->mode & meREGMODE_FROOT) meStrcpy(filebuf,rnp->value) ; else filebuf[0] = '\0' ; /* Get the filename */ if(meGetString((meUByte *)"Registry file",MLFILECASE|MLFILECASE, 0, filebuf, meBUF_SIZE_MAX) <= 0) return meFALSE ; mode |= meREGMODE_FROOT ; } return regSave(rnp,filebuf,mode) ; }
/* NOTE: Narrow undos are only added if there is already an * undo. This is so the state of the buffer will be correct * for the previous undo */ void meUndoAddNarrow(meInt sln, meInt name, meInt markupCmd, meLine *firstLine) { meUndoNarrow *nn ; int ll ; ll = (markupCmd > 0) ? meLineGetLength(firstLine):0 ; if((frameCur->bufferCur->undoHead != NULL) && ((nn = (meUndoNarrow *) meUndoCreateNode(sizeof(meUndoNarrow)+ll)) != NULL)) { nn->type |= meUNDO_SPECIAL|meUNDO_NARROW|meUNDO_NARROW_ADD ; nn->udata.dotp = sln ; nn->count = 0 ; nn->name = name ; nn->markupCmd = markupCmd ; if(markupCmd > 0) meStrcpy(nn->str,meLineGetText(firstLine)) ; } }
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 ; }
void meSetupPathsAndUser(char *progname) { meUByte *ss, buff[meBUF_SIZE_MAX] ; int ii, ll, gotUserPath ; curdir = gwd(0) ; if(curdir == NULL) /* not yet initialised so mlwrite will exit */ mlwrite(MWCURSOR|MWABORT|MWWAIT,(meUByte *)"Failed to get cwd\n") ; /* setup the $progname make it an absolute path. */ if(executableLookup(progname,evalResult)) meProgName = meStrdup(evalResult) ; else { #ifdef _ME_FREE_ALL_MEMORY /* stops problems on exit */ meProgName = meStrdup(progname) ; #else meProgName = (meUByte *)progname ; #endif } #if MEOPT_BINFS /* Initialise the built-in file system. Note for speed we only check the * header. Scope the "exepath" locally so it is discarded once the * pathname is passed to the mount and we exit the braces. */ bfsdev = bfs_mount (meProgName, BFS_CHECK_HEAD); #endif if(meUserName == NULL) { if(((ss = meGetenv ("MENAME")) == NULL) || (ss[0] == '\0')) ss = "user" ; meUserName = meStrdup(ss) ; } /* get the users home directory, user path and search path */ if(((ss = meGetenv("HOME")) == NULL) || (ss[0] == '\0')) ss = "c:/" ; fileNameSetHome(ss) ; if(((ss = meGetenv ("MEUSERPATH")) != NULL) && (ss[0] != '\0')) meUserPath = meStrdup(ss) ; if(((ss = meGetenv("MEPATH")) != NULL) && (ss[0] != '\0')) { /* explicit path set by the user, don't need to look at anything else */ searchPath = meStrdup(ss) ; /* we just need to add the $user-path to the front */ if(meUserPath != NULL) { /* check that the user path is first in the search path, if not add it */ ll = meStrlen(meUserPath) ; if(meStrncmp(searchPath,meUserPath,ll) || ((searchPath[ll] != '\0') && (searchPath[ll] != mePATH_CHAR))) { /* meMalloc will exit if it fails as ME has not finished initialising */ ss = meMalloc(ll + meStrlen(searchPath) + 2) ; meStrcpy(ss,meUserPath) ; ss[ll] = mePATH_CHAR ; meStrcpy(ss+ll+1,searchPath) ; meFree(searchPath) ; searchPath = ss ; } } } else { /* construct the search-path */ /* put the $user-path first */ if((gotUserPath = (meUserPath != NULL))) meStrcpy(evalResult,meUserPath) ; else evalResult[0] = '\0' ; ll = meStrlen(evalResult) ; /* look for the ~/jasspa directory */ if(homedir != NULL) { meStrcpy(buff,homedir) ; meStrcat(buff,"jasspa") ; if(((ll = mePathAddSearchPath(ll,evalResult,buff,&gotUserPath)) > 0) && !gotUserPath) /* as this is the user's area, use this directory unless we find * a .../<$user-name>/ directory */ gotUserPath = -1 ; } /* Get the system path of the installed macros. Use $MEINSTPATH as the * MicroEmacs standard macros */ if(((ss = meGetenv ("MEINSTALLPATH")) != NULL) && (ss[0] != '\0')) { meStrcpy(buff,ss) ; ll = mePathAddSearchPath(ll,evalResult,buff,&gotUserPath) ; } /* also check for directories in the same location as the binary */ if((meProgName != NULL) && ((ss=meStrrchr(meProgName,DIR_CHAR)) != NULL)) { ii = (((size_t) ss) - ((size_t) meProgName)) ; meStrncpy(buff,meProgName,ii) ; buff[ii] = '\0' ; ll = mePathAddSearchPath(ll,evalResult,buff,&gotUserPath) ; } if(!gotUserPath && (homedir != NULL)) { /* We have not found a user path so set ~/ as the user-path * as this is the best place for macros to write to etc. */ meStrcpy(buff,homedir) ; if(ll) { ii = meStrlen(buff) ; buff[ii++] = mePATH_CHAR ; meStrcpy(buff+ii,evalResult) ; } searchPath = meStrdup(buff) ; } else if(ll > 0) searchPath = meStrdup(evalResult) ; } if(searchPath != NULL) { fileNameConvertDirChar(searchPath) ; if(meUserPath == NULL) { /* no user path yet, take the first path from the search-path, this * should be a sensible directory to use */ if((ss = meStrchr(searchPath,mePATH_CHAR)) != NULL) *ss = '\0' ; meUserPath = meStrdup(searchPath) ; if(ss != NULL) *ss = mePATH_CHAR ; } } if(meUserPath != NULL) { fileNameConvertDirChar(meUserPath) ; ll = meStrlen(meUserPath) ; if(meUserPath[ll-1] != DIR_CHAR) { meUserPath = meRealloc(meUserPath,ll+2) ; meUserPath[ll++] = DIR_CHAR ; meUserPath[ll] = '\0' ; } } }
int meFrameChangeWidth(meFrame *frame, int ww) { /* ensure the value is in range */ if(ww < 8) ww = 8 ; else if(ww > 400) ww = 400 ; /* Already this size ?? Nothing to do */ if(frame->width == ww) return true; meFrameLoopBegin() ; /* only process frames which use the same screen window */ meFrameLoopContinue(loopFrame->mainId != frame->mainId) ; /* Only process if the window size is different from the current * window size. If we got here that is true, */ if(ww > loopFrame->widthMax) { /* Must extend the length of loopFrame->mlLine, loopFrame->mlLineStore, and all window * mode lines */ meWindow *wp ; /* Temporary window pointer */ meFrameLine *flp; /* Frame line pointer */ meFrameLine fl; /* Temporary frame line */ int ii, jj; /* Local loop counters */ meLine *ml ; meUByte *mls ; if(((ml = meLineMalloc(ww,0)) == NULL) || ((mls = meMalloc(ww+1)) == NULL)) return false ; /* Fix up the frame store by growing the lines. Do a safe * grow where by we can recover if a malloc fails. */ for (flp = loopFrame->store, ii = 0; ii < loopFrame->depthMax; ii++, flp++) { if ((fl.scheme = meMalloc(ww*(sizeof(meUByte)+sizeof(meStyle)))) == NULL) return false ; fl.text = (meUByte *) (fl.scheme+ww) ; /* Data structures allocated. Copy accross the new screen * information and pad endings with valid data. Strictly we * do not need to do this for all platforms, however if it * is safer if we make sure the data is valid. Resize is an * infrequent operation and time is not critical here */ memcpy(fl.text, flp->text, sizeof(meUByte) * loopFrame->widthMax); memcpy(fl.scheme, flp->scheme, sizeof(meScheme) * loopFrame->widthMax); jj = ww ; while(--jj >= loopFrame->widthMax) { fl.text[jj] = ' ' ; fl.scheme[jj] = globScheme ; } /* Free off old data and copy in new */ meFree (flp->scheme); flp->text = fl.text; flp->scheme = fl.scheme; } /* Fix up the window structures */ memcpy(ml,loopFrame->mlLine,meLINE_SIZE+loopFrame->mlLine->length) ; if(loopFrame->mlStatus & MLSTATUS_KEEP) { meStrcpy(mls,loopFrame->mlLine->text); loopFrame->mlColumnStore = loopFrame->mlColumn ; loopFrame->mlStatus = (loopFrame->mlStatus & ~MLSTATUS_KEEP) | MLSTATUS_RESTORE ; } else if(loopFrame->mlStatus & MLSTATUS_RESTORE) meStrcpy(mls,loopFrame->mlLineStore) ; free(loopFrame->mlLine) ; free(loopFrame->mlLineStore) ; loopFrame->video.lineArray[loopFrame->depth].line = (loopFrame->mlLine = ml) ; loopFrame->mlLineStore = mls ; wp = loopFrame->windowList ; while(wp != NULL) { if((ml = meLineMalloc(ww,0)) == NULL) return false ; memcpy(ml,wp->modeLine,meLINE_SIZE+wp->modeLine->length) ; free(wp->modeLine) ; wp->modeLine = ml ; wp = wp->next ; } loopFrame->widthMax = ww ; } loopFrame->width = ww ; /* Fix up the windows */ #if MEOPT_FRAME { meFrame *fc=frameCur ; frameCur = loopFrame ; meFrameResizeWindows(frameCur,meFRAMERESIZEWIN_WIDTH); frameCur = fc ; } #else meFrameResizeWindows(frameCur,meFRAMERESIZEWIN_WIDTH); #endif meFrameLoopEnd() ; return true ; }
/* * regRead * Open the specified registory. * Mode options are:- * * default - Exists in memory * meREGMODE_RELOAD - Delete the existing file, * meREGMODE_MERGE - Merge the existing file. */ meRegNode * regRead(meUByte *rname, meUByte *fname, int mode) { meLine hlp, *lp ; meUByte *fn ; meRegNode *rnp; /* Root node pointer */ meUInt flags ; /* Find the registry entry */ if(*rname == '/') rname++; if ((rnp = rnodeFind (&root, rname)) != NULL) { /* if not merging or reloading then we've can use the existing node */ if (!(mode & (meREGMODE_MERGE|meREGMODE_RELOAD))) goto finished; fn = rnp->value ; } else fn = NULL ; if(mode & meREGMODE_FROOT) { /* find the registry file */ /* have we been given a valid file name ? */ if ((fname != NULL) && (fname [0] != '\0')) { meUByte filename[meBUF_SIZE_MAX] ; /* Filename */ if(fileLookup(fname,(meUByte *)".erf",meFL_CHECKDOT|meFL_USESRCHPATH,filename)) fn = meStrdup(filename) ; else fn = meStrdup(fname) ; } /* else use the old file name (if there is one) else fail */ else if(fn == NULL) { mlwrite(MWABORT|MWWAIT,(meUByte *)"[No file name given to load]") ; return NULL ; } /* Load in the registry file */ flags = meRWFLAG_SILENT ; hlp.next = &hlp ; hlp.prev = &hlp ; if(mode & meREGMODE_CRYPT) { meUByte s1[meBUF_SIZE_MAX], *s2 ; int len ; meCrypt(NULL,0); meStrcpy(s1,getFileBaseName(fn)) ; 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 ; } if((ffReadFile(fn,flags,NULL,&hlp,0,0,0) == meABORT) && !(mode & meREGMODE_CREATE)) { mlwrite (MWABORT|MWWAIT,(meUByte *)"[Cannot load registry file %s]", fname); return NULL ; } lp = &hlp ; } else lp = frameCur->bufferCur->baseLine ; if ((rnp != NULL) && (mode & meREGMODE_RELOAD)) { /* Want to replace with new one. so delete old */ if(fn == rnp->value) rnp->value = NULL ; rnodeUnlink (rnp); rnodeDelete (rnp); rnp = NULL; } /* Construct the node for the file node */ if (rnp == NULL) { /* Construct the node */ if((rnp = regSet (&root, rname, NULL)) == NULL) return NULL ; rnp->mode = 0; } /* set the new file name */ if(rnp->value != fn) { meNullFree(rnp->value) ; rnp->value = fn ; } /* Now parse the registry file */ parseFile(rnp, lp) ; if(mode & meREGMODE_FROOT) meLineLoopFree(lp,0) ; finished: rnp->mode |= mode & meREGMODE_STORE_MASK ; return rnp ; }
/* * 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 ; }