aboutsummaryrefslogtreecommitdiff
path: root/src/extract.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-11-14 04:22:39 -0500
committerB. Watson <urchlay@slackware.uk>2025-11-14 04:22:39 -0500
commite286ed23ae3cabfb75327d8512dc937b2ecf9be1 (patch)
treea39a2494cdcca3145f283a515bfa42eb5f33e0df /src/extract.c
parente2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6 (diff)
downloadunalf-e286ed23ae3cabfb75327d8512dc937b2ecf9be1.tar.gz
Add command-line options.
Diffstat (limited to 'src/extract.c')
-rw-r--r--src/extract.c75
1 files changed, 65 insertions, 10 deletions
diff --git a/src/extract.c b/src/extract.c
index 079fe7f..4f761e4 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -1,9 +1,14 @@
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
#include <f65.h>
#include "unalf.h"
#include "addrs.h"
+char *out_filename;
+
void dpoke(int addr, u16 value) {
mem[addr] = value & 0xff;
mem[addr + 1] = value >> 8;
@@ -13,29 +18,79 @@ u16 dpeek(int addr) {
return mem[addr] | (mem[addr + 1] << 8);
}
-void extract_alf(void) {
- char *filename;
+void fix_filename(void) {
+ char *p;
+
+ if(!out_filename) return;
+
+ if(opts.lowercase) {
+ for(p = out_filename; *p; p++)
+ *p = tolower(*p);
+ }
+
+ if(!opts.keepdot) {
+ for(p = out_filename; *p; p++)
+ if(p[0] == '.' && !p[1])
+ *p = '\0';
+ }
+}
+
+void make_backup(void) {
+ char backup[PATH_MAX];
+
+ strcpy(backup, out_filename);
+ strcat(backup, "~");
+ /* silently ignore errors! */
+ rename(out_filename, backup);
+}
+
+void extract_alf(void) {
/* get ready to call fake 6502 stuff. set up memory like the Atari. */
dpoke(MEMTOP, 0xbc1f);
while(read_alf_header()) {
- filename = (char *)(mem + alf_hdr_filename);
- printf("Uncrunching %s\n", filename);
+ out_filename = (char *)(mem + alf_hdr_filename);
- if(!(out_file = fopen(filename, "wb"))) {
- fprintf(stderr, "%s: ", self);
- perror(filename);
- exit(1);
+ fix_filename();
+
+ if(!file_wanted(out_filename)) {
+ if(fseek(in_file, getquad(alf_hdr_compsize0), SEEK_CUR) != 0) {
+ fputs(self, stderr);
+ perror(": fseek");
+ exit(1);
+ }
+ out_filename = 0;
+ continue;
+ }
+
+ if(!opts.quiet) {
+ printf("%s %s\n", opts.testonly ? "Testing" : "Uncrunching", out_filename);
+ }
+
+ if(opts.extract_to_stdout) {
+ out_file = stdout;
+ } else {
+ if(opts.testonly) {
+ out_filename = "/dev/null";
+ } else if(!opts.overwrite) {
+ make_backup();
+ }
+ if(!(out_file = fopen(out_filename, "wb"))) {
+ perror(out_filename);
+ exit(1);
+ }
}
uncrunch_file();
- fclose(out_file);
+
+ if(!opts.extract_to_stdout) fclose(out_file);
+ out_filename = 0;
}
}
static void chksum_err(void) {
- fprintf(stderr, "%s: checksum error on file %s\n", self, in_filename);
+ fprintf(stderr, "%s: checksum error on file %s\n", self, out_filename);
}
void uncrunch_file(void) {