]> pd.if.org Git - pd_readline/blob - mg/autoexec.c
Added mg from an OpenBSD mirror site. Many thanks to the OpenBSD team and the mg...
[pd_readline] / mg / autoexec.c
1 /* $OpenBSD: autoexec.c,v 1.14 2007/02/08 21:40:03 kjell Exp $ */
2 /* this file is in the public domain */
3 /* Author: Vincent Labrecque <vincent@openbsd.org>      April 2002 */
4
5 #include "def.h"
6 #include "funmap.h"
7
8 #include <fnmatch.h>
9
10 struct autoexec {
11         SLIST_ENTRY(autoexec) next;     /* link in the linked list */
12         const char      *pattern;       /* Pattern to match to filenames */
13         PF               fp;
14 };
15
16 static SLIST_HEAD(, autoexec)    autos;
17 static int                       ready;
18
19
20 #define AUTO_GROW 8
21 /*
22  * Return a NULL terminated array of function pointers to be called
23  * when we open a file that matches <fname>.  The list must be free(ed)
24  * after use.
25  */
26 PF *
27 find_autoexec(const char *fname)
28 {
29         PF              *pfl, *npfl;
30         int              have, used;
31         struct autoexec *ae;
32
33         if (!ready)
34                 return (NULL);
35
36         pfl = NULL;
37         have = 0;
38         used = 0;
39         SLIST_FOREACH(ae, &autos, next) {
40                 if (fnmatch(ae->pattern, fname, 0) == 0) {
41                         if (used >= have) {
42                                 npfl = realloc(pfl, (have + AUTO_GROW + 1) *
43                                     sizeof(PF));
44                                 if (npfl == NULL)
45                                         panic("out of memory");
46                                 pfl = npfl;
47                                 have += AUTO_GROW;
48                         }
49                         pfl[used++] = ae->fp;
50                 }
51         }
52         if (used)
53                 pfl[used] = NULL;
54
55         return (pfl);
56 }
57
58 int
59 add_autoexec(const char *pattern, const char *func)
60 {
61         PF               fp;
62         struct autoexec *ae;
63
64         if (!ready) {
65                 SLIST_INIT(&autos);
66                 ready = 1;
67         }
68         fp = name_function(func);
69         if (fp == NULL)
70                 return (FALSE);
71         ae = malloc(sizeof(*ae));
72         if (ae == NULL)
73                 return (FALSE);
74         ae->fp = fp;
75         ae->pattern = strdup(pattern);
76         if (ae->pattern == NULL) {
77                 free(ae);
78                 return (FALSE);
79         }
80         SLIST_INSERT_HEAD(&autos, ae, next);
81
82         return (TRUE);
83 }
84
85 /*
86  * Register an auto-execute hook; that is, specify a filename pattern
87  * (conforming to the shell's filename globbing rules) and an associated
88  * function to execute when a file matching the specified pattern
89  * is read into a buffer. 
90 */
91 /* ARGSUSED */
92 int
93 auto_execute(int f, int n)
94 {
95         char    patbuf[128], funcbuf[128], *patp, *funcp;
96         int     s;
97
98         if ((patp = eread("Filename pattern: ", patbuf, sizeof(patbuf),
99             EFNEW | EFCR)) == NULL)
100                 return (ABORT);
101         else if (patp[0] == '\0')
102                 return (FALSE);
103         if ((funcp = eread("Execute: ", funcbuf, sizeof(funcbuf),
104             EFNEW | EFCR | EFFUNC)) == NULL)
105                 return (ABORT);
106         else if (funcp[0] == '\0')
107                 return (FALSE);
108         if ((s = add_autoexec(patp, funcp)) != TRUE)
109                 return (s);
110         return (TRUE);
111 }