static Lisp_Object inotifyevent_to_event (Lisp_Object watch, struct inotify_event const *ev) { Lisp_Object name; uint32_t mask; CONS_TO_INTEGER (Fnth (make_number (3), watch), uint32_t, mask); if (! (mask & ev->mask)) return Qnil; if (ev->len > 0) { size_t const len = strlen (ev->name); name = make_unibyte_string (ev->name, min (len, ev->len)); name = DECODE_FILE (name); } else name = XCAR (XCDR (watch)); return list2 (list4 (Fcons (INTEGER_TO_CONS (ev->wd), XCAR (watch)), mask_to_aspects (ev->mask), name, INTEGER_TO_CONS (ev->cookie)), Fnth (make_number (2), watch)); }
/* Generate a list from the directory_files_internal output. Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */ Lisp_Object kqueue_directory_listing (Lisp_Object directory_files) { Lisp_Object dl, result = Qnil; for (dl = directory_files; ! NILP (dl); dl = XCDR (dl)) { /* We ignore "." and "..". */ if ((strcmp (".", SSDATA (XCAR (XCAR (dl)))) == 0) || (strcmp ("..", SSDATA (XCAR (XCAR (dl)))) == 0)) continue; result = Fcons (list5 (/* inode. */ Fnth (make_number (11), XCAR (dl)), /* filename. */ XCAR (XCAR (dl)), /* last modification time. */ Fnth (make_number (6), XCAR (dl)), /* last status change time. */ Fnth (make_number (7), XCAR (dl)), /* size. */ Fnth (make_number (8), XCAR (dl))), result); } return result; }
/* Generate a file notification event. */ static void kqueue_generate_event (Lisp_Object watch_object, Lisp_Object actions, Lisp_Object file, Lisp_Object file1) { Lisp_Object flags, action, entry; struct input_event event; /* Check, whether all actions shall be monitored. */ flags = Fnth (make_number (2), watch_object); action = actions; do { if (NILP (action)) break; entry = XCAR (action); if (NILP (Fmember (entry, flags))) { action = XCDR (action); actions = Fdelq (entry, actions); } else action = XCDR (action); } while (1); /* Store it into the input event queue. */ if (! NILP (actions)) { EVENT_INIT (event); event.kind = FILE_NOTIFY_EVENT; event.frame_or_window = Qnil; event.arg = list2 (Fcons (XCAR (watch_object), Fcons (actions, NILP (file1) ? Fcons (file, Qnil) : list2 (file, file1))), Fnth (make_number (3), watch_object)); kbd_buffer_store_event (&event); } }
void Feighth(CL_FORM *base) { LOAD_SMALLFIXNUM(7, ARG(1)); COPY(ARG(0), ARG(2)); Fnth(ARG(1)); COPY(ARG(1), ARG(0)); }
void Fseventh(CL_FORM *base) { LOAD_FIXNUM(ARG(1), 6, ARG(1)); COPY(ARG(0), ARG(2)); Fnth(ARG(1)); COPY(ARG(1), ARG(0)); }
/* This is the callback function for arriving input on kqueuefd. It shall create a Lisp event, and put it into the Emacs input queue. */ static void kqueue_callback (int fd, void *data) { for (;;) { struct kevent kev; static const struct timespec nullts = { 0, 0 }; Lisp_Object descriptor, watch_object, file, actions; /* Read one event. */ int ret = kevent (kqueuefd, NULL, 0, &kev, 1, &nullts); if (ret < 1) { /* All events read. */ return; } /* Determine descriptor and file name. */ descriptor = make_number (kev.ident); watch_object = assq_no_quit (descriptor, watch_list); if (CONSP (watch_object)) file = XCAR (XCDR (watch_object)); else continue; /* Determine event actions. */ actions = Qnil; if (kev.fflags & NOTE_DELETE) actions = Fcons (Qdelete, actions); if (kev.fflags & NOTE_WRITE) { /* Check, whether this is a directory event. */ if (NILP (Fnth (make_number (4), watch_object))) actions = Fcons (Qwrite, actions); else kqueue_compare_dir_list (watch_object); } if (kev.fflags & NOTE_EXTEND) actions = Fcons (Qextend, actions); if (kev.fflags & NOTE_ATTRIB) actions = Fcons (Qattrib, actions); if (kev.fflags & NOTE_LINK) actions = Fcons (Qlink, actions); /* It would be useful to know the target of the rename operation. At this point, it is not possible. Happens only when the upper directory is monitored. */ if (kev.fflags & NOTE_RENAME) actions = Fcons (Qrename, actions); /* Create the event. */ if (! NILP (actions)) kqueue_generate_event (watch_object, actions, file, Qnil); /* Cancel monitor if file or directory is deleted or renamed. */ if (kev.fflags & (NOTE_DELETE | NOTE_RENAME)) Fkqueue_rm_watch (descriptor); } return; }
void Felt(CL_FORM *base) { if(CL_LISTP(ARG(0))) { COPY(ARG(1), ARG(2)); COPY(ARG(0), ARG(3)); Fnth(ARG(2)); COPY(ARG(2), ARG(0)); } else { Frow_major_aref(ARG(0)); } }
static Lisp_Object inotifyevent_to_event (Lisp_Object watch_object, struct inotify_event const *ev) { Lisp_Object name = Qnil; if (ev->len > 0) { size_t const len = strlen (ev->name); name = make_unibyte_string (ev->name, min (len, ev->len)); name = DECODE_FILE (name); } else name = XCAR (XCDR (watch_object)); return list2 (list4 (make_watch_descriptor (ev->wd), mask_to_aspects (ev->mask), name, make_number (ev->cookie)), Fnth (make_number (2), watch_object)); }
static int get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, int partial_p) { Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm; int ln1 = 0, ln2 = 0; int ix1 = right_p; int ix2 = ix1 + (partial_p ? 2 : 0); /* Lookup in buffer-local fringe-indicator-alist before global alist. Elements are: BITMAP -- use for all (L R) -- use for left right (whether partial or not) (L R PL PR) -- use for left right partial-left partial-right If any value in local binding is not present or t, use global value. If partial, lookup partial bitmap in default value if not found here. If not partial, or no partial spec is present, use non-partial bitmap. */ if ((cmap = BVAR (XBUFFER (w->buffer), fringe_indicator_alist)), !NILP (cmap)) { bm1 = Fassq (bitmap, cmap); if (CONSP (bm1)) { if ((bm1 = XCDR (bm1)), NILP (bm1)) return NO_FRINGE_BITMAP; if (CONSP (bm1)) { ln1 = XINT (Flength (bm1)); if (partial_p) { if (ln1 > ix2) { bm = Fnth (make_number (ix2), bm1); if (!EQ (bm, Qt)) goto found; } } else { if (ln1 > ix1) { bm = Fnth (make_number (ix1), bm1); if (!EQ (bm, Qt)) goto found; } } } else if ((bm = bm1, !EQ (bm, Qt))) goto found; } } if (!EQ (cmap, BVAR (&buffer_defaults, fringe_indicator_alist)) && !NILP (BVAR (&buffer_defaults, fringe_indicator_alist))) { bm2 = Fassq (bitmap, BVAR (&buffer_defaults, fringe_indicator_alist)); if (CONSP (bm2)) { if ((bm2 = XCDR (bm2)), !NILP (bm2)) { if (CONSP (bm2)) { ln2 = XINT (Flength (bm2)); if (partial_p) { if (ln2 > ix2) { bm = Fnth (make_number (ix2), bm2); if (!EQ (bm, Qt)) goto found; } } } } } } if (ln1 > ix1) { bm = Fnth (make_number (ix1), bm1); if (!EQ (bm, Qt)) goto found; } if (ln2 > ix1) { bm = Fnth (make_number (ix1), bm2); if (!EQ (bm, Qt)) goto found; return NO_FRINGE_BITMAP; } else if ((bm = bm2, NILP (bm))) return NO_FRINGE_BITMAP; found: return lookup_fringe_bitmap (bm); }
/* This compares two directory listings in case of a `write' event for a directory. Generate resulting file notification events. The old directory listing is retrieved from watch_object, it will be replaced by the new directory listing at the end of this function. */ static void kqueue_compare_dir_list (Lisp_Object watch_object) { Lisp_Object dir, pending_dl, deleted_dl; Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl; dir = XCAR (XCDR (watch_object)); pending_dl = Qnil; deleted_dl = Qnil; old_directory_files = Fnth (make_number (4), watch_object); old_dl = kqueue_directory_listing (old_directory_files); /* When the directory is not accessible anymore, it has been deleted. */ if (NILP (Ffile_directory_p (dir))) { kqueue_generate_event (watch_object, Fcons (Qdelete, Qnil), dir, Qnil); return; } new_directory_files = directory_files_internal (dir, Qnil, Qnil, Qnil, 1, Qnil); new_dl = kqueue_directory_listing (new_directory_files); /* Parse through the old list. */ dl = old_dl; while (1) { Lisp_Object old_entry, new_entry, dl1; if (NILP (dl)) break; /* Search for an entry with the same inode. */ old_entry = XCAR (dl); new_entry = assq_no_quit (XCAR (old_entry), new_dl); if (! NILP (Fequal (old_entry, new_entry))) { /* Both entries are identical. Nothing to do. */ new_dl = Fdelq (new_entry, new_dl); goto the_end; } /* Both entries have the same inode. */ if (! NILP (new_entry)) { /* Both entries have the same file name. */ if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { /* Modification time has been changed, the file has been written. */ if (NILP (Fequal (Fnth (make_number (2), old_entry), Fnth (make_number (2), new_entry)))) kqueue_generate_event (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil); /* Status change time has been changed, the file attributes have changed. */ if (NILP (Fequal (Fnth (make_number (3), old_entry), Fnth (make_number (3), new_entry)))) kqueue_generate_event (watch_object, Fcons (Qattrib, Qnil), XCAR (XCDR (old_entry)), Qnil); } else { /* The file has been renamed. */ kqueue_generate_event (watch_object, Fcons (Qrename, Qnil), XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); deleted_dl = Fcons (new_entry, deleted_dl); } new_dl = Fdelq (new_entry, new_dl); goto the_end; } /* Search, whether there is a file with the same name but another inode. */ for (dl1 = new_dl; ! NILP (dl1); dl1 = XCDR (dl1)) { new_entry = XCAR (dl1); if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { pending_dl = Fcons (new_entry, pending_dl); new_dl = Fdelq (new_entry, new_dl); goto the_end; } } /* Check, whether this a pending file. */ new_entry = assq_no_quit (XCAR (old_entry), pending_dl); if (NILP (new_entry)) { /* Check, whether this is an already deleted file (by rename). */ for (dl1 = deleted_dl; ! NILP (dl1); dl1 = XCDR (dl1)) { new_entry = XCAR (dl1); if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { deleted_dl = Fdelq (new_entry, deleted_dl); goto the_end; } } /* The file has been deleted. */ kqueue_generate_event (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil); } else { /* The file has been renamed. */ kqueue_generate_event (watch_object, Fcons (Qrename, Qnil), XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); pending_dl = Fdelq (new_entry, pending_dl); } the_end: dl = XCDR (dl); old_dl = Fdelq (old_entry, old_dl); } /* Parse through the resulting new list. */ dl = new_dl; while (1) { Lisp_Object entry; if (NILP (dl)) break; /* A new file has appeared. */ entry = XCAR (dl); kqueue_generate_event (watch_object, Fcons (Qcreate, Qnil), XCAR (XCDR (entry)), Qnil); /* Check size of that file. */ Lisp_Object size = Fnth (make_number (4), entry); if (FLOATP (size) || (XINT (size) > 0)) kqueue_generate_event (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil); dl = XCDR (dl); new_dl = Fdelq (entry, new_dl); } /* Parse through the resulting pending_dl list. */ dl = pending_dl; while (1) { Lisp_Object entry; if (NILP (dl)) break; /* A file is still pending. Assume it was a write. */ entry = XCAR (dl); kqueue_generate_event (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil); dl = XCDR (dl); pending_dl = Fdelq (entry, pending_dl); } /* At this point, old_dl, new_dl and pending_dl shall be empty. deleted_dl might not be empty when there was a rename to a nonexistent file. Let's make a check for this (might be removed once the code is stable). */ if (! NILP (old_dl)) report_file_error ("Old list not empty", old_dl); if (! NILP (new_dl)) report_file_error ("New list not empty", new_dl); if (! NILP (pending_dl)) report_file_error ("Pending events list not empty", pending_dl); // if (! NILP (deleted_dl)) // report_file_error ("Deleted events list not empty", deleted_dl); /* Replace old directory listing with the new one. */ XSETCDR (Fnthcdr (make_number (3), watch_object), Fcons (new_directory_files, Qnil)); return; }
static void fix_command (Lisp_Object input, Lisp_Object values) { /* FIXME: Instead of this ugly hack, we should provide a way for an interactive spec to return an expression/function that will re-build the args without user intervention. */ if (CONSP (input)) { Lisp_Object car; car = XCAR (input); /* Skip through certain special forms. */ while (EQ (car, Qlet) || EQ (car, Qletx) || EQ (car, Qsave_excursion) || EQ (car, Qprogn)) { while (CONSP (XCDR (input))) input = XCDR (input); input = XCAR (input); if (!CONSP (input)) break; car = XCAR (input); } if (EQ (car, Qlist)) { Lisp_Object intail, valtail; for (intail = Fcdr (input), valtail = values; CONSP (valtail); intail = Fcdr (intail), valtail = XCDR (valtail)) { Lisp_Object elt; elt = Fcar (intail); if (CONSP (elt)) { Lisp_Object presflag, carelt; carelt = XCAR (elt); /* If it is (if X Y), look at Y. */ if (EQ (carelt, Qif) && EQ (Fnthcdr (make_number (3), elt), Qnil)) elt = Fnth (make_number (2), elt); /* If it is (when ... Y), look at Y. */ else if (EQ (carelt, Qwhen)) { while (CONSP (XCDR (elt))) elt = XCDR (elt); elt = Fcar (elt); } /* If the function call we're looking at is a special preserved one, copy the whole expression for this argument. */ if (CONSP (elt)) { presflag = Fmemq (Fcar (elt), preserved_fns); if (!NILP (presflag)) Fsetcar (valtail, Fcar (intail)); } } } } } }
repv gh_list_ref(repv ls, repv k) { return Fnth (k, ls); }