]> pd.if.org Git - pd_readline/blobdiff - mg/autoexec.c
Added mg from an OpenBSD mirror site. Many thanks to the OpenBSD team and the mg...
[pd_readline] / mg / autoexec.c
diff --git a/mg/autoexec.c b/mg/autoexec.c
new file mode 100644 (file)
index 0000000..ad3b08d
--- /dev/null
@@ -0,0 +1,111 @@
+/* $OpenBSD: autoexec.c,v 1.14 2007/02/08 21:40:03 kjell Exp $ */
+/* this file is in the public domain */
+/* Author: Vincent Labrecque <vincent@openbsd.org>     April 2002 */
+
+#include "def.h"
+#include "funmap.h"
+
+#include <fnmatch.h>
+
+struct autoexec {
+       SLIST_ENTRY(autoexec) next;     /* link in the linked list */
+       const char      *pattern;       /* Pattern to match to filenames */
+       PF               fp;
+};
+
+static SLIST_HEAD(, autoexec)   autos;
+static int                      ready;
+
+
+#define AUTO_GROW 8
+/*
+ * Return a NULL terminated array of function pointers to be called
+ * when we open a file that matches <fname>.  The list must be free(ed)
+ * after use.
+ */
+PF *
+find_autoexec(const char *fname)
+{
+       PF              *pfl, *npfl;
+       int              have, used;
+       struct autoexec *ae;
+
+       if (!ready)
+               return (NULL);
+
+       pfl = NULL;
+       have = 0;
+       used = 0;
+       SLIST_FOREACH(ae, &autos, next) {
+               if (fnmatch(ae->pattern, fname, 0) == 0) {
+                       if (used >= have) {
+                               npfl = realloc(pfl, (have + AUTO_GROW + 1) *
+                                   sizeof(PF));
+                               if (npfl == NULL)
+                                       panic("out of memory");
+                               pfl = npfl;
+                               have += AUTO_GROW;
+                       }
+                       pfl[used++] = ae->fp;
+               }
+       }
+       if (used)
+               pfl[used] = NULL;
+
+       return (pfl);
+}
+
+int
+add_autoexec(const char *pattern, const char *func)
+{
+       PF               fp;
+       struct autoexec *ae;
+
+       if (!ready) {
+               SLIST_INIT(&autos);
+               ready = 1;
+       }
+       fp = name_function(func);
+       if (fp == NULL)
+               return (FALSE);
+       ae = malloc(sizeof(*ae));
+       if (ae == NULL)
+               return (FALSE);
+       ae->fp = fp;
+       ae->pattern = strdup(pattern);
+       if (ae->pattern == NULL) {
+               free(ae);
+               return (FALSE);
+       }
+       SLIST_INSERT_HEAD(&autos, ae, next);
+
+       return (TRUE);
+}
+
+/*
+ * Register an auto-execute hook; that is, specify a filename pattern
+ * (conforming to the shell's filename globbing rules) and an associated
+ * function to execute when a file matching the specified pattern
+ * is read into a buffer. 
+*/
+/* ARGSUSED */
+int
+auto_execute(int f, int n)
+{
+       char    patbuf[128], funcbuf[128], *patp, *funcp;
+       int     s;
+
+       if ((patp = eread("Filename pattern: ", patbuf, sizeof(patbuf),
+           EFNEW | EFCR)) == NULL)
+               return (ABORT);
+       else if (patp[0] == '\0')
+               return (FALSE);
+       if ((funcp = eread("Execute: ", funcbuf, sizeof(funcbuf),
+           EFNEW | EFCR | EFFUNC)) == NULL)
+               return (ABORT);
+       else if (funcp[0] == '\0')
+               return (FALSE);
+       if ((s = add_autoexec(patp, funcp)) != TRUE)
+               return (s);
+       return (TRUE);
+}