From f102a7723a9f12a0699fa7c472955d4617f2f1b9 Mon Sep 17 00:00:00 2001 From: Bobbi Webber-Manners Date: Sun, 31 May 2020 17:32:13 -0400 Subject: [PATCH] Made fileent a few bytes smaller. Fixed folder sort. Improved maxfiles check. --- sortdir.c | 98 ++++++++++++++++++++++++----------------------------- sortdir.po | Bin 143360 -> 143360 bytes 2 files changed, 45 insertions(+), 53 deletions(-) diff --git a/sortdir.c b/sortdir.c index 451e4fb..6477663 100644 --- a/sortdir.c +++ b/sortdir.c @@ -1,14 +1,14 @@ /* * SORTDIR - for Apple II (ProDOS) * - * Bobbi January-March 2020 + * Bobbi January-June 2020 * + * TODO: Multilevel sort is currently broken. Consider how to fix it in a + * memory efficient way. * TODO: IDEA you only need one sorteddata block at a time. Do not allocate * until writeout time and use one block buffer. Iterate through * filelist[] collecting all entries for block 1, 2, 3 in turn. * Huge aux memory savings!! - * TODO: filent can be a couple bytes smaller. - * TODO: Obsolete MAXFILES is hardcoded - need a better way to do this * TODO: Check for no memory when allocating aux memory * TODO: Enable free list functionality on ProDOS-8 * TODO: Get both ProDOS-8 and GNO versions to build from this source @@ -19,13 +19,14 @@ * v0.51 Made buf[] and buf2[] dynamic. * v0.52 Support for aux memory. * v0.53 Auto-sizing of filelist[] to fit available memory. - * v0.54 Make command line argument handling a compile time option - * v0.55 Can use *all* of largest heap block for filelist[] - * v0.56 Minor improvements to conditional compilation - * v0.57 Fixed bugs in aux memory allocation, memory zeroing bug - * v0.58 Fixed more bugs. Now working properly using aux memory + * v0.54 Make command line argument handling a compile time option. + * v0.55 Can use *all* of largest heap block for filelist[]. + * v0.56 Minor improvements to conditional compilation. + * v0.57 Fixed bugs in aux memory allocation, memory zeroing bug. + * v0.58 Fixed more bugs. Now working properly using aux memory. * v0.59 Moved creation of filelist[] into buildsorttable(). More bugfix. * v0.60 Modified fileent to be a union. Build it for each subsort. Saves RAM. + * v0.61 Squeezed fileent to be a few bytes smaller. Fixed folder sort. */ //#pragma debug 9 @@ -61,7 +62,6 @@ typedef unsigned int uint; typedef unsigned long ulong; #define NMLEN 15 /* Length of filename */ -#define MAXFILES 220 /* Max files per directory */ /* * ProDOS directory header @@ -138,15 +138,17 @@ struct block { struct fileent { uchar blockidx; /* Index of dir block (1,2,3 ...) */ uchar entrynum; /* Entry within the block */ - uint order; /* Hack to make qsort() stable */ -// TODO: Can make this a couple bytes smaller union { - char name[NMLEN+1]; /* Name converted to upper/lower case */ - char datetime[20]; /* Date/time as a yyyy-mm-dd hh:mm string */ + char name[NMLEN-2]; /* Name converted to upper/lower case */ + char datetime[12+1];/* Date/time as a yyyymmddhhmm string */ uchar type; /* ProDOS file type */ uint blocks; /* Size in blocks */ ulong eof; /* EOF position in bytes */ }; + /* NOTE: Because name is unique we do not need the order field to make + * the sort stable, so we can let the name buffer overflow by 2 bytes + */ + uint order; /* Hack to make qsort() stable */ }; /* @@ -186,6 +188,7 @@ static char currdir[NMLEN+1]; /* Name of directory currently processed */ static struct block *blocks = NULL; static struct dirblk *dirs = NULL; static uint numfiles; +static uint maxfiles; /* Size of filelist[] */ static uchar entsz; /* Bytes per file entry */ static uchar entperblk; /* Number of entries per block */ static uint errcount = 0; /* Error counter */ @@ -245,6 +248,7 @@ int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent, uint blocknum, uint blkentries, uint *blkcnt); void enqueuesubdir(uint blocknum, uint subdiridx); int readdir(uint device, uint blocknum); +#ifdef SORT void buildsorttable(char s); int cmp_name_asc(const void *a, const void *b); int cmp_name_desc(const void *a, const void *b); @@ -262,6 +266,7 @@ int cmp_eof_asc(const void *a, const void *b); int cmp_eof_desc(const void *a, const void *b); int cmp_noop(const void *a, const void *b); void sortlist(char s); +#endif void printlist(void); uint blockidxtoblocknum(uint idx); void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent, uint device); @@ -1207,23 +1212,6 @@ int readdir(uint device, uint blocknum) { blks = ent->blksused[0] + 256U * ent->blksused[1]; eof = ent->eof[0] + 256L * ent->eof[1] + 65536L * ent->eof[2]; -/*** - bzero(filelist[numfiles].name, NMLEN + 1); - for (i = 0; i < (ent->typ_len & 0x0f); ++i) - filelist[numfiles].name[i] = namebuf[i]; - filelist[numfiles].type = ent->type; - filelist[numfiles].blockidx = blkcnt; - filelist[numfiles].entrynum = blkentries; - filelist[numfiles].blocks = blks; - filelist[numfiles].eof = eof; - - readdatetime(do_ctime ? ent->ctime : ent->mtime, &dt); - sprintf(filelist[numfiles].datetime, - "%04d-%02d-%02d %02d:%02d %s", - dt.year, dt.month, dt.day, dt.hour, dt.minute, - (dt.ispd25format ? "*" : " ")); -***/ - keyblk = ent->keyptr[0] + 256U * ent->keyptr[1]; hdrblk = ent->hdrptr[0] + 256U * ent->hdrptr[1]; #ifdef CHECK @@ -1289,7 +1277,7 @@ int readdir(uint device, uint blocknum) { } #endif ++numfiles; - if (numfiles == MAXFILES) { + if (numfiles == maxfiles) { err(NONFATAL, "Too many files!\n"); return 1; } @@ -1369,6 +1357,8 @@ int readdir(uint device, uint blocknum) { return errcount - errsbefore; } +#ifdef SORT + /* * Build filelist[], the table used by the sorting algorithm. */ @@ -1402,10 +1392,11 @@ void buildsorttable(char s) { case 'i': fixcase(ent->name, namebuf, ent->vers, ent->minvers, ent->typ_len & 0x0f); - bzero(filelist[idx].name, NMLEN + 1); + bzero(filelist[idx].name, NMLEN); for (i = 0; i < (ent->typ_len & 0x0f); ++i) filelist[idx].name[i] = namebuf[i]; break; + case 'f': case 't': filelist[idx].type = ent->type; break; @@ -1419,10 +1410,8 @@ void buildsorttable(char s) { break; case 'd': readdatetime(do_ctime ? ent->ctime : ent->mtime, &dt); - sprintf(filelist[idx].datetime, - "%04d-%02d-%02d %02d:%02d %s", - dt.year, dt.month, dt.day, dt.hour, dt.minute, - (dt.ispd25format ? "*" : " ")); + sprintf(filelist[idx].datetime, "%04d%02d%02d%02d%02d", + dt.year, dt.month, dt.day, dt.hour, dt.minute); break; } ++idx; @@ -1435,8 +1424,6 @@ void buildsorttable(char s) { numfiles = idx; } -#ifdef SORT - /* * Compare - filename sort in ascending order */ @@ -1593,21 +1580,25 @@ int cmp_noop(const void *a, const void *b) { return aa->order - bb->order; } -#endif - /* * Sort filelist[] * s defines the field to sort on */ void sortlist(char s) { uint i; + char ss = tolower(s); -#ifndef SORT - return; -#else - for (i = 0; i < numfiles; ++i) { - filelist[i].order = i; + /* + * We only populate the order field when NOT sorting by name. + * This lets us save two bytes by overflowing the name field into the + * order field. + */ + if ((ss != 'n') && (ss != 'i')) { + for (i = 0; i < numfiles; ++i) { + filelist[i].order = i; + } } + switch (s) { case 'n': qsort(filelist, numfiles, sizeof(struct fileent), @@ -1672,9 +1663,10 @@ void sortlist(char s) { default: err(FATALBADARG, "Invalid sort option"); } -#endif } +#endif + /* * Print the file info stored in filelist[] */ @@ -1831,7 +1823,7 @@ void interactive(void) { doverbose = 1; - puts("S O R T D I R v0.60 alpha Use ^ to return to previous question"); + puts("S O R T D I R v0.61 alpha Use ^ to return to previous question"); q1: fputs("\nEnter path (e.g.: /H1) of starting directory> ", stdout); @@ -1954,6 +1946,7 @@ void processdir(uint device, uint blocknum) { err(NONFATAL, "Error scanning directory, will not sort\n"); goto done; } +#ifdef SORT if (strlen(sortopts) > 0) { if (doverbose) fputs("Sorting: ", stdout); @@ -1962,12 +1955,10 @@ void processdir(uint device, uint blocknum) { printf("[%c] ", sortopts[i]); buildsorttable(sortopts[i]); sortlist(sortopts[i]); + sortblocks(device); } if (doverbose) putchar('\n'); -#ifdef SORT - sortblocks(device); -#endif //if (doverbose) { // printlist(); //} @@ -1977,6 +1968,7 @@ void processdir(uint device, uint blocknum) { } else puts("** NOT writing dir"); } +#endif done: freeblocks(); #ifdef AUXMEM @@ -2179,9 +2171,9 @@ int main() { buf2 = (char*)malloc(sizeof(char) * BLKSZ); dirblkbuf = (char*)malloc(sizeof(char) * BLKSZ); //printf("\nHeap: %u %u\n", _heapmemavail(), _heapmaxavail()); - blk = _heapmaxavail() / sizeof(struct fileent); - printf("[%u]\n", blk); - filelist = (struct fileent*)malloc(sizeof(struct fileent) * blk); + maxfiles = _heapmaxavail() / sizeof(struct fileent); + printf("[%u]\n", maxfiles); + filelist = (struct fileent*)malloc(sizeof(struct fileent) * maxfiles); #ifdef CMDLINE parseargs(); diff --git a/sortdir.po b/sortdir.po index c756b2de96e0801cf3517849a3ae0d46bdc98e16..58df2df5be0a517a4af39b28d28cc6a4e167e44d 100644 GIT binary patch delta 23177 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