summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools
diff options
context:
space:
mode:
author Nathan Woods <npwoods@mess.org>2016-12-24 13:43:52 -0500
committer Nathan Woods <npwoods@mess.org>2016-12-24 13:45:03 -0500
commit1cd5935dde60c26027339f43fd4ad154daf445ce (patch)
tree0c748a7066099e3816619225813e3a452182c750 /src/tools
parent2f3e89b5dfc57c60950948147841c7bbf5041f94 (diff)
[Imgtool CoCo/RS-DOS] Miscellaneous cleanups and C++ modernization
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/imgtool/imgtool.cpp37
-rw-r--r--src/tools/imgtool/imgtool.h1
-rw-r--r--src/tools/imgtool/modules/rsdos.cpp215
3 files changed, 165 insertions, 88 deletions
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp
index bb7e6c860db..3eb836b6ce3 100644
--- a/src/tools/imgtool/imgtool.cpp
+++ b/src/tools/imgtool/imgtool.cpp
@@ -41,6 +41,11 @@ void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...)
Imgtool initialization and basics
***************************************************************************/
+
+//-------------------------------------------------
+// rtrim
+//-------------------------------------------------
+
void rtrim(char *buf)
{
size_t buflen;
@@ -54,6 +59,11 @@ void rtrim(char *buf)
}
}
+
+//-------------------------------------------------
+// strncpyz
+//-------------------------------------------------
+
char *strncpyz(char *dest, const char *source, size_t len)
{
char *s;
@@ -67,6 +77,33 @@ char *strncpyz(char *dest, const char *source, size_t len)
return s;
}
+
+//-------------------------------------------------
+// extract_padded_string
+//-------------------------------------------------
+
+static std::string extract_padded_string(const char *source, size_t len)
+{
+ while ((len > 0) && (source[len - 1] == ' '))
+ len--;
+ return std::string(source, len);
+}
+
+
+//-------------------------------------------------
+// extract_padded_filename - this is a common
+// enough scenario that it is justified to have
+// this in common code
+//-------------------------------------------------
+
+std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length)
+{
+ std::string filename = extract_padded_string(source, filename_length);
+ std::string extension = extract_padded_string(source + filename_length, extension_length);
+ return extension.empty() ? filename : filename + "." + extension;
+}
+
+
//-------------------------------------------------
// markerrorsource - marks where an error source
//-------------------------------------------------
diff --git a/src/tools/imgtool/imgtool.h b/src/tools/imgtool/imgtool.h
index eb614a9dabb..5640b3cab12 100644
--- a/src/tools/imgtool/imgtool.h
+++ b/src/tools/imgtool/imgtool.h
@@ -266,5 +266,6 @@ void unknown_partition_get_info(const imgtool_class *imgclass, uint32_t state, u
char *strncpyz(char *dest, const char *source, size_t len);
void rtrim(char *buf);
+std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length);
#endif /* IMGTOOL_H */
diff --git a/src/tools/imgtool/modules/rsdos.cpp b/src/tools/imgtool/modules/rsdos.cpp
index 8be6458e45c..9ee8de3cf8c 100644
--- a/src/tools/imgtool/modules/rsdos.cpp
+++ b/src/tools/imgtool/modules/rsdos.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/****************************************************************************
- rsdos.c
+ rsdos.cpp
CoCo RS-DOS disk images
@@ -18,8 +18,7 @@
/* this structure mirrors the structure of an RS-DOS directory entry on disk */
struct rsdos_dirent
{
- char fname[8];
- char fext[3];
+ char filename[11];
char ftype;
char asciiflag;
unsigned char first_granule;
@@ -31,7 +30,7 @@ struct rsdos_dirent
struct rsdos_direnum
{
int index;
- int eof;
+ bool eof;
};
#define RSDOS_OPTIONS_FTYPE 'T'
@@ -44,50 +43,51 @@ struct rsdos_direnum
*********************************************************************/
#define MAX_DIRENTS ((18-2)*(256/32))
-static floperr_t get_rsdos_dirent(imgtool::image &f, int index_loc, struct rsdos_dirent *ent)
+#define MAX_GRANULEMAP_SIZE 256
+
+//-------------------------------------------------
+// get_rsdos_dirent
+//-------------------------------------------------
+
+static floperr_t get_rsdos_dirent(imgtool::image &f, int index_loc, rsdos_dirent &ent)
{
- return floppy_read_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) ent, sizeof(*ent));
+ return floppy_read_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) &ent, sizeof(ent));
}
+//-------------------------------------------------
+// put_rsdos_dirent
+//-------------------------------------------------
-static floperr_t put_rsdos_dirent(imgtool::image &f, int index_loc, const struct rsdos_dirent *ent)
+static floperr_t put_rsdos_dirent(imgtool::image &f, int index_loc, const rsdos_dirent &ent)
{
if (index_loc >= MAX_DIRENTS)
return (floperr_t)IMGTOOLERR_FILENOTFOUND;
- return floppy_write_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) ent, sizeof(*ent), 0); /* TODO: pass ddam argument from imgtool */
+ return floppy_write_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) &ent, sizeof(ent), 0); /* TODO: pass ddam argument from imgtool */
}
+//-------------------------------------------------
+// get_dirent_fname
+//-------------------------------------------------
-/* fnamebuf must have at least 13 bytes */
-static void get_dirent_fname(char *fnamebuf, const struct rsdos_dirent *ent)
+static std::string get_dirent_fname(const rsdos_dirent &ent)
{
- char *s;
-
- memset(fnamebuf, 0, 13);
- memcpy(fnamebuf, ent->fname, sizeof(ent->fname));
- rtrim(fnamebuf);
- s = fnamebuf + strlen(fnamebuf);
- *(s++) = '.';
- memcpy(s, ent->fext, sizeof(ent->fext));
- rtrim(s);
-
- /* If no extension, remove period */
- if (*s == '\0')
- s[-1] = '\0';
+ return extract_padded_filename(ent.filename, 8, 3);
}
+//-------------------------------------------------
+// lookup_rsdos_file
+//-------------------------------------------------
-static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, struct rsdos_dirent *ent, int *position)
+static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, rsdos_dirent &ent, int *position = nullptr)
{
int i;
floperr_t ferr;
- char fnamebuf[13];
+ std::string fnamebuf;
i = 0;
- fnamebuf[0] = '\0';
do
{
@@ -97,15 +97,15 @@ static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, stru
if (ferr)
return imgtool_floppy_error(ferr);
}
- while(ent->fname[0] == '\0');
+ while(ent.filename[0] == '\0');
- if (ent->fname[0] != -1)
- get_dirent_fname(fnamebuf, ent);
+ if (ent.filename[0] != -1)
+ fnamebuf = get_dirent_fname(ent);
}
- while((ent->fname[0] != -1) && core_stricmp(fnamebuf, fname));
+ while((ent.filename[0] != -1) && core_stricmp(fnamebuf.c_str(), fname));
- if (ent->fname[0] == -1)
+ if (ent.filename[0] == -1)
return IMGTOOLERR_FILENOTFOUND;
if (position)
@@ -114,6 +114,9 @@ static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, stru
}
+//-------------------------------------------------
+// get_granule_count
+//-------------------------------------------------
static uint8_t get_granule_count(imgtool::image &img)
{
@@ -125,10 +128,12 @@ static uint8_t get_granule_count(imgtool::image &img)
return (granules > 255) ? 255 : (uint8_t) granules;
}
-#define MAX_GRANULEMAP_SIZE 256
-/* granule_map must be an array of MAX_GRANULEMAP_SIZE bytes */
-static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint8_t *granule_count)
+//-------------------------------------------------
+// get_granule_map
+//-------------------------------------------------
+
+static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint8_t granule_count[MAX_GRANULEMAP_SIZE])
{
uint8_t count;
@@ -140,6 +145,9 @@ static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint
}
+//-------------------------------------------------
+// put_granule_map
+//-------------------------------------------------
static floperr_t put_granule_map(imgtool::image &img, const uint8_t *granule_map, uint8_t granule_count)
{
@@ -147,7 +155,9 @@ static floperr_t put_granule_map(imgtool::image &img, const uint8_t *granule_map
}
-
+//-------------------------------------------------
+// transfer_granule
+//-------------------------------------------------
static imgtoolerr_t transfer_granule(imgtool::image &img, uint8_t granule, int length, imgtool::stream &f, imgtoolerr_t (*proc)(imgtool::image &, int, int, int, int, size_t, imgtool::stream &))
{
@@ -166,6 +176,9 @@ static imgtoolerr_t transfer_granule(imgtool::image &img, uint8_t granule, int l
}
+//-------------------------------------------------
+// transfer_from_granule
+//-------------------------------------------------
static imgtoolerr_t transfer_from_granule(imgtool::image &img, uint8_t granule, int length, imgtool::stream &destf)
{
@@ -173,6 +186,9 @@ static imgtoolerr_t transfer_from_granule(imgtool::image &img, uint8_t granule,
}
+//-------------------------------------------------
+// transfer_to_granule
+//-------------------------------------------------
static imgtoolerr_t transfer_to_granule(imgtool::image &img, uint8_t granule, int length, imgtool::stream &sourcef)
{
@@ -180,14 +196,17 @@ static imgtoolerr_t transfer_to_granule(imgtool::image &img, uint8_t granule, in
}
+//-------------------------------------------------
+// process_rsdos_file
+//-------------------------------------------------
-static imgtoolerr_t process_rsdos_file(struct rsdos_dirent *ent, imgtool::image &img, imgtool::stream *destf, size_t *size)
+static imgtoolerr_t process_rsdos_file(struct rsdos_dirent *ent, imgtool::image &img, imgtool::stream *destf, size_t &size)
{
floperr_t ferr;
size_t s, lastgransize;
uint8_t granule_count;
unsigned char i = 0, granule;
- uint8_t usedmap[MAX_GRANULEMAP_SIZE]; /* Used to detect infinite loops */
+ uint8_t usedmap[MAX_GRANULEMAP_SIZE]; // used to detect infinite loops
uint8_t granule_map[MAX_GRANULEMAP_SIZE];
ferr = get_granule_map(img, granule_map, &granule_count);
@@ -221,23 +240,24 @@ static imgtoolerr_t process_rsdos_file(struct rsdos_dirent *ent, imgtool::image
if (destf)
transfer_from_granule(img, granule, lastgransize, *destf);
- if (size)
- *size = s + lastgransize;
+ size = s + lastgransize;
return IMGTOOLERR_SUCCESS;
}
+//-------------------------------------------------
+// prepare_dirent - create a new directory entry
+// with a specified name
+//-------------------------------------------------
-/* create a new directory entry with a specified name */
-static imgtoolerr_t prepare_dirent(struct rsdos_dirent *ent, const char *fname)
+static imgtoolerr_t prepare_dirent(rsdos_dirent &ent, const char *fname)
{
const char *fname_end;
const char *fname_ext;
int fname_ext_len;
- memset(ent, '\0', sizeof(*ent));
- memset(ent->fname, ' ', sizeof(ent->fname));
- memset(ent->fext, ' ', sizeof(ent->fext));
+ memset(&ent, '\0', sizeof(ent));
+ memset(ent.filename, ' ', sizeof(ent.filename));
fname_end = strchr(fname, '.');
if (fname_end)
@@ -247,32 +267,34 @@ static imgtoolerr_t prepare_dirent(struct rsdos_dirent *ent, const char *fname)
fname_ext_len = strlen(fname_ext);
- /* We had better be an 8.3 filename */
+ // we had better be an 8.3 filename
if (((fname_end - fname) > 8) || (fname_ext_len > 3))
return IMGTOOLERR_BADFILENAME;
- memcpy(ent->fname, fname, fname_end - fname);
- memcpy(ent->fext, fname_ext, fname_ext_len);
+ memcpy(&ent.filename[0], fname, fname_end - fname);
+ memcpy(&ent.filename[8], fname_ext, fname_ext_len);
- /* For now, all files are type 2 binary files */
- ent->ftype = 2;
- ent->asciiflag = 0;
+ // for now, all files are type 2 binary files
+ ent.ftype = 2;
+ ent.asciiflag = 0;
return IMGTOOLERR_SUCCESS;
}
+//-------------------------------------------------
+// rsdos_diskimage_nextenum
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_nextenum(imgtool::directory &enumeration, imgtool_dirent &ent)
{
floperr_t ferr;
imgtoolerr_t err;
size_t filesize;
- struct rsdos_direnum *rsenum;
- struct rsdos_dirent rsent;
- char fname[13];
+ rsdos_direnum *rsenum;
+ rsdos_dirent rsent;
imgtool::image &image(enumeration.image());
- rsenum = (struct rsdos_direnum *) enumeration.extra_bytes();
+ rsenum = (rsdos_direnum *) enumeration.extra_bytes();
/* Did we hit the end of file before? */
if (rsenum->eof)
@@ -283,14 +305,14 @@ static imgtoolerr_t rsdos_diskimage_nextenum(imgtool::directory &enumeration, im
if (rsenum->index >= MAX_DIRENTS)
goto eof;
- ferr = get_rsdos_dirent(image, rsenum->index++, &rsent);
+ ferr = get_rsdos_dirent(image, rsenum->index++, rsent);
if (ferr)
return imgtool_floppy_error(ferr);
}
- while(rsent.fname[0] == '\0');
+ while(rsent.filename[0] == '\0');
- /* Now are we at the eof point? */
- if (rsent.fname[0] == -1)
+ // now are we at the eof point?
+ if (rsent.filename[0] == -1)
{
rsenum->eof = 1;
eof:
@@ -299,7 +321,7 @@ eof:
else
{
/* Not the end of file */
- err = process_rsdos_file(&rsent, image, nullptr, &filesize);
+ err = process_rsdos_file(&rsent, image, nullptr, filesize);
if (err)
return err;
@@ -316,15 +338,18 @@ eof:
}
ent.eof = 0;
- get_dirent_fname(fname, &rsent);
+ std::string fname = get_dirent_fname(rsent);
- snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", fname);
+ snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", fname.c_str());
snprintf(ent.attr, ARRAY_LENGTH(ent.attr), "%d %c", (int) rsent.ftype, (char) (rsent.asciiflag + 'B'));
}
return IMGTOOLERR_SUCCESS;
}
+//-------------------------------------------------
+// rsdos_diskimage_freespace
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_freespace(imgtool::partition &partition, uint64_t *size)
{
@@ -349,16 +374,19 @@ static imgtoolerr_t rsdos_diskimage_freespace(imgtool::partition &partition, uin
}
+//-------------------------------------------------
+// delete_entry
+//-------------------------------------------------
-static imgtoolerr_t delete_entry(imgtool::image &img, struct rsdos_dirent *ent, int pos)
+static imgtoolerr_t delete_entry(imgtool::image &img, rsdos_dirent &ent, int pos)
{
floperr_t ferr;
unsigned char g, i;
uint8_t granule_count;
uint8_t granule_map[MAX_GRANULEMAP_SIZE];
- /* Write a NUL in the filename, marking it deleted */
- ent->fname[0] = 0;
+ // write a NUL in the filename, marking it deleted
+ ent.filename[0] = 0;
ferr = put_rsdos_dirent(img, pos, ent);
if (ferr)
return imgtool_floppy_error(ferr);
@@ -367,8 +395,8 @@ static imgtoolerr_t delete_entry(imgtool::image &img, struct rsdos_dirent *ent,
if (ferr)
return imgtool_floppy_error(ferr);
- /* Now free up the granules */
- g = ent->first_granule;
+ // now free up the granules
+ g = ent.first_granule;
while (g < granule_count)
{
i = granule_map[g];
@@ -384,6 +412,9 @@ static imgtoolerr_t delete_entry(imgtool::image &img, struct rsdos_dirent *ent,
}
+//-------------------------------------------------
+// rsdos_diskimage_readfile
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_readfile(imgtool::partition &partition, const char *fname, const char *fork, imgtool::stream &destf)
{
@@ -392,11 +423,11 @@ static imgtoolerr_t rsdos_diskimage_readfile(imgtool::partition &partition, cons
size_t size;
imgtool::image &img(partition.image());
- err = lookup_rsdos_file(img, fname, &ent, NULL);
+ err = lookup_rsdos_file(img, fname, ent);
if (err)
return err;
- err = process_rsdos_file(&ent, img, &destf, &size);
+ err = process_rsdos_file(&ent, img, &destf, size);
if (err)
return err;
@@ -407,6 +438,9 @@ static imgtoolerr_t rsdos_diskimage_readfile(imgtool::partition &partition, cons
}
+//-------------------------------------------------
+// rsdos_diskimage_writefile
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, const char *fname, const char *fork, imgtool::stream &sourcef, util::option_resolution *writeoptions)
{
@@ -422,7 +456,7 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
uint8_t granule_count;
uint8_t granule_map[MAX_GRANULEMAP_SIZE];
- /* can we write to this image? */
+ // can we write to this image?
if (floppy_is_read_only(imgtool_floppy(img)))
return IMGTOOLERR_READONLY;
@@ -430,13 +464,13 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
if (err)
return err;
- /* is there enough space? */
+ // is there enough space?
sz = sourcef.size();
if (sz > freespace)
return IMGTOOLERR_NOSPACE;
- /* setup our directory entry */
- err = prepare_dirent(&ent, fname);
+ // setup our directory entry
+ err = prepare_dirent(ent, fname);
if (err)
return err;
@@ -458,7 +492,7 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
{
g++;
if ((g >= granule_count) || (g == 0))
- return IMGTOOLERR_UNEXPECTED; /* We should have already verified that there is enough space */
+ return IMGTOOLERR_UNEXPECTED; // we should have already verified that there is enough space
}
*gptr = g;
gptr = &granule_map[g];
@@ -471,39 +505,38 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
sz -= i;
- /* Go to next granule */
+ // go to next granule
g++;
}
while(sz > 0);
- /* Now that we are done with the file, we need to specify the final entry
- * in the file allocation table
- */
+ // now that we are done with the file, we need to specify the final entry
+ // in the file allocation table
*gptr = 0xc0 + ((i + 255) / 256);
- /* Now we need to find an empty directory entry */
+ // now we need to find an empty directory entry
i = -1;
do
{
- ferr = get_rsdos_dirent(img, ++i, &ent2);
+ ferr = get_rsdos_dirent(img, ++i, ent2);
if (ferr)
return imgtool_floppy_error(ferr);
}
- while((ent2.fname[0] != '\0') && strcmp(ent.fname, ent2.fname) && (ent2.fname[0] != -1));
+ while((ent2.filename[0] != '\0') && strcmp(ent.filename, ent2.filename) && (ent2.filename[0] != -1));
- /* delete file if it already exists */
- if (ent2.fname[0] && (ent2.fname[0] != -1))
+ // delete file if it already exists
+ if (ent2.filename[0] && (ent2.filename[0] != -1))
{
- err = delete_entry(img, &ent2, i);
+ err = delete_entry(img, ent2, i);
if (err)
return err;
}
- ferr = put_rsdos_dirent(img, i, &ent);
+ ferr = put_rsdos_dirent(img, i, ent);
if (ferr)
return imgtool_floppy_error(ferr);
- /* write the granule map back out */
+ // write the granule map back out
ferr = put_granule_map(img, granule_map, granule_count);
if (ferr)
return imgtool_floppy_error(ferr);
@@ -512,6 +545,9 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
}
+//-------------------------------------------------
+// rsdos_diskimage_deletefile
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_deletefile(imgtool::partition &partition, const char *fname)
{
@@ -520,14 +556,17 @@ static imgtoolerr_t rsdos_diskimage_deletefile(imgtool::partition &partition, co
int pos;
struct rsdos_dirent ent;
- err = lookup_rsdos_file(image, fname, &ent, &pos);
+ err = lookup_rsdos_file(image, fname, ent, &pos);
if (err)
return err;
- return delete_entry(image, &ent, pos);
+ return delete_entry(image, ent, pos);
}
+//-------------------------------------------------
+// rsdos_diskimage_suggesttransfer
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_suggesttransfer(imgtool::partition &partition, const char *fname, imgtool_transfer_suggestion *suggestions, size_t suggestions_length)
{
@@ -538,7 +577,7 @@ static imgtoolerr_t rsdos_diskimage_suggesttransfer(imgtool::partition &partitio
if (fname)
{
- err = lookup_rsdos_file(image, fname, &ent, &pos);
+ err = lookup_rsdos_file(image, fname, ent, &pos);
if (err)
return err;