diff options
| -rw-r--r-- | src/alf.c | 146 |
1 files changed, 60 insertions, 86 deletions
@@ -7,6 +7,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #ifndef u8 #define u8 unsigned char @@ -17,7 +18,7 @@ #define MAX_BITS 12 #define MAX_TOKENS (1 << MAX_BITS) #define TOK_RESET 256 -#define TOK_INCBITS 257 +#define TOK_END 257 #define INIT_TOKEN 258 /* 256 = reset dict, 257 = token_bits++ */ #define MAX_INPUT_SIZE (1 << 24) @@ -40,6 +41,7 @@ int token_bits; int max_token; int curr_token; long hdr_compsize_pos; +int in_pos; void init_table(void) { int i; @@ -57,53 +59,75 @@ void init_table(void) { } } -#if 0 -void writequad(unsigned long data) { +void store_quad(int pos, unsigned long data) { int i; for(i = 0; i < 4; i++) { - fputc(data & 0xff, out_file); + output_buf[pos++] = data & 0xff; data >>= 8; } } -void write_cksum(void) { +void store_cksum(void) { int i; u16 cksum = 0; for(i = 0; i < input_len; i++) cksum += input_buf[i]; - fputc(cksum & 0xff, out_file); - fputc(cksum >> 8, out_file); + output_buf[23] = cksum & 0xff; + output_buf[24] = cksum >> 8; } -#endif -void store_quad(int pos, unsigned long data) { +/* examples: + foo => FOO. + toolongfile => TOOLONGF. (really should be TOOLONGF.ILE) + regular.txt => REGULAR.TXT + too.many.dots => TOO.MAN + */ +void atarify_filename(char *result) { int i; + char name[9], ext[4], *p; - for(i = 0; i < 4; i++) { - output_buf[pos++] = data & 0xff; - data >>= 8; + p = strrchr(in_filename, '/'); + if(p) + p++; + else + p = (char *)in_filename; + + strncpy(name, p, 8); + for(i = 0; i < 8; i++) { + if(!name[i]) break; + if(name[i] == '.') { + name[i] = '\0'; + break; + } } -} -void store_cksum(void) { - int i; - u16 cksum = 0; + strcpy(result, name); + strcat(result, "."); - for(i = 0; i < input_len; i++) - cksum += input_buf[i]; + p = strchr(in_filename, '.'); + if(p) { + p++; + strncpy(ext, p, 3); + for(p = ext; *p; p++) + if(*p == '.') *p = 0; + } - output_buf[23] = cksum & 0xff; - output_buf[24] = cksum >> 8; + strcat(result, ext); + for(p = result; *p; p++) + *p = toupper(*p); } void create_header(void) { + char hdr_filename[13]; + + atarify_filename(hdr_filename); + output_buf[0] = 0x1a; output_buf[1] = 0x0f; - /* TODO: atari-ize filename */ - strncat((char *)&output_buf[2], in_filename, 13); + strncat((char *)&output_buf[2], hdr_filename, 13); output_buf[14] = 0x00; store_quad(15, 0); /* compressed size, fill in later */ store_quad(19, 0); /* date/time (TODO: real timestamp) */ @@ -112,35 +136,6 @@ void create_header(void) { output_len = 29; } -#if 0 -void write_header(void) { - /* TODO: atari-ize the filename */ - fwrite("\x1a\x0f", 1, 2, out_file); - fwrite(in_filename, 1, 12, out_file); /* TODO: capitalize, etc */ - fwrite("\0", 1, 1, out_file); - if((hdr_compsize_pos = ftell(out_file)) < 0) { - perror("ftell"); - exit(1); - } - writequad(0); /* compressed size, will fill in later */ - writequad(0); /* TODO: real timestamps */ - write_cksum(); - writequad(input_len); - exit(0); -} -#endif - -/* -void update_header(void) { - if(fseek(out_file, hdr_compsize_pos, SEEK_SET) < 0) { - perror("fseek"); - exit(1); - } - writequad(output_len); - fseek(out_file, 0, SEEK_END); -} -*/ - void update_header(void) { store_quad(15, output_len - 29); } @@ -153,15 +148,6 @@ void open_input(const char *filename) { } } -/* -void dump_table(void) { - int i, j; - printf("tokens: %d\n", curr_token); - for(i = INIT_TOKEN; i < curr_token; i++) { - } -} -*/ - void append_bit(int bit) { output_buf[output_len] |= (bit << (7 - out_bitpos)); out_bitpos++; @@ -176,29 +162,14 @@ void store_token(int tok) { for(mask = 1 << (token_bits - 1); mask; mask >>= 1) { append_bit(tok & mask ? 1 : 0); - // printf("%d", tok & mask ? 1 : 0); } - // putchar('\n'); - - #if 0 - if(tok == ' ') - printf("\" \""); - else if(tok > 255) - printf("tok(%d)", tok - 256); - else if(tok < ' ' || tok > 126) - printf("$%02x", tok); - else - printf("%c", tok); - putchar('\n'); - #endif - } int match_token(int pos) { int i, bestmatch = -1; for(i = 0; i < curr_token; i++) { - if(i == TOK_RESET || i == TOK_INCBITS) + if(i == TOK_RESET || i == TOK_END) continue; if(memcmp(&input_buf[pos], tokentab[i].start, tokentab[i].length) == 0) bestmatch = i; @@ -213,24 +184,27 @@ int match_token(int pos) { } void make_token(int start, int end) { - tokentab[curr_token].start = &input_buf[start]; - tokentab[curr_token].length = end - start + 1; - curr_token++; if(curr_token == max_token) { - store_token(TOK_INCBITS); - if(token_bits == 12) { - store_token(TOK_RESET); + printf("%d: curr_token %d == max_token, ", in_pos, curr_token); + if(token_bits == MAX_BITS) { + printf("token_bits %d == MAX_BITS, reset\n", token_bits); token_bits = 9; + store_token(TOK_RESET); init_table(); } else { + printf("token_bits %d < MAX_BITS, inc\n", token_bits); token_bits++; } max_token = 1 << token_bits; } + tokentab[curr_token].start = &input_buf[start]; + tokentab[curr_token].length = end - start + 1; + curr_token++; } void crunch(void) { - int in_pos = 0, new_pos; + int new_pos; + in_pos = 0; int token; out_bitpos = 0; @@ -247,7 +221,7 @@ void crunch(void) { in_pos = new_pos; } - store_token(TOK_INCBITS); + store_token(TOK_END); if(out_bitpos) output_len++; update_header(); } @@ -263,12 +237,12 @@ void crunch_file(const char *filename) { output_len = 0; fclose(in_file); + memset(output_buf, 0, sizeof(output_buf)); + create_header(); crunch(); fwrite(output_buf, 1, output_len, out_file); - - // dump_table(); } int main(int argc, char **argv) { |
