From 3ef2ba8fca2930a61ccc80ffcccb6342215b3fb2 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 6 Apr 2014 03:55:25 +0200 Subject: [PATCH] Added a generic tool to implement filters (not fully functional yet) --- Makefile | 7 ++- po/POTFILES | 1 + project.conf | 2 +- src/Makefile | 7 ++- src/editor.c | 15 +++++ src/filter.c | 78 ++++++++++++++++++++++++ src/filter.h | 27 +++++++++ src/main.c | 59 ++----------------- src/project.conf | 10 +++- tools/Makefile | 41 +++++++++++++ tools/filter.c | 144 +++++++++++++++++++++++++++++++++++++++++++++ tools/project.conf | 11 ++++ 12 files changed, 342 insertions(+), 60 deletions(-) create mode 100644 src/filter.c create mode 100644 src/filter.h create mode 100644 tools/Makefile create mode 100644 tools/filter.c create mode 100644 tools/project.conf diff --git a/Makefile b/Makefile index b8a86de..d0cc851 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PACKAGE = Editor VERSION = 0.2.1 -SUBDIRS = data doc po src +SUBDIRS = data doc po src tools RM = rm -f LN = ln -f TAR = tar -czvf @@ -38,11 +38,16 @@ dist: $(PACKAGE)-$(VERSION)/po/project.conf \ $(PACKAGE)-$(VERSION)/src/callbacks.c \ $(PACKAGE)-$(VERSION)/src/editor.c \ + $(PACKAGE)-$(VERSION)/src/filter.c \ $(PACKAGE)-$(VERSION)/src/main.c \ $(PACKAGE)-$(VERSION)/src/Makefile \ $(PACKAGE)-$(VERSION)/src/callbacks.h \ $(PACKAGE)-$(VERSION)/src/editor.h \ + $(PACKAGE)-$(VERSION)/src/filter.h \ $(PACKAGE)-$(VERSION)/src/project.conf \ + $(PACKAGE)-$(VERSION)/tools/filter.c \ + $(PACKAGE)-$(VERSION)/tools/Makefile \ + $(PACKAGE)-$(VERSION)/tools/project.conf \ $(PACKAGE)-$(VERSION)/Makefile \ $(PACKAGE)-$(VERSION)/COPYING \ $(PACKAGE)-$(VERSION)/config.h \ diff --git a/po/POTFILES b/po/POTFILES index d0922c3..1aa3d88 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,3 +1,4 @@ ../src/callbacks.c ../src/editor.c ../src/main.c +../tools/filter.c diff --git a/project.conf b/project.conf index dcdce71..8abab08 100644 --- a/project.conf +++ b/project.conf @@ -2,5 +2,5 @@ package=Editor version=0.2.1 config=h,sh -subdirs=data,doc,po,src +subdirs=data,doc,po,src,tools dist=Makefile,COPYING,config.h,config.sh diff --git a/src/Makefile b/src/Makefile index 11f881d..4c91ec6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,7 @@ INSTALL = install all: $(TARGETS) -editor_OBJS = callbacks.o editor.o main.o +editor_OBJS = callbacks.o editor.o filter.o main.o editor_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) editor_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) @@ -31,7 +31,10 @@ callbacks.o: callbacks.c editor.h callbacks.h editor.o: editor.c callbacks.h editor.h ../config.h $(CC) $(editor_CFLAGS) -c editor.c -main.o: main.c +filter.o: filter.c filter.h + $(CC) $(editor_CFLAGS) -c filter.c + +main.o: main.c filter.h $(CC) $(editor_CFLAGS) -c main.c clean: diff --git a/src/editor.c b/src/editor.c index 10e0c71..7bc69dc 100644 --- a/src/editor.c +++ b/src/editor.c @@ -39,6 +39,9 @@ static char const _license[] = /* Editor */ /* private */ /* constants */ +#ifndef PROGNAME +# define PROGNAME "editor" +#endif #define EDITOR_CONFIG_FILE ".editor" #define EDITOR_DEFAULT_FONT "Monospace 9" @@ -617,14 +620,20 @@ int editor_confirm(Editor * editor, char const * message, ...) /* editor_error */ +static int _error_text(char const * message, int ret); + int editor_error(Editor * editor, char const * message, int ret) { #if GTK_CHECK_VERSION(2, 18, 0) + if(editor == NULL) + return _error_text(message, ret); gtk_label_set_text(GTK_LABEL(editor->infobar_label), message); gtk_widget_show(editor->infobar); #else GtkWidget * dialog; + if(editor == NULL) + return _error_text(message, ret); dialog = gtk_message_dialog_new(GTK_WINDOW(editor->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, @@ -641,6 +650,12 @@ int editor_error(Editor * editor, char const * message, int ret) return ret; } +static int _error_text(char const * message, int ret) +{ + fprintf(stderr, "%s: %s\n", PROGNAME, message); + return ret; +} + /* editor_close */ int editor_close(Editor * editor) diff --git a/src/filter.c b/src/filter.c new file mode 100644 index 0000000..38510a2 --- /dev/null +++ b/src/filter.c @@ -0,0 +1,78 @@ +/* $Id$ */ +/* Copyright (c) 2014 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Editor */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include +#include +#include "filter.h" + + +/* public */ +/* functions */ +/* filter_read */ +int filter_read(int fd, char const * template) +{ + int ret; + FILE * fp; + char buf[BUFSIZ]; + size_t s; + + if((fp = fdopen(fd, "w")) == NULL) + { + unlink(template); + return -error_set_code(1, "%s: %s", "stdin", strerror(errno)); + } + /* read from the standard input */ + for(ret = 0; ret == 0 && (s = fread(buf, sizeof(*buf), sizeof(buf) + / sizeof(*buf), stdin)) > 0;) + /* write to the temporary file */ + if(fwrite(buf, sizeof(*buf), s, fp) != s) + ret = -error_set_code(1, "%s: %s", template, + strerror(errno)); + if(ret == 0 && !feof(stdin)) + ret = -error_set_code(1, "%s: %s", "stdin", strerror(errno)); + if(fclose(fp) != 0 && ret == 0) + ret = -error_set_code(1, "%s: %s", template, strerror(errno)); + return ret; +} + + +/* filter_write */ +int filter_write(char const * template) +{ + int ret; + FILE * fp; + char buf[BUFSIZ]; + size_t s; + + if((fp = fopen(template, "r")) == NULL) + return -error_set_code(1, "%s: %s", template, strerror(errno)); + /* read from the temporary file */ + for(ret = 0; (s = fread(buf, sizeof(*buf), sizeof(buf) / sizeof(*buf), + fp)) > 0;) + /* write to the standard output */ + if(fwrite(buf, sizeof(*buf), s, stdout) != s) + ret = -error_set_code(1, "%s: %s", "stdout", + strerror(errno)); + if(ret == 0 && !feof(fp)) + ret = -error_set_code(1, "%s: %s", template, strerror(errno)); + if(fclose(fp) != 0 && ret == 0) + ret = -error_set_code(1, "%s: %s", template, strerror(errno)); + return ret; +} diff --git a/src/filter.h b/src/filter.h new file mode 100644 index 0000000..26dbe46 --- /dev/null +++ b/src/filter.h @@ -0,0 +1,27 @@ +/* $Id$ */ +/* Copyright (c) 2014 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Editor */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#ifndef EDITOR_FILTER_H +# define EDITOR_FILTER_H + + +/* public */ +/* functions */ +int filter_read(int fd, char const * template); +int filter_write(char const * template); + +#endif /* !EDITOR_FILTER_H */ diff --git a/src/main.c b/src/main.c index 199ef50..c543f22 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ #include #include #include +#include "filter.h" #include "editor.h" #include "../config.h" #define _(string) gettext(string) @@ -40,7 +41,7 @@ #endif -/* editor */ +/* Editor */ /* private */ /* prototypes */ static int _editor(EditorPrefs * prefs, char const * filename); @@ -67,13 +68,10 @@ static int _editor(EditorPrefs * prefs, char const * filename) /* editor_filter */ -static int _filter_read(int fd, char const * template); -static int _filter_write(char const * template); - static int _editor_filter(EditorPrefs * prefs) { int ret = 0; - char template[] = "/tmp/editor.XXXXXX"; + char template[] = "/tmp/" PROGNAME ".XXXXXX"; int fd; #ifdef DEBUG @@ -86,9 +84,9 @@ static int _editor_filter(EditorPrefs * prefs) fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, template); #endif /* write to and from the temporary file */ - if((ret = _filter_read(fd, template)) == 0 + if((ret = filter_read(fd, template)) == 0 && (ret = _editor(prefs, template)) == 0) - ret = _filter_write(template); + ret = filter_write(template); /* remove the temporary file */ if(unlink(template) != 0) /* we can otherwise ignore this error */ @@ -96,53 +94,6 @@ static int _editor_filter(EditorPrefs * prefs) return ret; } -static int _filter_read(int fd, char const * template) -{ - int ret; - FILE * fp; - char buf[BUFSIZ]; - size_t s; - - if((fp = fdopen(fd, "w")) == NULL) - { - unlink(template); - return -_error("stdin", 1); - } - /* read from the standard input */ - for(ret = 0; ret == 0 && (s = fread(buf, sizeof(*buf), sizeof(buf) - / sizeof(*buf), stdin)) > 0;) - /* write to the temporary file */ - if(fwrite(buf, sizeof(*buf), s, fp) != s) - ret = -_error(template, 1); - if(ret == 0 && !feof(stdin)) - ret = -_error("stdin", 1); - if(fclose(fp) != 0 && ret == 0) - ret = -_error(template, 1); - return ret; -} - -static int _filter_write(char const * template) -{ - int ret; - FILE * fp; - char buf[BUFSIZ]; - size_t s; - - if((fp = fopen(template, "r")) == NULL) - return -_error(template, 1); - /* read from the temporary file */ - for(ret = 0; (s = fread(buf, sizeof(*buf), sizeof(buf) / sizeof(*buf), - fp)) > 0;) - /* write to the standard output */ - if(fwrite(buf, sizeof(*buf), s, stdout) != s) - ret = -_error("stdout", 1); - if(ret == 0 && !feof(fp)) - ret = -_error(template, 1); - if(fclose(fp) != 0 && ret == 0) - ret = -_error(template, 1); - return ret; -} - /* error */ static int _error(char const * message, int ret) diff --git a/src/project.conf b/src/project.conf index 72ee6cc..fe39159 100644 --- a/src/project.conf +++ b/src/project.conf @@ -4,11 +4,11 @@ cflags_force=-W `pkg-config --cflags libDesktop` cflags=-Wall -g -O2 -pedantic ldflags_force=`pkg-config --libs libDesktop` -lintl ldflags= -dist=Makefile,callbacks.h,editor.h +dist=Makefile,callbacks.h,editor.h,filter.h [editor] type=binary -sources=callbacks.c,editor.c,main.c +sources=callbacks.c,editor.c,filter.c,main.c install=$(BINDIR) [callbacks.c] @@ -16,3 +16,9 @@ depends=editor.h,callbacks.h [editor.c] depends=callbacks.h,editor.h,../config.h + +[filter.c] +depends=filter.h + +[main.c] +depends=filter.h diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..0a48796 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,41 @@ +TARGETS = filter +PREFIX = /usr/local +DESTDIR = +BINDIR = $(PREFIX)/bin +SBINDIR = $(PREFIX)/sbin +CC = cc +CPPFLAGSF= +CPPFLAGS= +CFLAGSF = -W +CFLAGS = -Wall -g -O2 -pedantic +LDFLAGSF= -lintl +LDFLAGS = +RM = rm -f +LN = ln -f +MKDIR = mkdir -m 0755 -p +INSTALL = install + + +all: $(TARGETS) + +filter_OBJS = filter.o +filter_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +filter_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) `pkg-config --libs libSystem` ../src/filter.o + +filter: $(filter_OBJS) + $(CC) -o filter $(filter_OBJS) $(filter_LDFLAGS) + +filter.o: filter.c + $(CC) $(filter_CFLAGS) -c filter.c + +clean: + $(RM) -- $(filter_OBJS) + +distclean: clean + $(RM) -- $(TARGETS) + +install: $(TARGETS) + +uninstall: + +.PHONY: all clean distclean install uninstall diff --git a/tools/filter.c b/tools/filter.c new file mode 100644 index 0000000..5f9415b --- /dev/null +++ b/tools/filter.c @@ -0,0 +1,144 @@ +/* $Id$ */ +/* Copyright (c) 2014 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Editor */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include +#include +#include +#include "../src/filter.h" +#include "../config.h" +#define _(string) gettext(string) + +/* constants */ +#ifndef PROGNAME +# define PROGNAME "filter" +#endif +#ifndef PREFIX +# define PREFIX "/usr/local" +#endif +#ifndef DATADIR +# define DATADIR PREFIX "/share" +#endif +#ifndef LOCALEDIR +# define LOCALEDIR DATADIR "/locale" +#endif + + +/* filter */ +/* private */ +/* prototypes */ +static int _filter(int argc, char const * argv[]); + +static int _error(char const * message, int ret); +static int _usage(void); + + +/* functions */ +/* filter */ +static int _filter_exec(char const * template, int argc, char const ** argv); + +static int _filter(int argc, char const * argv[]) +{ + int ret = 0; + char template[] = "/tmp/" PROGNAME ".XXXXXX"; + int fd; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + /* obtain a temporary file */ + if((fd = mkstemp(template)) < 0) + return -_error("mkstemp", 1); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, template); +#endif + /* write to and from the temporary file */ + if((ret = filter_read(fd, template)) == 0 + && (ret = _filter_exec(template, argc, argv)) == 0) + ret = filter_write(template); + /* remove the temporary file */ + if(unlink(template) != 0) + /* we can otherwise ignore this error */ + _error(template, 1); + return ret; +} + +static int _filter_exec(char const * template, int argc, char const ** argv) +{ + int ret = 0; + char ** args; + int i; + + if((args = malloc(sizeof(*args) * (argc + 1))) == NULL) + return -_error("malloc", 1); + for(i = 0; i < argc; i++) + args[i] = strdup(argv[i]); + args[i] = strdup(template); + /* check for errors */ + for(i = 0; ret == 0 && i <= argc; i++) + if(args[i] == NULL) + ret = -_error("strdup", 1); + /* FIXME fork() first */ + if(ret == 0 && execvp(args[0], args) != 0) + ret = -_error(args[0], 1); + for(i = 0; i <= argc; i++) + free(args[i]); + free(args); + return ret; +} + + +/* error */ +static int _error(char const * message, int ret) +{ + fputs(PROGNAME ": ", stderr); + perror(message); + return ret; +} + + +/* usage */ +static int _usage(void) +{ + fprintf(stderr, _("Usage: %s [-F][filename]\n" +" -F Behave like a filter\n"), PROGNAME); + return 1; +} + + +/* main */ +int main(int argc, char * argv[]) +{ + int o; + + if(setlocale(LC_ALL, "") == NULL) + _error("setlocale", 1); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + while((o = getopt(argc, argv, "")) != -1) + switch(o) + { + default: + return _usage(); + } + if(argc - optind == 0) + return _usage(); + return (_filter(argc - optind, (const char **)&argv[optind]) == 0) + ? 0 : 2; +} diff --git a/tools/project.conf b/tools/project.conf new file mode 100644 index 0000000..7b21458 --- /dev/null +++ b/tools/project.conf @@ -0,0 +1,11 @@ +targets=filter +cflags_force=-W +cflags=-Wall -g -O2 -pedantic +ldflags_force=-lintl +ldflags= +dist=Makefile + +[filter] +type=binary +sources=filter.c +ldflags=`pkg-config --libs libSystem` ../src/filter.o