From 72654f620c12e7d0fb15f20c99ee85298a14250f Mon Sep 17 00:00:00 2001 From: Vincent Labrecque Date: Wed, 29 May 2002 12:41:43 +0000 Subject: add an "auto-execute" feature, that allows binding function calls to certain patterns. for example, `auto-execute "*.c" auto-indent-mode'. ok art@ --- usr.bin/mg/Makefile | 4 +- usr.bin/mg/autoexec.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++ usr.bin/mg/def.h | 7 +++- usr.bin/mg/file.c | 14 ++++++- usr.bin/mg/funmap.c | 3 +- 5 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 usr.bin/mg/autoexec.c (limited to 'usr.bin/mg') diff --git a/usr.bin/mg/Makefile b/usr.bin/mg/Makefile index f9d2ada1be0..0a31fa89dba 100644 --- a/usr.bin/mg/Makefile +++ b/usr.bin/mg/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.11 2002/02/20 22:30:54 vincent Exp $ +# $OpenBSD: Makefile,v 1.12 2002/05/29 12:41:42 vincent Exp $ PROG= mg @@ -22,7 +22,7 @@ SRCS= cinfo.c fileio.c spawn.c ttyio.c tty.c ttykbd.c \ basic.c dir.c dired.c file.c line.c match.c paragraph.c \ random.c region.c search.c version.c window.c word.c \ buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \ - macro.c main.c modes.c re_search.c funmap.c undo.c + macro.c main.c modes.c re_search.c funmap.c undo.c autoexec.c # # More or less standalone extensions. diff --git a/usr.bin/mg/autoexec.c b/usr.bin/mg/autoexec.c new file mode 100644 index 00000000000..e67107ee1df --- /dev/null +++ b/usr.bin/mg/autoexec.c @@ -0,0 +1,101 @@ +/* $OpenBSD: autoexec.c,v 1.1 2002/05/29 12:41:42 vincent Exp $ */ +/* this file is in the public domain */ +/* Author: Vincent Labrecque April 2002 */ + +#include "def.h" +#include "funmap.h" + +#include + +#include + +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; + +/* + * Return a NULL terminated array of function pointers to be called + * when we open a file that matches . The list must be free(ed) + * after use. + */ +PF * +find_autoexec(const char *fname) +{ + PF *pfl; + 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) { + have += 8; + /* + * XXX - realloc(NULL, ...) is not really + * portable + */ + pfl = realloc(pfl, (have + 1) * sizeof(PF)); + if (pfl == NULL) + panic("out of memory"); + } + pfl[used++] = ae->fp; + } + } + if (used) { + pfl[used] = NULL; + pfl = realloc(pfl, (used + 1) * sizeof(PF)); + } + 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); +} + +int +auto_execute(int f, int n) +{ + char patbuf[128], funcbuf[128]; + int s; + + if ((s = ereply("Filename pattern: ", patbuf, sizeof patbuf)) != TRUE) + return (s); + if ((s = ereply("Execute: ", funcbuf, sizeof funcbuf)) != TRUE) + return (s); + if ((s = add_autoexec(patbuf, funcbuf)) != TRUE) + return (s); + return (TRUE); +} diff --git a/usr.bin/mg/def.h b/usr.bin/mg/def.h index f899d71a2e0..8470428d992 100644 --- a/usr.bin/mg/def.h +++ b/usr.bin/mg/def.h @@ -1,4 +1,4 @@ -/* $OpenBSD: def.h,v 1.40 2002/05/29 12:32:51 vincent Exp $ */ +/* $OpenBSD: def.h,v 1.41 2002/05/29 12:41:42 vincent Exp $ */ #include @@ -589,6 +589,11 @@ int undo_add_delete(LINE *, int, int); int undo_add_change(LINE *, int, int); int undo(int, int); +/* autoexec.c X */ +int auto_execute(int, int); +PF *find_autoexec(const char *); +int add_autoexec(const char *, const char *); + /* * Externals. */ diff --git a/usr.bin/mg/file.c b/usr.bin/mg/file.c index a26922e4c22..8faabf4d8cd 100644 --- a/usr.bin/mg/file.c +++ b/usr.bin/mg/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.17 2002/05/29 12:32:51 vincent Exp $ */ +/* $OpenBSD: file.c,v 1.18 2002/05/29 12:41:42 vincent Exp $ */ /* * File commands. @@ -128,13 +128,23 @@ readin(fname) char *fname; { MGWIN *wp; - int status; + int status, i; + PF *ael; /* might be old */ if (bclear(curbp) != TRUE) return TRUE; status = insertfile(fname, fname, TRUE); + /* + * Call auto-executing function if we need to. + */ + if ((ael = find_autoexec(fname)) != NULL) { + for (i = 0; ael[i] != NULL; i++) + (*ael[i])(0, 1); + free(ael); + } + /* no change */ curbp->b_flag &= ~BFCHG; for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { diff --git a/usr.bin/mg/funmap.c b/usr.bin/mg/funmap.c index bf02c6d36a8..83436798ae5 100644 --- a/usr.bin/mg/funmap.c +++ b/usr.bin/mg/funmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: funmap.c,v 1.8 2002/05/29 12:33:36 vincent Exp $ */ +/* $OpenBSD: funmap.c,v 1.9 2002/05/29 12:41:42 vincent Exp $ */ /* * Copyright (c) 2001 Artur Grabowski . All rights reserved. * @@ -43,6 +43,7 @@ static struct funmap functnames[] = { #ifndef NO_HELP {apropos_command, "apropos",}, #endif /* !NO_HELP */ + { auto_execute, "auto-execute", }, {fillmode, "auto-fill-mode",}, {indentmode, "auto-indent-mode",}, {backchar, "backward-char",}, -- cgit v1.2.3