changeset 172:47427342e41d

lwar now creates, lists, and adds to archive files
author lost
date Sun, 01 Mar 2009 22:59:52 +0000
parents d610b8aef91b
children 0395e6fd67e9
files lwar/Makefile.am lwar/add.c lwar/list.c lwar/lwar.c lwar/lwar.h lwar/main.c lwar/remove.c
diffstat 7 files changed, 436 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/lwar/Makefile.am	Sun Mar 01 19:37:03 2009 +0000
+++ b/lwar/Makefile.am	Sun Mar 01 22:59:52 2009 +0000
@@ -1,3 +1,3 @@
 bin_PROGRAMS = lwar
-lwar_SOURCES = main.c util.c lwar.c
+lwar_SOURCES = main.c util.c lwar.c list.c add.c remove.c
 EXTRA_DIST = lwar.h util.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwar/add.c	Sun Mar 01 22:59:52 2009 +0000
@@ -0,0 +1,138 @@
+/*
+add.c
+Copyright © 2009 William Astle
+
+This file is part of LWAR.
+
+LWAR 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 3 of the License, or (at your option) any later
+version.
+
+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 <http://www.gnu.org/licenses/>.
+
+
+Implements the program startup code
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "lwar.h"
+
+void do_add(void)
+{
+	FILE *f;
+	unsigned char buf[8];
+	long l;
+	int c;
+	FILE *f2;
+	int i;
+	
+	f = fopen(archive_file, "r+");
+	if (!f)
+	{
+		if (errno == ENOENT)
+		{
+			f = fopen(archive_file, "w");
+			if (f)
+			{
+				fputs("LWAR1V", f);
+				goto doadd;
+			}
+		}
+		perror("Cannot open archive file");
+	}
+	
+	fread(buf, 1, 6, f);
+	if (memcmp("LWAR1V", buf, 6))
+	{
+		fprintf(stderr, "%s is not a valid archive file.\n", archive_file);
+		exit(1);
+	}
+
+	for (;;)
+	{
+		c = fgetc(f);
+		if (c == EOF && ferror(f))
+		{
+			perror("Reading archive file");
+			exit(1);
+		}
+		if (c == EOF)
+			goto doadd;
+		
+		if (!c)
+		{
+			fseek(f, -1, SEEK_CUR);
+			goto doadd;
+		}
+		
+		// find the end of the file name
+		while (c)
+		{
+			c = fgetc(f);
+			if (c == EOF || ferror(f))
+			{
+				fprintf(stderr, "Bad archive file\n");
+				exit(1);
+			}
+		}
+		
+		// get length of archive member
+		l = 0;
+		c = fgetc(f);
+		l = c << 24;
+		c = fgetc(f);
+		l |= c << 16;
+		c = fgetc(f);
+		l |= c << 8;
+		c = fgetc(f);
+		l |= c;
+		
+		fseek(f, l, SEEK_CUR);
+	}
+	// back up to the NUL byte at the end of the file
+	fseek(f, -1, SEEK_CUR);
+doadd:
+	for (i = 0; i < nfiles; i++)
+	{
+		f2 = fopen(files[i], "r");
+		if (!f2)
+		{
+			fprintf(stderr, "Cannot open file %s:", files[i]);
+			perror("");
+			exit(1);
+		}
+		fseek(f2, 0, SEEK_END);
+		l = ftell(f2);
+		fseek(f2, 0, SEEK_SET);
+		fputs(files[i], f);
+		fputc(0, f);
+		fputc(l >> 24, f);
+		fputc((l >> 16) & 0xff, f);
+		fputc((l >> 8) & 0xff, f);
+		fputc(l & 0xff, f);
+		while (l)
+		{
+			c = fgetc(f2);
+			fputc(c, f);
+			l--;
+		}
+	}
+	
+	// flag end of file
+	fputc(0, f);	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwar/list.c	Sun Mar 01 22:59:52 2009 +0000
@@ -0,0 +1,97 @@
+/*
+list.c
+Copyright © 2009 William Astle
+
+This file is part of LWAR.
+
+LWAR 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 3 of the License, or (at your option) any later
+version.
+
+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 <http://www.gnu.org/licenses/>.
+
+
+Implements the program startup code
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lwar.h"
+
+void do_list(void)
+{
+	FILE *f;
+	char buf[8];
+	long l;
+	int c;
+		
+	f = fopen(archive_file, "r");
+	if (!f)
+	{
+		perror("Opening archive file");
+		exit(1);
+	}
+	
+	fread(buf, 1, 6, f);
+	if (memcmp("LWAR1V", buf, 6))
+	{
+		fprintf(stderr, "%s is not a valid archive file.\n", archive_file);
+		exit(1);
+	}
+
+	for (;;)
+	{
+		c = fgetc(f);
+		if (ferror(f))
+		{
+			perror("Reading archive file");
+			exit(1);
+		}
+		if (c == EOF)
+			return;
+		
+		
+		// find the end of the file name
+		if (!c)
+			return;
+
+		while (c)
+		{
+			putchar(c);
+			c = fgetc(f);
+			if (c == EOF || ferror(f))
+			{
+				fprintf(stderr, "Bad archive file\n");
+				exit(1);
+			}
+		}
+		
+		// get length of archive member
+		l = 0;
+		c = fgetc(f);
+		l = c << 24;
+		c = fgetc(f);
+		l |= c << 16;
+		c = fgetc(f);
+		l |= c << 8;
+		c = fgetc(f);
+		l |= c;
+		printf(": %04lx bytes\n", l);
+		fseek(f, l, SEEK_CUR);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwar/lwar.c	Sun Mar 01 22:59:52 2009 +0000
@@ -0,0 +1,47 @@
+/*
+lwar.c
+Copyright © 2009 William Astle
+
+This file is part of LWAR.
+
+LWAR 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 3 of the License, or (at your option) any later
+version.
+
+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 <http://www.gnu.org/licenses/>.
+
+
+Implements the program startup code
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#define __lwar_c_seen__
+#include "lwar.h"
+#include "util.h"
+
+int debug_level = 0;
+int operation = 0;
+int nfiles = 0;
+char *archive_file = NULL;
+
+char **files = NULL;
+
+void add_file_name(char *fn)
+{
+	files = lw_realloc(files, sizeof(char *) * (nfiles + 1));
+	files[nfiles] = fn;
+	nfiles++;
+}
--- a/lwar/lwar.h	Sun Mar 01 19:37:03 2009 +0000
+++ b/lwar/lwar.h	Sun Mar 01 22:59:52 2009 +0000
@@ -21,18 +21,29 @@
 */
 
 
+#define LWAR_OP_LIST	1
+#define LWAR_OP_ADD		2
+#define LWAR_OP_REMOVE	3
+#define LWAR_OP_CREATE	4
+
 #ifndef __lwar_h_seen__
 #define __lwar_h_seen__
 
 #ifndef __lwar_c_seen__
 
+extern char *archive_file;
 extern int debug_level;
+extern int operation;
+extern int nfiles;
+extern char **files;
 
 #define __lwar_E__ extern
 #else
 #define __lwar_E__
 #endif // __lwar_c_seen__
 
+__lwar_E__ void add_file_name(char *fn);
+
 #undef __lwar_E__
 
 #endif //__lwar_h_seen__
--- a/lwar/main.c	Sun Mar 01 19:37:03 2009 +0000
+++ b/lwar/main.c	Sun Mar 01 22:59:52 2009 +0000
@@ -30,6 +30,9 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include "lwar.h"
 
@@ -46,9 +49,35 @@
 		debug_level++;
 		break;
 	
-//	case ARGP_KEY_ARG:
-//
+	case 'a':
+		// add members
+		operation = LWAR_OP_ADD;
+		break;
+	
+	case 'c':
+		// create archive
+		operation = LWAR_OP_CREATE;
+		break;
+		
+//	case 'r':
+//		// remove members
+//		operation = LWAR_OP_REMOVE;
 //		break;
+	
+	case 'l':
+		// list members
+		operation = LWAR_OP_LIST;
+		break;
+	
+	case ARGP_KEY_ARG:
+		if (archive_file)
+		{
+			// add archive member to list
+			add_file_name(arg);
+		}
+		else
+			archive_file = arg;
+		break;
 		
 	default:
 		return ARGP_ERR_UNKNOWN;
@@ -58,6 +87,14 @@
 
 static struct argp_option options[] =
 {
+//	{ "remove",		'r',	0,		0,
+//				"Remove members from the archive" },
+	{ "add",		'a',	0,		0,
+				"Add members to the archive" },
+	{ "list",		'l',	0,		0,
+				"List the contents of the archive" },
+	{ "create",		'c',	0,		0,
+				"Create new archive (or truncate existing one)" },
 	{ "debug",		'd',	0,		0,
 				"Set debug mode"},
 	{ 0 }
@@ -67,15 +104,83 @@
 {
 	options,
 	parse_opts,
-	"<input file> ...",
-	"LWLINK, a HD6309 and MC6809 cross-linker"
+	"<archive> [<file> ...]",
+	"LWAR, a library file manager for LWLINK"
 };
 
+extern void do_list(void);
+extern void do_add(void);
+extern void do_remove(void);
+
 // main function; parse command line, set up assembler state, and run the
 // assembler on the first file
 int main(int argc, char **argv)
 {
 	argp_parse(&argp, argc, argv, 0, 0, NULL);
+	if (archive_file == NULL)
+	{
+		fprintf(stderr, "You must specify an archive file.\n");
+		exit(1);
+	}
+
+	if (operation == 0)
+	{
+		fprintf(stderr, "You must specify an operation.\n");
+		exit(1);
+	}
+
+	if (operation == LWAR_OP_LIST || operation == LWAR_OP_REMOVE)
+	{
+		struct stat stbuf;
+		// make sure the archive exists
+		if (stat(archive_file, &stbuf) < 0)
+		{
+			fprintf(stderr, "Cannot open archive file %s:\n", archive_file);
+			perror("");
+			exit(2);
+		}
+	}
+	if (operation == LWAR_OP_CREATE)
+	{
+		struct stat stbuf;
+		// check if the archive exists
+		if (stat(archive_file, &stbuf) < 0)
+		{
+			if (errno != ENOENT)
+			{
+				fprintf(stderr, "Cannot create archive file %s:\n", archive_file);
+				perror("");
+				exit(2);
+			}
+		}
+		else
+		{
+			if (unlink(archive_file) < 0)
+			{
+				fprintf(stderr, "Cannot create archive file %s:\n", archive_file);
+				perror("");
+				exit(2);
+			}
+				
+		}
+	}
 	
+	switch (operation)
+	{
+	case LWAR_OP_LIST:
+		do_list();
+		break;
+	
+	case LWAR_OP_ADD:
+	case LWAR_OP_CREATE:
+		do_add();
+		break;
+	
+	case LWAR_OP_REMOVE:
+		do_remove();
+		break;
+	
+	}
+
 	exit(0);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwar/remove.c	Sun Mar 01 22:59:52 2009 +0000
@@ -0,0 +1,33 @@
+/*
+remove.c
+Copyright © 2009 William Astle
+
+This file is part of LWAR.
+
+LWAR 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 3 of the License, or (at your option) any later
+version.
+
+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 <http://www.gnu.org/licenses/>.
+
+
+Implements the program startup code
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "lwar.h"
+
+void do_remove(void)
+{
+}