summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2009-09-03 19:38:20 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2015-06-26 00:30:14 -0600
commit67d3b5846d84d4a2e5a31d4e268bc9d51495d7e0 (patch)
tree92db2e7852b7ee09e55a68276101566c562a4283
parent1eacc442394d1f70bbe05dea699c80ca41f26d4c (diff)
the C implementation properly loads the plugins, then creates a dependancy tree
-rwxr-xr-xc/Makefile2
-rw-r--r--c/plugin-debug.c69
-rw-r--r--c/plugin-depend.c102
-rw-r--r--c/plugin-parse.c135
-rw-r--r--c/plugin.c149
-rw-r--r--c/plugin.h6
l---------c/plugins1
-rw-r--r--c/rvs.c5
-rw-r--r--c/rvs.h29
-rw-r--r--c/test.c5
-rw-r--r--plugins/file0
11 files changed, 370 insertions, 133 deletions
diff --git a/c/Makefile b/c/Makefile
index fa0a285..61a4763 100755
--- a/c/Makefile
+++ b/c/Makefile
@@ -4,5 +4,5 @@ CC = gcc
all :
$(CC) rvs.c -Wall -ansi -g -o rvs
-test :
+test : test.c rvs.h plugin.c plugin.h plugin-debug.c plugin-depends.c
$(CC) test.c -Wall -ansi -g -o test
diff --git a/c/plugin-debug.c b/c/plugin-debug.c
index 50e5497..553237d 100644
--- a/c/plugin-debug.c
+++ b/c/plugin-debug.c
@@ -18,23 +18,70 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-void print_commands(struct plugin_command *command)
+size_t xstrlen (const char *s)
{
- printf(" - %s\n",command->name);
- if (command->depends != NULL) {
- printf(" depend: %s\n",command->depends);
+ printf("xstrlen(%p)\n",s);
+ size_t size=0;
+ while (s[size] != '\0') {
+ printf("%i = %p `%c'\n",size,&s[size],s[size]);
+ size++;
}
- if (command->p_next != NULL) {
- print_commands(command->p_next);
+ return size;
+}
+
+void _plugin_print_plugin_command(struct plugin_command *command)
+{
+ if (command != NULL) {
+ printf(" - %s\n",command->name);
+ if (command->depends != NULL)
+ printf(" depend string: %s\n",command->depends);
+ if (command->depend->plugin == NULL) {
+ puts (" depend: <none>");
+ } else {
+ printf(" depend: %s / %s\n",
+ command->depend->plugin->name,
+ command->depend->name);
+ }
+ _plugin_print_plugin_command(command->p_next);
+ }
+}
+
+void _plugin_print_plugin(struct plugin *plugin)
+{
+ if (plugin != NULL) {
+ printf(" %s\n",plugin->name);
+ _plugin_print_plugin_command(plugin->child);
+ _plugin_print_plugin(plugin->next);
}
}
-void print_plugins(struct plugin *plugin)
+void _plugin_print_depend(struct plugin_command *command,size_t indent)
{
- printf("%s\n",plugin->name);
- print_commands(plugin->child);
- if (plugin->next != NULL) {
- print_plugins(plugin->next);
+ int i=0;
+ while (i < indent) {
+ printf(" ");
+ i++;
}
+ if (command->name == NULL) {
+ puts("<none>");
+ } else {
+ printf("%s / %s\n",
+ command->plugin->name,
+ command->name);
+ }
+ if (command->child != NULL) {
+ _plugin_print_depend(command->child,indent+1);
+ }
+ if (command->d_next != NULL) {
+ _plugin_print_depend(command->d_next,indent);
+ }
+}
+
+void _plugin_print(struct plugin_tree *tree)
+{
+ puts("Plugins:");
+ _plugin_print_plugin(tree->plugins);
+ puts("\nDepends:");
+ _plugin_print_depend(tree->depends,0);
}
diff --git a/c/plugin-depend.c b/c/plugin-depend.c
new file mode 100644
index 0000000..4101fe1
--- /dev/null
+++ b/c/plugin-depend.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 2009 Luke Shumaker
+
+ This file is part of rvs.
+
+ rvs 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; either version 2, or (at your
+ option) any later version.
+
+ rvs 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 rvs; see the file COPYING.
+ If not, write to the Free Software Foundation,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* translates a string in syntax `plugin/command' into a pointer to the commnad
+ DON'T plan on using the string again, it will be mutilated!
+ (so we go ahead and free() it) */
+struct plugin_command *
+_plugin_depend_parse(struct plugin *root, char *string)
+{
+ char *c=strchr(string,'/');
+ c[0]='\0';
+ return _plugin_find_command(
+ _plugin_find_plugin(root,string)->child,
+ &c[1]);
+ xfree(string);
+}
+
+/* used by _plugin_depend_add */
+void
+_plugin_depend_add2(struct plugin_command *prev, struct plugin_command *next)
+{
+ if (prev->d_next==NULL) {
+ prev->d_next=next;
+ } else {
+ _plugin_depend_add2(prev->d_next,next);
+ }
+}
+
+/* _plugin_depend_add(depend,depender) */
+void
+_plugin_depend_add(struct plugin_command *depend, struct plugin_command *depender)
+{
+ if (depend->child==NULL) {
+ depend->child=depender;
+ } else {
+ _plugin_depend_add2(depend->child,depender);
+ }
+}
+
+/* take care of depends for `command', and those after it (linked list) */
+void
+_plugin_depend_command(struct plugin_command *command, struct plugin_tree *tree)
+{
+ if (command->depends == NULL) {
+ command->depend=tree->depends;
+ } else {
+ command->depend=_plugin_depend_parse(tree->plugins,command->depends);
+ command->depends=NULL;
+ }
+ _plugin_depend_add(command->depend,command);
+ if (command->p_next != NULL)
+ _plugin_depend_command(command->p_next,tree);
+}
+
+/* take care of commands for a `plugin', and those after it (linked list) */
+void
+_plugin_depend_plugin(struct plugin *plugin, struct plugin_tree *tree)
+{
+ _plugin_depend_command(plugin->child,tree);
+ if (plugin->next != NULL) {
+ _plugin_depend_plugin(plugin->next,tree);
+ }
+}
+
+/* take care of all depends */
+void
+_plugin_depend(struct plugin_tree *tree)
+{
+ /* add a blank `root' command for those that don't have depends */
+ struct plugin_command *command;
+ command=(struct plugin_command *)xmalloc(sizeof(*command));
+ command->name=NULL;
+ command->plugin=NULL;
+ command->p_next=NULL;
+ command->depend=NULL;
+ command->depends=NULL;
+ command->child=NULL;/*<--only variable of any value */
+ command->d_next=NULL;
+
+ tree->depends=command;
+
+ /* parse all commands */
+ _plugin_depend_plugin(tree->plugins,tree);
+}
+
diff --git a/c/plugin-parse.c b/c/plugin-parse.c
new file mode 100644
index 0000000..c333193
--- /dev/null
+++ b/c/plugin-parse.c
@@ -0,0 +1,135 @@
+/* Copyright (C) 2009 Luke Shumaker
+
+ This file is part of rvs.
+
+ rvs 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; either version 2, or (at your
+ option) any later version.
+
+ rvs 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 rvs; see the file COPYING.
+ If not, write to the Free Software Foundation,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+void _plugin_parse_comment (FILE *file)
+{
+ char c;
+ while ( (c=getc(file)) != EOF ) {
+ if ( c == '\n' ) {
+ ungetc (c, file);
+ break;
+ }
+ }
+}
+
+char _plugin_parse_escape(FILE *file)
+{
+ char c=getc(file);
+ switch (c) {
+ case 'n':
+ c = '\n';
+ case '\\':
+ case '#':
+ case ':':
+ break;
+ default:
+ error(EXIT_FAILURE,0,"syntax error");
+ break;
+ }
+ return c;
+}
+
+char *_plugin_parse_depend (FILE *file)
+{
+ size_t nbytes = 10;
+ char *string = (char *)xmalloc(nbytes);
+ string[0]='\0';
+
+ char c[2] = " \0";
+ char *cs = (char *)&c;
+ while ( (c[0]=getc(file)) != EOF ) {
+ if (c[0] == '\n') {
+ ungetc (c[0], file);
+ break;
+ } else {
+ switch (c[0]) {
+ case '\\':
+ c[0]=_plugin_parse_escape(file);
+ stradds(&nbytes,&string,cs);
+ break;
+ case '#':
+ _plugin_parse_comment(file);
+ break;
+ default:
+ stradds(&nbytes,&string,cs);
+ break;
+ }
+ }
+ }
+ return string;
+}
+
+struct plugin_command *_plugin_parse (struct plugin *plugin, FILE *file)
+{
+ struct plugin_command *command;
+ command=(struct plugin_command *)xmalloc(sizeof(*command));
+
+ command->plugin=plugin;
+ command->p_next=NULL;
+
+ command->depend=NULL;
+ command->depends=NULL;
+ command->child=NULL;
+ command->d_next=NULL;
+
+ size_t nbytes = 10;
+ char *string = (char *)xmalloc(nbytes);
+ string[0]='\0';
+
+ char c[2] = " \0";
+ char *cs = (char *)&c;
+ if ( (c[0]=getc(file)) == EOF ) {
+ return NULL;
+ } else {
+ ungetc (c[0], file);
+ }
+ while ( (c[0]=getc(file)) != EOF ) {
+ if (c[0] == '\n') {
+ if (strcmp(string,"")==0) {
+ xfree(command);
+ xfree(string);
+ command=_plugin_parse(plugin, file);
+ } else {
+ command->name=string;
+ command->p_next=_plugin_parse(plugin, file);
+ }
+ break;
+ } else {
+ switch (c[0]) {
+ case '\\':
+ c[0]=_plugin_parse_escape(file);
+ stradds(&nbytes,&string,cs);
+ break;
+ case '#':
+ _plugin_parse_comment(file);
+ break;
+ case ':':
+ command->depends=_plugin_parse_depend(file);
+ break;
+ default:
+ stradds(&nbytes,&string,cs);
+ break;
+ }
+ }
+ }
+ return command;
+}
+
diff --git a/c/plugin.c b/c/plugin.c
index 7b0146b..7182626 100644
--- a/c/plugin.c
+++ b/c/plugin.c
@@ -7,7 +7,7 @@
the Free Software Foundation; either version 2, or (at your
option) any later version.
- rvs is distributed in the hope 1. A user enters a username and passwthat it will be useful, but
+ rvs 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.
@@ -32,137 +32,72 @@
#include "rvs.h"
#include "plugin.h"
-void _parse_comment (FILE *file)
+/* finds a plugin with `name'. Start looking at `plugin' (linked list) */
+struct plugin *
+_plugin_find_plugin(struct plugin *plugin, char *name)
{
- char c;
- while ( (c=getc(file)) != EOF ) {
- if ( c == '\n' ) {
- ungetc (c, file);
- break;
- }
- }
-}
-
-char _parse_escape(FILE *file)
-{
- char c=getc(file);
- switch (c) {
- case 'n':
- c = '\n';
- case '\\':
- case '#':
- case ':':
- break;
- default:
- error(EXIT_FAILURE,0,"syntax error");
- break;
- }
- return c;
-}
-
-char *_parse_depend (FILE *file)
-{
- size_t nbytes = 10;
- char *string = (char *)xmalloc(nbytes);
-
- char c[2] = " \0";
- char *cs = (char *)&c;
- while ( (c[0]=getc(file)) != EOF ) {
- if (c[0] == '\n') {
- ungetc (c[0], file);
- break;
+ if (strcmp(plugin->name,name) == 0) {
+ return plugin;
+ } else {
+ if (plugin->next==NULL) {
+ error(EXIT_FAILURE,0,"cannot find plugin `%s'",name);
+ return NULL;
} else {
- switch (c[0]) {
- case '\\':
- c[0]=_parse_escape(file);
- stradds(&nbytes,&string,cs);
- break;
- case '#':
- _parse_comment(file);
- break;
- default:
- stradds(&nbytes,&string,cs);
- break;
- }
+ return _plugin_find_plugin(plugin->next,name);
}
}
- return string;
}
-struct plugin_command *_parse_plugin (struct plugin *plugin, FILE *file)
+/* finds a command with `name'. Start looking at `command' (linked list) */
+struct plugin_command *
+_plugin_find_command(struct plugin_command *command, char *name)
{
- struct plugin_command *command;
- command=(struct plugin_command *)xmalloc(sizeof(*command));
- command->p_next=NULL;
- command->depends=NULL;
-
- size_t nbytes = 10;
- char *string = (char *)xmalloc(nbytes);
- strcpy(string,"");
-
- char c[2] = " \0";
- char *cs = (char *)&c;
- if ( (c[0]=getc(file)) == EOF ) {
- return NULL;
+ if (strcmp(command->name,name) == 0) {
+ return command;
} else {
- ungetc (c[0], file);
- }
- while ( (c[0]=getc(file)) != EOF ) {
- if (c[0] == '\n') {
- if (strcmp(string,"")==0) {
- free(command);
- free(string);
- return _parse_plugin(plugin, file);
- } else {
- command->name=string;
- command->p_next=_parse_plugin(plugin, file);
- break;
- }
+ if (command->p_next==NULL) {
+ error(EXIT_FAILURE,0,
+ "plugin `%s' does not contain command `%s'",
+ command->plugin->name,name);
+ return NULL;
} else {
- switch (c[0]) {
- case '\\':
- c[0]=_parse_escape(file);
- stradds(&nbytes,&string,cs);
- break;
- case '#':
- _parse_comment(file);
- break;
- case ':':
- command->depends=_parse_depend(file);
- break;
- default:
- stradds(&nbytes,&string,cs);
- break;
- }
+ return _plugin_find_command(command->p_next,name);
}
}
- return command;
}
-struct plugin *load_plugin (char *plug_name, char *plugin_conf)
+#include "plugin-parse.c"
+#include "plugin-depend.c"
+
+struct plugin *
+_plugin_load (char *plug_name, char *plugin_conf)
{
- printf("loading plugin `%s'\n",plug_name);
struct plugin *plugin=(struct plugin *)xmalloc(sizeof(*plugin));
- plugin->name=plug_name;
+ char *plug_name2 = (char *)xmalloc(strlen(plug_name)+1);
+ strcpy(plug_name2,plug_name);
+ plugin->name=plug_name2;
plugin->next=NULL;
- chdir(plug_name);
+ xchdir(plug_name);
FILE *file = xfopen(plugin_conf,"r");
- plugin->child=_parse_plugin(plugin, file);
+ plugin->child=_plugin_parse(plugin, file);
fclose( file );
- chdir("..");
+ xchdir("..");
return plugin;
}
-struct plugin_tree *load_plugins (char *libexecdir, char *plugin_conf)
+struct plugin_tree *
+load_plugins (char *libexecdir, char *plugin_conf)
{
struct plugin_tree *tree=(struct plugin_tree *)xmalloc(sizeof(*tree));
struct plugin **last=&tree->plugins;
+ *last=NULL;
struct plugin *plugin;
- chdir(libexecdir);
+ xchdir(libexecdir);
+
DIR *cwd;
struct dirent *dirent;
int serr;
@@ -173,13 +108,17 @@ struct plugin_tree *load_plugins (char *libexecdir, char *plugin_conf)
(strcmp(dirent->d_name,"..")!=0)) {
serr = stat(dirent->d_name, &sbuf);
if (!serr && S_ISDIR(sbuf.st_mode)) {
- plugin=load_plugin(dirent->d_name,plugin_conf);
- *last=plugin;
+ plugin=_plugin_load(dirent->d_name,plugin_conf);
+ *last=plugin;/* this sets the last's `next' */
last=&plugin->next;
}
}
}
closedir (cwd);
+
+ _plugin_depend(tree);
+
+ xchdir("..");
return tree;
}
diff --git a/c/plugin.h b/c/plugin.h
index 92deed2..d5ede8f 100644
--- a/c/plugin.h
+++ b/c/plugin.h
@@ -31,12 +31,12 @@ struct plugin_command
char *name;
/*plugin ID*/
- struct plugin *plugin; /* which plugin does it belong to? */
+ struct plugin *plugin; /* which plugin does it belong to? */
struct plugin_command *p_next; /* next command in this plugin (linked list)*/
/*dependancy tree*/
struct plugin_command *depend; /* what does this depend on? */
- char *depends; /* what does this depend on? */
+ char *depends;/* what does this depend on? */
struct plugin_command *child; /* what depends on this? (linked list) */
struct plugin_command *d_next; /* next command w/ same dependancy (linked list) */
};
@@ -44,6 +44,6 @@ struct plugin_command
struct plugin_tree
{
struct plugin *plugins;
- struct plugin_command *depend;
+ struct plugin_command *depends;
};
diff --git a/c/plugins b/c/plugins
deleted file mode 120000
index b1f2dbf..0000000
--- a/c/plugins
+++ /dev/null
@@ -1 +0,0 @@
-../plugins/ \ No newline at end of file
diff --git a/c/rvs.c b/c/rvs.c
index 6997596..56162ac 100644
--- a/c/rvs.c
+++ b/c/rvs.c
@@ -26,9 +26,10 @@ const char *ver="0.8c";
const char *libexecdir="./plugins";
const char *plugin_conf="plugin.conf";
-int main (void)
+int
+main (void)
{
- load_plugins(libexecdir,plugin_conf);
+ struct plugin_tree *plugins=load_plugins(libexecdir,plugin_conf);
return 0;
}
diff --git a/c/rvs.h b/c/rvs.h
index 1bcbacf..5301b09 100644
--- a/c/rvs.h
+++ b/c/rvs.h
@@ -18,6 +18,8 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include <stdio.h>
+#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -26,20 +28,34 @@
void *xmalloc (size_t size)
{
- register void *value = malloc (size);
- if (value == 0)
+ void *value = malloc (size);
+ if (value == NULL)
error(EXIT_FAILURE,0,"virtual memory exhausted");
return value;
}
void *xrealloc (void *ptr, size_t size)
{
- register void *value = realloc (ptr, size);
- if (value == 0)
+ void *value = realloc (ptr, size);
+ if (value == NULL)
error(EXIT_FAILURE,0,"virtual memory exhausted");
return value;
}
+void xfree (void *ptr)
+{
+ free (ptr);
+}
+
+int xchdir (const char *filename)
+{
+ int ret=chdir(filename);
+ if (ret != 0) {
+ error(EXIT_FAILURE,errno,"%s/",filename);
+ }
+ return ret;
+}
+
FILE *xfopen (const char *filename, const char *opentype)
{
FILE *file = fopen(filename,opentype);
@@ -68,9 +84,8 @@ void stradds(size_t *size, char **dest, char *str)
} else {
*size = strlen(*dest) + strlen(str) + 1;
- char *string;
- string = (char *) xrealloc (*dest, *size);
- strcat(string, str);
+ *dest = (char *) xrealloc (*dest, *size);
+ strcat(*dest, str);
}
}
diff --git a/c/test.c b/c/test.c
index 3a10711..3a9abc9 100644
--- a/c/test.c
+++ b/c/test.c
@@ -1,10 +1,9 @@
#include "plugin.c"
#include "plugin-debug.c"
-int main()
-{
+int main() {
struct plugin_tree *plugins=load_plugins("plugins","plugin.conf");
- print_plugins(plugins->plugins);
+ _plugin_print(plugins);
return 0;
}
diff --git a/plugins/file b/plugins/file
deleted file mode 100644
index e69de29..0000000
--- a/plugins/file
+++ /dev/null