NEOERR *ne_listdir_fmatch(const char *path, ULIST **files, MATCH_FUNC fmatch, void *rock) { DIR *dp; struct dirent *de; ULIST *myfiles = NULL; NEOERR *err = STATUS_OK; if (files == NULL) return nerr_raise(NERR_ASSERT, "Invalid call to ne_listdir_fmatch"); if (*files == NULL) { err = uListInit(&myfiles, 10, 0); if (err) return nerr_pass(err); } else { myfiles = *files; } if ((dp = opendir (path)) == NULL) { return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path); } while ((de = readdir (dp)) != NULL) { if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; if (fmatch != NULL && !fmatch(rock, de->d_name)) continue; err = uListAppend(myfiles, strdup(de->d_name)); if (err) break; } closedir(dp); if (err && *files == NULL) { uListDestroy(&myfiles, ULIST_FREE); } else if (*files == NULL) { *files = myfiles; } return nerr_pass(err); }
NEOERR *ne_listdir_fmatch(const char *path, ULIST **files, MATCH_FUNC fmatch, void *rock) { NEOERR *err = STATUS_OK; ULIST *myfiles = NULL; if (files == NULL) return nerr_raise(NERR_ASSERT, "Invalid call to ne_listdir_fmatch"); if (*files == NULL) { err = uListInit(&myfiles, 10, 0); if (err) return nerr_pass(err); } else { myfiles = *files; } #ifdef _MSC_VER HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA ffd; CHAR rootDir[MAX_PATH]; StringCchCopy(rootDir, MAX_PATH, path); StringCchCat(rootDir, MAX_PATH, TEXT("\\*")); hFind = FindFirstFile(rootDir, &ffd); if (hFind == INVALID_HANDLE_VALUE) return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path); do { if (!strcmp(ffd.cFileName, ".") || !strcmp(ffd.cFileName, "..")) continue; if (fmatch != NULL && !fmatch(rock, ffd.cFileName)) continue; err = uListAppend(myfiles, strdup(ffd.cFileName)); if (err) break; } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); #else DIR *dp; struct dirent *de; if ((dp = opendir (path)) == NULL) { return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path); } while ((de = readdir (dp)) != NULL) { if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; if (fmatch != NULL && !fmatch(rock, de->d_name)) continue; err = uListAppend(myfiles, strdup(de->d_name)); if (err) break; } closedir(dp); #endif if (err && *files == NULL) { uListDestroy(&myfiles, ULIST_FREE); } else if (*files == NULL) { *files = myfiles; } return nerr_pass(err); }
/* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ int execute(int c, int f, int n) { int status; fn_t execfunc; /* if the keystroke is a bound function...do it */ execfunc = getbind(c); if (execfunc != NULL) { thisflag = 0; status = (*execfunc) (f, n); lastflag = thisflag; return status; } /* * If a space was typed, fill column is defined, the argument is non- * negative, wrap mode is enabled, and we are now past fill column, * and we are not read-only, perform word wrap. */ if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 && n >= 0 && getccol(FALSE) > fillcol && (curwp->w_bufp->b_mode & MDVIEW) == FALSE) execute(META | SPEC | 'W', FALSE, 1); #if PKCODE if ((c >= 0x20 && c <= 0x7E) /* Self inserting. */ #if IBMPC || (c >= 0x80 && c <= 0xFE)) { #else #if VMS || BSD || USG /* 8BIT P.K. */ || (c >= 0xA0 && c <= 0xFFFF)) { #else ) { #endif #endif #else if ((c >= 0x20 && c <= 0xFF)) { /* Self inserting. */ #endif if (n <= 0) { /* Fenceposts. */ lastflag = 0; return n < 0 ? FALSE : TRUE; } thisflag = 0; /* For the future. */ /* if we are in overwrite mode, not at eol, and next char is not a tab or we are at a tab stop, delete a char forword */ if (curwp->w_bufp->b_mode & MDOVER && curwp->w_doto < curwp->w_dotp->l_used && (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' || (curwp->w_doto) % 8 == 7)) ldelchar(1, FALSE); /* do the appropriate insertion */ if (c == '}' && (curbp->b_mode & MDCMOD) != 0) status = insbrace(n, c); else if (c == '#' && (curbp->b_mode & MDCMOD) != 0) status = inspound(); else status = linsert(n, c); #if CFENCE /* check for CMODE fence matching */ if ((c == '}' || c == ')' || c == ']') && (curbp->b_mode & MDCMOD) != 0) fmatch(c); #endif /* check auto-save mode */ if (curbp->b_mode & MDASAVE) if (--gacount == 0) { /* and save the file if needed */ upscreen(FALSE, 0); filesave(FALSE, 0); gacount = gasave; } lastflag = thisflag; return status; } TTbeep(); mlwrite("(Key not bound)"); /* complain */ lastflag = 0; /* Fake last flags. */ return FALSE; } /* * Fancy quit command, as implemented by Norm. If the any buffer has * changed do a write on that buffer and exit emacs, otherwise simply exit. */ int quickexit(int f, int n) { struct buffer *bp; /* scanning pointer to buffers */ struct buffer *oldcb; /* original current buffer */ int status; oldcb = curbp; /* save in case we fail */ bp = bheadp; while (bp != NULL) { if ((bp->b_flag & BFCHG) != 0 /* Changed. */ && (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */ && (bp->b_flag & BFINVS) == 0) { /* Real. */ curbp = bp; /* make that buffer cur */ mlwrite("(Saving %s)", bp->b_fname); #if PKCODE #else mlwrite("\n"); #endif if ((status = filesave(f, n)) != TRUE) { curbp = oldcb; /* restore curbp */ return status; } } bp = bp->b_bufp; /* on to the next buffer */ } quit(f, n); /* conditionally quit */ return TRUE; } static void emergencyexit(int signr) { quickexit(FALSE, 0); quit(TRUE, 0); } /* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int quit(int f, int n) { int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ || (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE) { #if (FILOCK && BSD) || SVR4 if (lockrel() != TRUE) { TTputc('\n'); TTputc('\r'); TTclose(); TTkclose(); exit(1); } #endif vttidy(); if (f) exit(n); else exit(GOOD); } mlwrite(""); return s; } /* * Begin a keyboard macro. * Error if not at the top level in keyboard processing. Set up variables and * return. */ int ctlxlp(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } mlwrite("(Start macro)"); kbdptr = &kbdm[0]; kbdend = kbdptr; kbdmode = RECORD; return TRUE; } /* * End keyboard macro. Check for the same limit conditions as the above * routine. Set up the variables and return to the caller. */ int ctlxrp(int f, int n) { if (kbdmode == STOP) { mlwrite("%%Macro not active"); return FALSE; } if (kbdmode == RECORD) { mlwrite("(End macro)"); kbdmode = STOP; } return TRUE; } /* * Execute a macro. * The command argument is the number of times to loop. Quit as soon as a * command gets an error. Return TRUE if all ok, else FALSE. */ int ctlxe(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } if (n <= 0) return TRUE; kbdrep = n; /* remember how many times to execute */ kbdmode = PLAY; /* start us in play mode */ kbdptr = &kbdm[0]; /* at the beginning */ return TRUE; } /* * Abort. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Sometimes called as a routine, to do general aborting of stuff. */ int ctrlg(int f, int n) { TTbeep(); kbdmode = STOP; mlwrite("(Aborted)"); return ABORT; }