diff options
Diffstat (limited to 'src/mess/tools/imgtool/library.c')
-rw-r--r-- | src/mess/tools/imgtool/library.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/src/mess/tools/imgtool/library.c b/src/mess/tools/imgtool/library.c new file mode 100644 index 00000000000..a564f37dd38 --- /dev/null +++ b/src/mess/tools/imgtool/library.c @@ -0,0 +1,280 @@ +/**************************************************************************** + + library.c + + Code relevant to the Imgtool library; analgous to the MESS/MAME driver + list. + +****************************************************************************/ + +#include <string.h> + +#include "library.h" +#include "pool.h" + +struct _imgtool_library +{ + object_pool *pool; + imgtool_module *first; + imgtool_module *last; +}; + + + +imgtool_library *imgtool_library_create(void) +{ + imgtool_library *library; + object_pool *pool; + + /* create a memory pool */ + pool = pool_alloc_lib(NULL); + if (!pool) + goto error; + + /* allocate the main structure */ + library = (imgtool_library *)pool_malloc_lib(pool, sizeof(struct _imgtool_library)); + if (!library) + goto error; + + /* initialize the structure */ + memset(library, 0, sizeof(*library)); + library->pool = pool; + + return library; + +error: + if (pool) + pool_free_lib(pool); + return NULL; +} + + + +void imgtool_library_close(imgtool_library *library) +{ + pool_free_lib(library->pool); +} + + + +static void imgtool_library_add_class(imgtool_library *library, const imgtool_class *imgclass) +{ + imgtool_module *module; + char *s1, *s2; + + /* allocate the module and place it in the chain */ + module = (imgtool_module *)imgtool_library_malloc(library, sizeof(*module)); + memset(module, 0, sizeof(*module)); + module->previous = library->last; + if (library->last) + library->last->next = module; + else + library->first = module; + library->last = module; + + /* extensions have a weird format */ + s1 = imgtool_get_info_string(imgclass, IMGTOOLINFO_STR_FILE_EXTENSIONS); + s2 = (char*)imgtool_library_malloc(library, strlen(s1) + 1); + strcpy(s2, s1); + module->extensions = s2; + + module->imgclass = *imgclass; + module->name = imgtool_library_strdup(library, imgtool_get_info_string(imgclass, IMGTOOLINFO_STR_NAME)); + module->description = imgtool_library_strdup(library, imgtool_get_info_string(imgclass, IMGTOOLINFO_STR_DESCRIPTION)); + module->eoln = imgtool_library_strdup_allow_null(library, imgtool_get_info_string(imgclass, IMGTOOLINFO_STR_EOLN)); + module->initial_path_separator = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_INITIAL_PATH_SEPARATOR) ? 1 : 0; + module->open_is_strict = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_OPEN_IS_STRICT) ? 1 : 0; + module->tracks_are_called_cylinders = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_TRACKS_ARE_CALLED_CYLINDERS) ? 1 : 0; + module->writing_untested = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_WRITING_UNTESTED) ? 1 : 0; + module->creation_untested = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_CREATION_UNTESTED) ? 1 : 0; + module->open = (imgtoolerr_t (*)(imgtool_image *, imgtool_stream *)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_OPEN); + module->create = (imgtoolerr_t (*)(imgtool_image *, imgtool_stream *, option_resolution *)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_CREATE); + module->close = (void (*)(imgtool_image *)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_CLOSE); + module->info = (void (*)(imgtool_image *, char *, size_t)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_INFO); + module->read_sector = (imgtoolerr_t (*)(imgtool_image *, UINT32, UINT32, UINT32, void *, size_t)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_READ_SECTOR); + module->write_sector = (imgtoolerr_t (*)(imgtool_image *, UINT32, UINT32, UINT32, const void *, size_t)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_WRITE_SECTOR); + module->get_geometry = (imgtoolerr_t (*)(imgtool_image *, UINT32 *, UINT32 *, UINT32 *))imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_GET_GEOMETRY); + module->get_sector_size = (imgtoolerr_t (*)(imgtool_image *, UINT32, UINT32, UINT32, UINT32 *))imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_GET_SECTOR_SIZE); + module->read_block = (imgtoolerr_t (*)(imgtool_image *, void *, UINT64)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_READ_BLOCK); + module->write_block = (imgtoolerr_t (*)(imgtool_image *, const void *, UINT64)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_WRITE_BLOCK); + module->list_partitions = (imgtoolerr_t (*)(imgtool_image *, imgtool_partition_info *, size_t)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_LIST_PARTITIONS); + module->block_size = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_BLOCK_SIZE); + module->createimage_optguide = (const option_guide *) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE); + module->createimage_optspec = imgtool_library_strdup_allow_null(library, (const char*)imgtool_get_info_ptr(imgclass, IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC)); + module->image_extra_bytes += imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES); +} + + + +void imgtool_library_add(imgtool_library *library, imgtool_get_info get_info) +{ + int (*make_class)(int index, imgtool_class *imgclass); + imgtool_class imgclass; + int i, result; + + /* try this class */ + memset(&imgclass, 0, sizeof(imgclass)); + imgclass.get_info = get_info; + + /* do we have derived getinfo functions? */ + make_class = (int (*)(int index, imgtool_class *imgclass)) + imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_MAKE_CLASS); + + if (make_class) + { + i = 0; + do + { + /* clear out the class */ + memset(&imgclass, 0, sizeof(imgclass)); + imgclass.get_info = get_info; + + /* make the class */ + result = make_class(i++, &imgclass); + if (result) + imgtool_library_add_class(library, &imgclass); + } + while(result); + } + else + { + imgtool_library_add_class(library, &imgclass); + } +} + + + +const imgtool_module *imgtool_library_unlink(imgtool_library *library, + const char *module) +{ + imgtool_module *m; + imgtool_module **previous; + imgtool_module **next; + + for (m = library->first; m; m = m->next) + { + if (!core_stricmp(m->name, module)) + { + previous = m->previous ? &m->previous->next : &library->first; + next = m->next ? &m->next->previous : &library->last; + *previous = m->next; + *next = m->previous; + m->previous = NULL; + m->next = NULL; + return m; + } + } + return NULL; +} + + + +static int module_compare(const imgtool_module *m1, + const imgtool_module *m2, imgtool_libsort_t sort) +{ + int rc = 0; + switch(sort) + { + case ITLS_NAME: + rc = strcmp(m1->name, m2->name); + break; + case ITLS_DESCRIPTION: + rc = core_stricmp(m1->name, m2->name); + break; + } + return rc; +} + + + +void imgtool_library_sort(imgtool_library *library, imgtool_libsort_t sort) +{ + imgtool_module *m1; + imgtool_module *m2; + imgtool_module *target; + imgtool_module **before; + imgtool_module **after; + + for (m1 = library->first; m1; m1 = m1->next) + { + target = m1; + for (m2 = m1->next; m2; m2 = m2->next) + { + while(module_compare(target, m2, sort) > 0) + target = m2; + } + + if (target != m1) + { + /* unlink the target */ + before = target->previous ? &target->previous->next : &library->first; + after = target->next ? &target->next->previous : &library->last; + *before = target->next; + *after = target->previous; + + /* now place the target before m1 */ + target->previous = m1->previous; + target->next = m1; + before = m1->previous ? &m1->previous->next : &library->first; + *before = target; + m1->previous = target; + + /* since we changed the order, we have to replace ourselves */ + m1 = target; + } + } +} + + + +const imgtool_module *imgtool_library_findmodule( + imgtool_library *library, const char *module_name) +{ + const imgtool_module *module; + + assert(library); + module = library->first; + while(module && module_name && strcmp(module->name, module_name)) + module = module->next; + return module; +} + + + +imgtool_module *imgtool_library_iterate(imgtool_library *library, const imgtool_module *module) +{ + return module ? module->next : library->first; +} + + + +imgtool_module *imgtool_library_index(imgtool_library *library, int i) +{ + imgtool_module *module; + module = library->first; + while(module && i--) + module = module->next; + return module; +} + + + +void *imgtool_library_malloc(imgtool_library *library, size_t mem) +{ + return pool_malloc_lib(library->pool, mem); +} + + + +char *imgtool_library_strdup(imgtool_library *library, const char *s) +{ + return pool_strdup_lib(library->pool, s); +} + + + +char *imgtool_library_strdup_allow_null(imgtool_library *library, const char *s) +{ + return s ? imgtool_library_strdup(library, s) : NULL; +} + |