diff --git a/bobbi/README.md b/bobbi/README.md index 519f23d..142dda0 100644 --- a/bobbi/README.md +++ b/bobbi/README.md @@ -1,3 +1,23 @@ -** DO NOT USE THIS CODE YET ** +** THIS IS ALPHA-QUALITY CODE ** +** USE AT YOUR OWN RISK! ** + +usage: sortdir [-s xxx] [-rwv] path\n + Options: -s xxx Directory sort options + -w Enable writing to disk + -v Verbose output + -h This help + +Directory sort options xxx, is a list of fields on which to +sort. The sort options are processed left-to-right. + n sort by filename ascending + N sort by filename descending + t sort by type ascending + T sort by type descending + d sort directories to top + D sort directories to bottom + +e.g.: sortdir -w -s nd . +Will sort the current directory first by name (ascending), +then sort directories to the top, and will write the sorted +directory to disk. -** WORK-IN-PROGRESS ** diff --git a/bobbi/sortdir.c#b00008 b/bobbi/sortdir.c#b00008 index 0f7e612..62b50ad 100644 --- a/bobbi/sortdir.c#b00008 +++ b/bobbi/sortdir.c#b00008 @@ -1,9 +1,8 @@ /* * Bobbi January 2020 * - * TODO: Fix bugs!!!! - * TODO: Sort by type, combinations etc. - * TODO: Improve checking code + * TODO: Improve filesystem checking code + * TODO: Improve output */ #pragma debug 25 /* Enable stack checking */ @@ -21,7 +20,7 @@ #include -#define DEBUG /* Enable additional debug printout */ +#undef DEBUG /* Enable additional debug printout */ #define CHECK /* Perform additional integrity checking */ typedef unsigned char uchar; @@ -89,7 +88,9 @@ struct block { * Entry for array of filenames used by qsort() */ struct fileent { - char name[NMLEN+1]; /* Name converted to upper/lower case */ + char name[NMLEN+1];/* Name converted to upper/lower case */ + uchar type; /* ProDOS file type */ + uint order; /* Hack to make qsort() stable */ uchar blockidx; /* Index of dir block (1,2,3 ...) */ uchar entrynum; /* Entry within the block */ }; @@ -102,8 +103,8 @@ static uchar entsz; /* Bytes per file entry */ static uchar entperblk; /* Number of entries per block */ static char buf[BLKSZ]; /* General purpose scratch buffer */ static uchar dowrite = 0; -static uchar doreverse = 0; static uchar doverbose = 0; +static char sortopts[5] = "n"; static uint stack; // DEBUG @@ -121,8 +122,13 @@ int readdiskblock(uchar device, uint blocknum, char *buf); int writediskblock(uchar device, uint blocknum, char *buf); void fixcase(char *in, char *out, uchar minvers, uchar vers); int readdir(uint device, uint blocknum); -int compare(const void *a, const void *b); -void sortlist(void); +int cmp_name_asc(const void *a, const void *b); +int cmp_name_desc(const void *a, const void *b); +int cmp_type_asc(const void *a, const void *b); +int cmp_type_desc(const void *a, const void *b); +int cmp_dir_beg(const void *a, const void *b); +int cmp_dir_end(const void *a, const void *b); +void sortlist(char s); void printlist(void); void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent, uint device); void sortblocks(uint device); @@ -408,6 +414,7 @@ int readdir(uint device, uint blocknum) { filelist[numfiles].name[i] = '\0'; for (uchar 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; #ifdef CHECK @@ -494,26 +501,114 @@ int readdir(uint device, uint blocknum) { } /* - * Compare two filenames + * Compare - filename sort in ascending order */ -int compare(const void *a, const void *b) { - int rc; - rc = strncmp(((struct fileent*)a)->name, - ((struct fileent*)b)->name, 15); - return (doreverse ? -rc : rc); +int cmp_name_asc(const void *a, const void *b) { + return strncmp(((struct fileent*)a)->name, + ((struct fileent*)b)->name, NMLEN); +} + +/* + * Compare - filename sort in descending order + */ +int cmp_name_desc(const void *a, const void *b) { + return strncmp(((struct fileent*)b)->name, + ((struct fileent*)a)->name, NMLEN); +} + +/* + * Compare - type sort in ascending order + * Uses the order field to make qsort() stable + */ +int cmp_type_asc(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + int rc = aa->type - bb->type; + return rc != 0 ? rc : aa->order - bb->order; +} +/* + * Compare - type sort in descending order + * Uses the order field to make qsort() stable + */ +int cmp_type_desc(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + int rc = bb->type - aa->type; + return rc != 0 ? rc : aa->order - bb->order; +} + +/* + * Compare - sort with directories at the beginning + * Uses the order field to make qsort() stable + */ +int cmp_dir_beg(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + if ((aa->type == 0x0f) && (bb->type != 0x0f)) + return -1; + if ((bb->type == 0x0f) && (aa->type != 0x0f)) + return 1; + return aa->order - bb->order; +} + +/* + * Compare - sort with directories at the end + * Uses the order field to make qsort() stable + */ +int cmp_dir_end(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + if ((aa->type == 0x0f) && (bb->type != 0x0f)) + return 1; + if ((bb->type == 0x0f) && (aa->type != 0x0f)) + return -1; + return aa->order - bb->order; } /* * Sort filelist[] + * s defines the field to sort on */ -void sortlist(void) { - qsort(filelist, numfiles, sizeof(struct fileent), compare); +void sortlist(char s) { + for(uint i=0; inext; - } -} -#endif - int main(int argc, char *argv[]) { if (argc < 2) { usage(); exit(1); } int opt; - while ((opt = getopt(argc, argv, "rwv")) != -1) { + while ((opt = getopt(argc, argv, "hwvs:")) != -1) { switch (opt) { - case 'r': - doreverse = 1; + case 's': + strncpy(sortopts, optarg, 5); break; case 'w': dowrite = 1; @@ -661,6 +760,7 @@ int main(int argc, char *argv[]) { case 'v': doverbose = 1; break; + case 'h': default: usage(); } @@ -678,8 +778,11 @@ int main(int argc, char *argv[]) { if (!err) { if (doverbose) printlist(); - sortlist(); + for (uchar i=0; i