mirror of
https://github.com/ctm/executor.git
synced 2024-09-27 05:54:33 +00:00
252 lines
4.8 KiB
C
252 lines
4.8 KiB
C
/* Copyright 2000 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_suffix_maps[] =
|
|
"$Id: suffix_maps.c 63 2004-12-24 18:19:43Z ctm $";
|
|
#endif
|
|
|
|
#include "rsys/common.h"
|
|
|
|
#include "rsys/suffix_maps.h"
|
|
#include "rsys/file.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
/*
|
|
* This file contains the routines needed to create mappings from file
|
|
* suffixes to (Creator, Type) pairs. When a file is created with a suffix
|
|
* that is in the list, the normal % file won't be created. When the file's
|
|
* creator and type is queried, the creator and type from the list will be
|
|
* read.
|
|
*/
|
|
|
|
typedef struct suffix_entry
|
|
{
|
|
char *suffix;
|
|
uint32 creator;
|
|
uint32 type;
|
|
const char *application;
|
|
struct suffix_entry *next;
|
|
}
|
|
suffix_entry_t;
|
|
|
|
PRIVATE suffix_entry_t *suffix_head;
|
|
|
|
PRIVATE boolean_t
|
|
str_to_hex (const char *str, uint32 *valp)
|
|
{
|
|
boolean_t retval;
|
|
int len;
|
|
|
|
len = strlen (str);
|
|
retval = (str[0] == '0' &&
|
|
(str[1] == 'x' || str[1] == 'X') &&
|
|
len >= 3 &&
|
|
len <= 10);
|
|
|
|
if (retval)
|
|
{
|
|
uint32 val;
|
|
|
|
val = 0;
|
|
for (str += 2; retval && *str; ++str)
|
|
if (isxdigit (*str))
|
|
val = (val << 4) | ROMlib_fromhex (*str);
|
|
else
|
|
retval = FALSE;
|
|
*valp = val;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
PUBLIC void
|
|
ROMlib_add_suffix_quad (const char *suffixp, const char *creator_hexp,
|
|
const char *type_hexp, const char *applicationp)
|
|
{
|
|
uint32 creator;
|
|
uint32 type;
|
|
|
|
if (str_to_hex (creator_hexp, &creator) &&
|
|
str_to_hex (type_hexp, &type))
|
|
{
|
|
suffix_entry_t *new;
|
|
|
|
new = malloc (sizeof *new);
|
|
if (new)
|
|
{
|
|
new->suffix = strdup (suffixp);
|
|
if (!new->suffix)
|
|
free (new);
|
|
else
|
|
{
|
|
new->creator = creator;
|
|
new->type = type;
|
|
new->application = strdup (applicationp);
|
|
new->next = suffix_head;
|
|
suffix_head = new;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
PRIVATE suffix_entry_t **
|
|
find_suffixpp (const char *suffix)
|
|
{
|
|
suffix_entry_t **retval;
|
|
|
|
retval = &suffix_head;
|
|
|
|
while (*retval && strcasecmp ((*retval)->suffix, suffix) != 0)
|
|
retval = &(*retval)->next;
|
|
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
* Best match is (creator, 'APPL')
|
|
* next best is (creator, type)
|
|
* next best is (creator, X)
|
|
* worst is (X, type)
|
|
*/
|
|
|
|
PUBLIC const char *
|
|
ROMlib_find_best_creator_type_match (uint32 creator, uint32 type)
|
|
{
|
|
enum { no_match, type_match, creator_match, both_match, appl_match } match;
|
|
suffix_entry_t **pp;
|
|
const char *retval;
|
|
|
|
retval = NULL;
|
|
for (match = no_match, pp = &suffix_head;
|
|
match != appl_match && *pp;
|
|
pp = &(*pp)->next)
|
|
{
|
|
if (*(*pp)->application)
|
|
{
|
|
if ((*pp)->creator == creator)
|
|
{
|
|
if ((*pp)->type == TICK("APPL"))
|
|
{
|
|
retval = (*pp)->application;
|
|
match = appl_match;
|
|
}
|
|
else if (match < both_match && (*pp)->type == type)
|
|
{
|
|
retval = (*pp)->application;
|
|
match = both_match;
|
|
}
|
|
else if (match < creator_match)
|
|
{
|
|
retval = (*pp)->application;
|
|
match = creator_match;
|
|
}
|
|
}
|
|
else if ((*pp)->type == type && match < type_match)
|
|
{
|
|
retval = (*pp)->application;
|
|
match = type_match;
|
|
}
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE boolean_t
|
|
filename_suffix_match (const char *suffix, int len, const char *filename)
|
|
{
|
|
boolean_t retval;
|
|
int suffix_len;
|
|
|
|
suffix_len = strlen (suffix);
|
|
retval = (len >= suffix_len &&
|
|
strncasecmp (suffix, filename + len - suffix_len, suffix_len)
|
|
== 0);
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE suffix_entry_t **
|
|
find_filenamepp (int len, const char *filename)
|
|
{
|
|
suffix_entry_t **retval;
|
|
|
|
retval = &suffix_head;
|
|
|
|
while (*retval && !filename_suffix_match ((*retval)->suffix, len, filename))
|
|
retval = &(*retval)->next;
|
|
|
|
return retval;
|
|
}
|
|
|
|
PUBLIC boolean_t
|
|
ROMlib_creator_and_type_from_suffix (const char *suffix, uint32 *creatorp,
|
|
uint32 *typep)
|
|
{
|
|
boolean_t retval;
|
|
suffix_entry_t **pp;
|
|
|
|
pp = find_suffixpp (suffix);
|
|
if (!*pp)
|
|
retval = FALSE;
|
|
else
|
|
{
|
|
retval = TRUE;
|
|
if (creatorp)
|
|
*creatorp = (*pp)->creator;
|
|
if (typep)
|
|
*typep = (*pp)->type;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
PUBLIC boolean_t
|
|
ROMlib_creator_and_type_from_filename (int len, const char *filename,
|
|
uint32 *creatorp, uint32 *typep)
|
|
{
|
|
boolean_t retval;
|
|
suffix_entry_t **pp;
|
|
|
|
pp = find_filenamepp (len, filename);
|
|
if (!*pp)
|
|
retval = FALSE;
|
|
else
|
|
{
|
|
retval = TRUE;
|
|
if (creatorp)
|
|
*creatorp = (*pp)->creator;
|
|
if (typep)
|
|
*typep = (*pp)->type;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE void
|
|
release_entry (suffix_entry_t *to_release)
|
|
{
|
|
free (to_release->suffix);
|
|
free (to_release);
|
|
}
|
|
|
|
PUBLIC boolean_t
|
|
ROMlib_delete_suffix (const char *suffix)
|
|
{
|
|
boolean_t retval;
|
|
suffix_entry_t **pp;
|
|
|
|
pp = find_suffixpp (suffix);
|
|
if (!*pp)
|
|
retval = FALSE;
|
|
else
|
|
{
|
|
suffix_entry_t *to_release;
|
|
|
|
retval = TRUE;
|
|
to_release = *pp;
|
|
*pp = (*pp)->next;
|
|
release_entry (to_release);
|
|
}
|
|
return retval;
|
|
}
|