Reinstated no-op sort. Improved directory trimming code.

This commit is contained in:
Bobbi Webber-Manners 2020-06-14 02:24:50 -04:00
parent 7a4fabd990
commit aad021cbd2

View File

@ -3,10 +3,9 @@
* *
* Bobbi January-June 2020 * Bobbi January-June 2020
* *
* TODO: *** When trimming dirs fix EOF in directory header ***
* TODO: Trimming unused directory blocks * TODO: Trimming unused directory blocks
* TODO: Don't trim volume directory to <4 blocks * TODO: Don't trim volume directory to <4 blocks
* TODO: *** When trimming dirs fix EOF in directory header ***
* TODO: no-op sort is useful after all - reinstate it
* TODO: Get both ProDOS-8 and GNO versions to build from this source * TODO: Get both ProDOS-8 and GNO versions to build from this source
* *
* Revision History * Revision History
@ -40,6 +39,7 @@
* v0.77 Implemented zeroblock() for ProDOS-8. * v0.77 Implemented zeroblock() for ProDOS-8.
* v0.78 Improved error handling when too many files to sort. * v0.78 Improved error handling when too many files to sort.
* v0.79 Trim unused directory blocks after sorting. Write freelist to disk. * v0.79 Trim unused directory blocks after sorting. Write freelist to disk.
* v0.80 Reinstated no-op sort (useful for compacting dir without reordering)
*/ */
//#pragma debug 9 //#pragma debug 9
@ -68,6 +68,7 @@
#define FREELIST /* Checking of free list */ #define FREELIST /* Checking of free list */
#define AUXMEM /* Auxiliary memory support on //e and up */ #define AUXMEM /* Auxiliary memory support on //e and up */
#undef CMDLINE /* Command line option parsing */ #undef CMDLINE /* Command line option parsing */
#define TRIMDIR /* Enable trimming of directory blocks */
#define NLEVELS 4 /* Number of nested sorts permitted */ #define NLEVELS 4 /* Number of nested sorts permitted */
@ -295,7 +296,7 @@ int readfreelist(uchar device);
int isfree(uint blk); int isfree(uint blk);
int isused(uint blk); int isused(uint blk);
void markused(uint blk); void markused(uint blk);
void marknotused(uint blk); void trimdirblock(uint blk);
void checkblock(uint blk, char *msg); void checkblock(uint blk, char *msg);
#endif #endif
#ifdef CHECK #ifdef CHECK
@ -324,6 +325,7 @@ int cmp_blocks_asc(const void *a, const void *b);
int cmp_blocks_desc(const void *a, const void *b); int cmp_blocks_desc(const void *a, const void *b);
int cmp_eof_asc(const void *a, const void *b); int cmp_eof_asc(const void *a, const void *b);
int cmp_eof_desc(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); void sortlist(char s);
#endif #endif
void printlist(void); void printlist(void);
@ -898,9 +900,9 @@ void markused(uint blk) {
} }
/* /*
* Mark a block as not used * Mark a block as not used and add it to freelist
*/ */
void marknotused(uint blk) { void trimdirblock(uint blk) {
uchar temp; uchar temp;
uint idx = blk / 8; uint idx = blk / 8;
uint bit = blk % 8; uint bit = blk % 8;
@ -908,8 +910,12 @@ void marknotused(uint blk) {
copyaux(usedlist + idx, &temp, 1, FROMAUX); copyaux(usedlist + idx, &temp, 1, FROMAUX);
temp &= ~(0x80 >> bit); temp &= ~(0x80 >> bit);
copyaux(&temp, usedlist + idx, 1, TOAUX); copyaux(&temp, usedlist + idx, 1, TOAUX);
copyaux(freelist + idx, &temp, 1, FROMAUX);
temp |= (0x80 >> bit);
copyaux(&temp, freelist + idx, 1, TOAUX);
#else #else
usedlist[idx] |= (0x80 >> bit); usedlist[idx] &= ~(0x80 >> bit);
freelist[idx] |= (0x80 >> bit);
#endif #endif
} }
@ -1638,7 +1644,7 @@ int cmp_dir_end(const void *a, const void *b) {
/* /*
* Compare - sort in increasing order of blocks used * Compare - sort in increasing order of blocks used
*/ */
int cmp_blocks_asc(const void *a, const void *b) { int cmp_blocks_asc(const void *a, const void *b) {
struct fileent *aa = (struct fileent*)a; struct fileent *aa = (struct fileent*)a;
struct fileent *bb = (struct fileent*)b; struct fileent *bb = (struct fileent*)b;
int rc = aa->blocks - bb->blocks; int rc = aa->blocks - bb->blocks;
@ -1648,7 +1654,7 @@ int cmp_blocks_asc(const void *a, const void *b) {
/* /*
* Compare - sort in decreasing order of blocks used * Compare - sort in decreasing order of blocks used
*/ */
int cmp_blocks_desc(const void *a, const void *b) { int cmp_blocks_desc(const void *a, const void *b) {
struct fileent *aa = (struct fileent*)a; struct fileent *aa = (struct fileent*)a;
struct fileent *bb = (struct fileent*)b; struct fileent *bb = (struct fileent*)b;
int rc = bb->blocks - aa->blocks; int rc = bb->blocks - aa->blocks;
@ -1658,7 +1664,7 @@ int cmp_blocks_desc(const void *a, const void *b) {
/* /*
* Compare - sort in increasing order of EOF position * Compare - sort in increasing order of EOF position
*/ */
int cmp_eof_asc(const void *a, const void *b) { int cmp_eof_asc(const void *a, const void *b) {
struct fileent *aa = (struct fileent*)a; struct fileent *aa = (struct fileent*)a;
struct fileent *bb = (struct fileent*)b; struct fileent *bb = (struct fileent*)b;
long diff = aa->eof - bb->eof; long diff = aa->eof - bb->eof;
@ -1673,7 +1679,7 @@ int cmp_eof_asc(const void *a, const void *b) {
/* /*
* Compare - sort in decreasing order of EOF position * Compare - sort in decreasing order of EOF position
*/ */
int cmp_eof_desc(const void *a, const void *b) { int cmp_eof_desc(const void *a, const void *b) {
struct fileent *aa = (struct fileent*)a; struct fileent *aa = (struct fileent*)a;
struct fileent *bb = (struct fileent*)b; struct fileent *bb = (struct fileent*)b;
long diff = bb->eof - aa->eof; long diff = bb->eof - aa->eof;
@ -1685,6 +1691,15 @@ int cmp_eof_desc(const void *a, const void *b) {
return -1; return -1;
} }
/*
* Compare - no-op compare which leaves order unchanged
*/
int cmp_noop(const void *a, const void *b) {
struct fileent *aa = (struct fileent*)a;
struct fileent *bb = (struct fileent*)b;
return aa->order - bb->order;
}
/* /*
* Sort filelist[] * Sort filelist[]
* s defines the field to sort on * s defines the field to sort on
@ -1706,62 +1721,51 @@ void sortlist(char s) {
switch (s) { switch (s) {
case 'n': case 'n':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_name_asc);
cmp_name_asc);
break; break;
case 'N': case 'N':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_name_desc);
cmp_name_desc);
break; break;
case 'i': case 'i':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_name_asc_ci);
cmp_name_asc_ci);
break; break;
case 'I': case 'I':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_name_desc_ci);
cmp_name_desc_ci);
break; break;
case 'c': case 'c':
case 'm': case 'm':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_datetime_asc);
cmp_datetime_asc);
break; break;
case 'C': case 'C':
case 'M': case 'M':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_datetime_desc);
cmp_datetime_desc);
break; break;
case 't': case 't':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_type_asc);
cmp_type_asc);
break; break;
case 'T': case 'T':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_type_desc);
cmp_type_desc);
break; break;
case 'd': case 'd':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_dir_beg);
cmp_dir_beg);
break; break;
case 'D': case 'D':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_dir_end);
cmp_dir_end);
break; break;
case 'b': case 'b':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_blocks_asc);
cmp_blocks_asc);
break; break;
case 'B': case 'B':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_blocks_desc);
cmp_blocks_desc);
break; break;
case 'e': case 'e':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_eof_asc);
cmp_eof_asc);
break; break;
case 'E': case 'E':
qsort(filelist, numfiles, sizeof(struct fileent), qsort(filelist, numfiles, sizeof(struct fileent), cmp_eof_desc);
cmp_eof_desc); break;
case '.':
qsort(filelist, numfiles, sizeof(struct fileent), cmp_noop);
break; break;
default: default:
err(FATALBADARG, err_invopt, "sort"); err(FATALBADARG, err_invopt, "sort");
@ -1900,10 +1904,14 @@ uchar writedir(uchar device) {
err(NONFATAL, err_wtblk1, b->blocknum); err(NONFATAL, err_wtblk1, b->blocknum);
return 1; return 1;
} }
#ifdef TRIMDIR
} else { } else {
puts("Trimming dir blk"); puts("Trimming dir blk");
marknotused(b->blocknum); trimdirblock(b->blocknum);
} }
#else
}
#endif
b = b->next; b = b->next;
} }
return 0; return 0;
@ -1966,7 +1974,7 @@ void interactive(void) {
revers(1); revers(1);
hlinechar(' '); hlinechar(' ');
fputs("S O R T D I R v0.79 alpha Use ^ to return to previous question", stdout); fputs("S O R T D I R v0.80 alpha Use ^ to return to previous question", stdout);
hlinechar(' '); hlinechar(' ');
revers(0); revers(0);
@ -2003,12 +2011,12 @@ q3:
fputs("| Lower case option ascending order, upper case option descending order |", stdout); fputs("| Lower case option ascending order, upper case option descending order |", stdout);
fputs("| [nN] Name | [iI] Name (case-insens) | [tT] Type | [dD] Directories |", stdout); fputs("| [nN] Name | [iI] Name (case-insens) | [tT] Type | [dD] Directories |", stdout);
fputs("| [cC] Creation | [mM] Modification | [bB] Blocks | [eE] EOF Position |", stdout); fputs("| [cC] Creation | [mM] Modification | [bB] Blocks | [eE] EOF Position |", stdout);
fputs("| [-] Done | | | |", stdout); fputs("| [-] Done | [.] Just compact dir | | |", stdout);
for (level = 0; level < NLEVELS; ++level) { for (level = 0; level < NLEVELS; ++level) {
do { do {
printf("\nLevel %d > ", level+1); printf("\nLevel %d > ", level+1);
sortopts[level] = getchar(); sortopts[level] = getchar();
} while (strchr("-nNiItTdDcCmMbBeE^", sortopts[level]) == NULL); } while (strchr("-.nNiItTdDcCmMbBeE^", sortopts[level]) == NULL);
if (sortopts[level] == '-') { if (sortopts[level] == '-') {
sortopts[level] = '\0'; sortopts[level] = '\0';
break; break;