diff options
| author | Simon Tatham <anakin@pobox.com> | 1999-01-30 21:35:36 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 1999-01-30 21:35:36 +0000 |
| commit | f91811f57de0561cc7c8efb5897a6b62f5c0e0b2 (patch) | |
| tree | 0f942e70bd4936e5806874193d17ba90693cd313 | |
| download | halibut-f91811f57de0561cc7c8efb5897a6b62f5c0e0b2.zip halibut-f91811f57de0561cc7c8efb5897a6b62f5c0e0b2.tar.gz halibut-f91811f57de0561cc7c8efb5897a6b62f5c0e0b2.tar.bz2 halibut-f91811f57de0561cc7c8efb5897a6b62f5c0e0b2.tar.xz | |
Initial checkin of skeleton application. About to start reading files
[originally from svn r22]
| -rw-r--r-- | Makefile | 55 | ||||
| -rw-r--r-- | buttress.h | 113 | ||||
| -rw-r--r-- | error.c | 60 | ||||
| -rw-r--r-- | help.c | 32 | ||||
| -rw-r--r-- | input.c | 33 | ||||
| -rw-r--r-- | licence.c | 16 | ||||
| -rw-r--r-- | main.c | 187 | ||||
| -rw-r--r-- | malloc.c | 39 | ||||
| -rw-r--r-- | version.c | 13 |
9 files changed, 548 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..23eb91e --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +# Buttress master makefile + +# Requires a compiler with -MD support, currently + +# `make' from top level will build in buttress.b +# `make BUILDDIR=foo' from top level will build in directory foo +ifndef REALBUILD +ifndef BUILDDIR +BUILDDIR := build +endif +all: + @test -d $(BUILDDIR) || mkdir $(BUILDDIR) + @make -C $(BUILDDIR) -f ../Makefile REALBUILD=yes +else + +# The `real' makefile part. + +ifdef RELEASE +ifndef VERSION +VERSION := $(RELEASE) +endif +else +CFLAGS += -g +endif + +ifndef VER +ifdef VERSION +VER := $(VERSION) +endif +endif +ifdef VER +VDEF := -DVERSION=\"$(VER)\" +endif + +SRC := ../ + +MODULES := main malloc error help licence version + +OBJECTS := $(addsuffix .o,$(MODULES)) +DEPS := $(addsuffix .d,$(MODULES)) + +buttress: $(OBJECTS) + $(CC) $(LFLAGS) -o buttress $(OBJECTS) + +%.o: $(SRC)%.c + $(CC) $(CFLAGS) -MD -c $< + +version.o: FORCE + $(CC) $(VDEF) -MD -c $(SRC)version.c + +FORCE: # phony target to force version.o to be rebuilt every time + +-include $(DEPS) + +endif diff --git a/buttress.h b/buttress.h new file mode 100644 index 0000000..afb38ae --- /dev/null +++ b/buttress.h @@ -0,0 +1,113 @@ +#ifndef BUTTRESS_BUTTRESS_H +#define BUTTRESS_BUTTRESS_H + +#ifdef __GNUC__ +#define NORETURN __attribute__((__noreturn__)) +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* + * Structure tags + */ +typedef struct input_Tag input; +typedef struct paragraph_Tag paragraph; +typedef struct word_Tag word; + +/* + * Data structure to hold all the file names etc for input + */ +#define INPUT_PUSHBACK_MAX 16 +struct input_Tag { + char **filenames; /* complete list of input files */ + int nfiles; /* how many in the list */ + FILE *currfp; /* the currently open one */ + int currindex; /* which one is that in the list */ + char pushback[INPUT_PUSHBACK_MAX]; /* pushed-back input characters */ + int npushback; +}; + +/* + * Data structure to hold the input form of the source, ie a linked + * list of paragraphs + */ +struct paragraph_Tag { + paragraph *next; + int type; + char *keyword; /* for IR, IA, and heading paras */ + word *words; /* list of words in paragraph */ +} paragraph; +enum { + para_IA, /* index alias */ + para_IR, /* index rewrite */ + para_Chapter, + para_Appendix, + para_Heading, + para_Subsect, + para_Normal, + para_Bullet, + para_Code +}; + +/* + * Data structure to hold an individual word + */ +struct word_Tag { + word *next; + int type; + char *text; +} +enum { + word_Normal, + word_Emph, + word_Code, + word_IndexRef /* always invisible */ +} + +/* + * error.c + */ +void fatal(int code, ...) NORETURN; +void error(int code, ...); +enum { + err_nomemory, /* out of memory */ + err_optnoarg, /* option `-%s' requires an argument */ + err_nosuchopt, /* unrecognised option `-%s' */ + err_noinput, /* no input files */ +}; + +/* + * malloc.c + */ +void *smalloc(int size); +void *srealloc(void *p, int size); +void sfree(void *p); + +/* + * help.c + */ +void help(void); +void usage(void); +void showversion(void); + +/* + * licence.c + */ +void licence(void); + +/* + * version.c + */ +const char *const version; + +/* + * input.c + */ +paragraph *read_input(input *in); + +#endif @@ -0,0 +1,60 @@ +/* + * error.c: buttress error handling + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include "buttress.h" + +/* + * Error flags + */ +#define PREFIX 0x0001 /* give `buttress:' prefix */ + +static void do_error(int code, va_list ap) { + char error[1024]; + char *sp; + int flags; + + switch(code) { + case err_nomemory: /* no arguments */ + sprintf(error, "out of memory"); + flags = PREFIX; + break; + case err_optnoarg: + sp = va_arg(ap, char *); + sprintf(error, "option `-%.200s' requires an argument", sp); + flags = PREFIX; + break; + case err_nosuchopt: + sp = va_arg(ap, char *); + sprintf(error, "unrecognised option `-%.200s'", sp); + flags = PREFIX; + break; + case err_noinput: /* no arguments */ + sprintf(error, "no input files"); + flags = PREFIX; + break; + } + + if (flags & PREFIX) + fputs("buttress: ", stderr); + fputs(error, stderr); + fputc('\n', stderr); +} + +void fatal(int code, ...) { + va_list ap; + va_start(ap, code); + do_error(code, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +void error(int code, ...) { + va_list ap; + va_start(ap, code); + do_error(code, ap); + va_end(ap); +} @@ -0,0 +1,32 @@ +/* + * help.c: usage instructions + */ + +#include <stdio.h> +#include "buttress.h" + +static char *helptext[] = { + "FIXME: help text goes here", + NULL +}; + +static char *usagetext[] = { + "FIXME: usage text goes here", + NULL +}; + +void help(void) { + char **p; + for (p = helptext; *p; p++) + puts(*p); +} + +void usage(void) { + char **p; + for (p = usagetext; *p; p++) + puts(*p); +} + +void showversion(void) { + printf("Buttress, %s\n", version); +} @@ -0,0 +1,33 @@ +/* + * input.c: read the source form + */ + +#include <stdio.h> +#include <assert.h> +#include "buttress.h" + +static void unget(input *in, char c) { + assert(in->npushback < INPUT_PUSHBACK_MAX); + in->pushback[in->npushback++] = c; +} + +/* + * Can return EOF + */ +static int get(input *in) { + if (in->npushback) + return (unsigned char)in->pushback[--in->npushback]; + else if (in->currfp) { + int c = getc(in->currfp); + if (c == EOF) { + fclose(in->currfp); + in->currfp = NULL; + in->currindex++; + } + return c; + } +} + +paragraph *read_input(input *in) { + /* FIXME: do some reading */ +} diff --git a/licence.c b/licence.c new file mode 100644 index 0000000..0c4338a --- /dev/null +++ b/licence.c @@ -0,0 +1,16 @@ +/* + * licence.c: licence text + */ + +#include <stdio.h> + +static char *licencetext[] = { + "FIXME: licence text goes here", + NULL +}; + +void licence(void) { + char **p; + for (p = licencetext; *p; p++) + puts(*p); +} @@ -0,0 +1,187 @@ +/* + * main.c: command line parsing and top level + */ + +#include <stdio.h> +#include <stdlib.h> +#include "buttress.h" + +int main(int argc, char **argv) { + char **infiles; + char *outfile; + int nfiles; + int nogo; + int errs; + + /* + * Set up initial (default) parameters. + */ + infiles = smalloc(argc*sizeof(char *)); + outfile = NULL; + nfiles = 0; + nogo = errs = FALSE; + + if (argc == 1) { + usage(); + exit(EXIT_SUCCESS); + } + + /* + * Parse command line arguments. + */ + while (--argc) { + char *p = *++argv; + if (*p == '-') { + /* + * An option. + */ + while (p && *++p) { + char c = *p; + switch (c) { + case '-': + /* + * Long option. + */ + { + char *opt, *val; + opt = p++; /* opt will have _one_ leading - */ + while (*p && *p != '=') + p++; /* find end of option */ + if (*p == '=') { + *p++ = '\0'; + val = p; + } else + val = NULL; + if (!strcmp(opt, "-help")) { + help(); + nogo = TRUE; + } else if (!strcmp(opt, "-version")) { + showversion(); + nogo = TRUE; + } else if (!strcmp(opt, "-licence") || + !strcmp(opt, "-license")) { + licence(); + nogo = TRUE; + } else if (!strcmp(opt, "-output")) { + if (!val) + errs = TRUE, error(err_optnoarg, opt); + else + outfile = val; + } else { + errs = TRUE, error(err_nosuchopt, opt); + } + } + p = NULL; + break; + case 'h': + case 'V': + case 'L': + /* + * Option requiring no parameter. + */ + switch (c) { + case 'h': + help(); + nogo = TRUE; + break; + case 'V': + showversion(); + nogo = TRUE; + break; + case 'L': + licence(); + nogo = TRUE; + break; + } + break; + case 'o': + /* + * Option requiring parameter. + */ + p++; + if (!*p && argc > 1) + --argc, p = *++argv; + else if (!*p) { + char opt[2]; + opt[0] = c; + opt[1] = '\0'; + errs = TRUE, error(err_optnoarg, opt); + } + /* + * Now c is the option and p is the parameter. + */ + switch (c) { + case 'o': + ofile = p; + break; + } + p = NULL; /* prevent continued processing */ + break; + default: + /* + * Unrecognised option. + */ + { + char opt[2]; + opt[0] = c; + opt[1] = '\0'; + errs = TRUE, error(err_nosuchopt, opt); + } + } + } + } else { + /* + * A non-option argument. + */ + infiles[nfiles++] = p; + } + } + + if (errs) + exit(EXIT_FAILURE); + if (nogo) + exit(EXIT_SUCCESS); + + /* + * Do the work. + */ + if (nfiles == 0) { + error(err_noinput); + usage(); + exit(EXIT_FAILURE); + } + + { + input in; + paragraph sourceform; + + in.filenames = infiles; + in.nfiles = nfiles; + in.currfp = NULL; + in.currindex = 0; + in.npushback = 0; + + sourceform = read_input(&in); + if (!sourceform) + exit(EXIT_FAILURE); + + sfree(infiles); + + /* + * FIXME: having read it, do something with it! + */ + { + paragraph *p; + word *w; + for (p = sourceform; p; p = p->next) { + printf("para %d \"%s\" {\n", p->type, p->keyword); + for (w = p->words; w; w = w->next) { + printf(" word %d \"%s\"\n", w->type, w->text); + } + printf("}\n"); + } + } + } + + return 0; +} diff --git a/malloc.c b/malloc.c new file mode 100644 index 0000000..cf0f2e0 --- /dev/null +++ b/malloc.c @@ -0,0 +1,39 @@ +/* + * malloc.c: safe wrappers around malloc, realloc, free, strdup + */ + +#include <stdlib.h> +#include "buttress.h" + +/* + * smalloc should guarantee to return a useful pointer - buttress + * can do nothing except die when it's out of memory anyway + */ +void *smalloc(int size) { + void *p = malloc(size); + if (!p) + fatal(err_nomemory); + return p; +} + +/* + * sfree should guaranteeably deal gracefully with freeing NULL + */ +void sfree(void *p) { + if (p) + free(p); +} + +/* + * srealloc should guaranteeably be able to realloc NULL + */ +void *srealloc(void *p, int size) { + void *q; + if (p) + q = realloc(p, size); + else + q = malloc(size); + if (!q) + fatal(err_nomemory); + return p; +} diff --git a/version.c b/version.c new file mode 100644 index 0000000..38fbca1 --- /dev/null +++ b/version.c @@ -0,0 +1,13 @@ +/* + * version.c: version string + */ + +#include <stdio.h> + +#ifndef VERSION +#define VER "anonymous build (" __DATE__ " " __TIME__ ")" +#else +#define VER "version " VERSION +#endif + +const char *const version = VER; |