Esempio n. 1
0
/*
 * Returns the unit to which an identifier maps in a particular unit-system.
 *
 * Arguments:
 *	systemMap	NULL or pointer to the system-map.  If NULL, then
 *			NULL will be returned.
 *	system		Pointer to the unit-system.
 *	id		Pointer to the identifier.
 * Returns:
 *	NULL	Failure.  "ut_get_status()" will be:
 *		    UT_BAD_ARG	        "system" is NULL or "id" is NULL.
 *	else	Pointer to the unit in "system" with the identifier "id".
 *		Should be passed to ut_free() when no longer needed.
 */
static ut_unit*
getUnitById(
    const SystemMap* const	systemMap,
    const ut_system* const	system,
    const char* const		id)
{
    ut_unit*	unit = NULL;		/* failure */

    if (system == NULL) {
	ut_set_status(UT_BAD_ARG);
	ut_handle_error_message("getUnitById(): NULL unit-system argument");
    }
    else if (id == NULL) {
	ut_set_status(UT_BAD_ARG);
	ut_handle_error_message("getUnitById(): NULL identifier argument");
    }
    else if (systemMap != NULL) {
	IdToUnitMap** const	idToUnit =
	    (IdToUnitMap**)smFind(systemMap, system);

	if (idToUnit != NULL) {
	    const UnitAndId*	uai = itumFind(*idToUnit, id);

	    if (uai != NULL)
		unit = ut_clone(uai->unit);
	}
    }					/* valid arguments */

    return unit;
}
Esempio n. 2
0
/*
 * Finds an entry with a UTF-8 identifier corresponding to a unit.
 *
 * Arguments:
 *	map	The unit-to-identifier map.
 *	unit	The unit to be used as the key in the search.
 * Returns:
 *	NULL	The map doesn't contain an entry corresponding to "unit" whose
 *		identifier is in UTF-8.
 *	else	Pointer to the entry corresponding to "unit" whose identifier is
 *		in UTF-8 (and might, actually, be in ASCII).
 */
static UnitAndId*
utimFindUtf8ByUnit(
    UnitToIdMap* const	        map,
    const ut_unit* const	unit)
{
    UnitAndId	targetEntry;
    UnitAndId**	treeEntry = NULL;	/* failure */

    targetEntry.unit = (ut_unit*)unit;
    treeEntry = tfind(&targetEntry, &map->utf8, compareUnits);

    if (treeEntry == NULL) {
	treeEntry = tfind(&targetEntry, &map->latin1, compareUnits);

	if (treeEntry == NULL) {
	    treeEntry = tfind(&targetEntry, &map->ascii, compareUnits);
	}
	else {
	    /*
	     * Create the UTF-8 version of the Latin-1 identifier and add it to
	     * the UTF-8 unit-to-id map so that it will be found next time.
	     */
	    char* const	id = latin1ToUtf8((*treeEntry)->id);

	    if (id == NULL) {
		ut_set_status(UT_OS);
		ut_handle_error_message(strerror(errno));
		ut_handle_error_message(
		    "Couldn't convert identifier from ISO-8859-1 to UTF-8");
		treeEntry = NULL;
	    }
	    else {
		UnitAndId*	newEntry = uaiNew(unit, id);

		if (newEntry != NULL) {
		    treeEntry = tsearch(newEntry, &map->utf8, compareUnits);

		    if (treeEntry == NULL) {
			uaiFree(newEntry);
			ut_set_status(UT_OS);
			ut_handle_error_message(strerror(errno));
			ut_handle_error_message(
                            "Couldn't add unit-and-identifier to search-tree");
		    }
		}

		free(id);
	    }				/* UTF-8 identifier created */
	}				/* found Latin-1 identifier */
    }					/* no UTF-8 identifier */

    return treeEntry == NULL ? NULL : *treeEntry;
}
Esempio n. 3
0
/*
 * Adds an entry to a unit-to-identifier map.
 *
 * Arguments:
 *	map		Pointer to unit-to-identifier map.
 *	unit		The unit.  May be freed upon return.
 *	id		The identifier.  May be freed upon return.
 *	encoding	The ostensible encoding of "id".
 * Returns:
 *	UT_BAD_ARG	"id" is inconsistent with "encoding".
 *	UT_OS		Operating-system error.  See "errno".
 *	UT_EXISTS	"unit" already maps to a different identifier.
 *	UT_SUCCESS	Success.
 */
static ut_status
utimAdd(
    UnitToIdMap* const	map,
    const ut_unit*	unit,
    const char* const	id,
    ut_encoding		encoding)
{
    ut_status		status;

    assert(map != NULL);
    assert(unit != NULL);
    assert(id != NULL);

    if (adjustEncoding(&encoding, id)) {
	status = UT_BAD_ARG;
        ut_set_status(status);
	ut_handle_error_message("Identifier not in given encoding");
    }
    else {
	UnitAndId*	targetEntry = uaiNew(unit, id);

	if (targetEntry != NULL) {
	    void**	rootp = selectTree(map, encoding);

	    UnitAndId**	treeEntry = tsearch(targetEntry, rootp, compareUnits);

	    if (treeEntry == NULL) {
		status = UT_OS;
                ut_set_status(status);
		ut_handle_error_message(strerror(errno));
		ut_handle_error_message("Couldn't add search-tree entry");
		uaiFree(targetEntry);
	    }
	    else {
		if (strcmp((*treeEntry)->id, id) != 0) {
		    status = UT_EXISTS;
                    ut_set_status(status);
		    ut_handle_error_message("Unit already maps to \"%s\"",
			(*treeEntry)->id);
		}
		else {
		    status = UT_SUCCESS;
		}

                if (targetEntry != *treeEntry)
                    uaiFree(targetEntry);
	    }
	}				/* "targetEntry" allocated */
    }					/* valid arguments */

    return status;
}
Esempio n. 4
0
/*
 * Returns the identifier in a given encoding to which a unit associated with
 * a unit-system maps.
 *
 * Arguments:
 *	systemMap	Pointer to the system-to-unit-to-id map.
 *	unit		Pointer to the unit whose identifier should be returned.
 *	encoding	The desired encoding of the identifier.
 * Returns:
 *	NULL		Failure.  "ut_get_status()" will be
 *			    UT_BAD_ARG	"unit" was NULL.
 *	else		Pointer to the identifier in the given encoding
 *			associated with "unit".
 */
static const char*
getId(
    SystemMap* const	systemMap,
    const ut_unit* const	unit,
    const ut_encoding	encoding)
{
    const char*	id = NULL;		/* failure */

    if (unit == NULL) {
	ut_set_status(UT_BAD_ARG);
	ut_handle_error_message("NULL unit argument");
    }
    else {
	UnitToIdMap** const	unitToId = 
	    (UnitToIdMap**)smFind(systemMap, ut_get_system(unit));

	if (unitToId != NULL) {
	    UnitAndId*	mapEntry = 
		encoding == UT_LATIN1
		    ? utimFindLatin1ByUnit(*unitToId, unit)
		    : encoding == UT_UTF8
			? utimFindUtf8ByUnit(*unitToId, unit)
			: utimFindAsciiByUnit(*unitToId, unit);

	    if (mapEntry != NULL)
		id = mapEntry->id;
	}
    }

    return id;
}
Esempio n. 5
0
/*
 * Arguments:
 *	unit	The unit.  May be freed upon return.
 *	id	The identifier (name or symbol).  May be freed upon return.
 * Returns:
 *	NULL	Failure.  "ut_get_status()" will be
 *		    UT_BAD_ARG	"unit" or "id" is NULL.
 *		    UT_OS	Operating-system failure.  See "errno".
 *	else	Pointer to the new unit-and-identifier.
 */
UnitAndId*
uaiNew(
    const ut_unit* const	unit,
    const char* const	        id)
{
    UnitAndId*	entry = NULL;		/* failure */

    if (id == NULL || unit == NULL) {
	ut_set_status(UT_BAD_ARG);
	ut_handle_error_message("uaiNew(): NULL argument");
    }
    else {
	entry = malloc(sizeof(UnitAndId));

	if (entry == NULL) {
	    ut_set_status(UT_OS);
	    ut_handle_error_message(strerror(errno));
	    ut_handle_error_message("Couldn't allocate %lu-byte data-structure",
		sizeof(UnitAndId));
	}
	else {
	    entry->id = strdup(id);

	    if (entry->id == NULL) {
		ut_set_status(UT_OS);
		ut_handle_error_message(strerror(errno));
		ut_handle_error_message("Couldn't duplicate identifier");
	    }
	    else {
		entry->unit = ut_clone(unit);

		if (entry->unit == NULL) {
		    assert(ut_get_status() != UT_SUCCESS);
		    free(entry->id);
		}
	    }

	    if (ut_get_status() != UT_SUCCESS) {
		free(entry);
		entry = NULL;
	    }
	}
    }

    return entry;
}
Esempio n. 6
0
/*
 * Adds an entry to an identifier-to-unit map.
 *
 * Arguments:
 *	map		The database.
 *	id		The identifier.  May be freed upon return.
 *	unit		The unit.  May be freed upon return.
 * Returns:
 *	UT_OS		Operating-system error.  See "errno".
 *	UT_EXISTS	"id" already maps to a different unit.
 *	UT_SUCCESS	Success.
 */
static ut_status
itumAdd(
    IdToUnitMap*		map,
    const char* const		id,
    const ut_unit* const	unit)
{
    ut_status		status;
    UnitAndId*		targetEntry;

    assert(map != NULL);
    assert(id != NULL);
    assert(unit != NULL);

    targetEntry = uaiNew(unit, id);

    if (targetEntry == NULL) {
        status = ut_get_status();
    }
    else {
	UnitAndId**	treeEntry = tsearch(targetEntry, &map->tree,
	    map->compare);

	if (treeEntry == NULL) {
	    uaiFree(targetEntry);
	    status = UT_OS;
	}
	else {
	    if (ut_compare((*treeEntry)->unit, unit) == 0) {
		status = UT_SUCCESS;
	    }
	    else {
		status = UT_EXISTS;
                ut_set_status(status);
		ut_handle_error_message(
		    "\"%s\" already maps to existing but different unit", id);
	    }

            if (targetEntry != *treeEntry)
                uaiFree(targetEntry);
	}				/* found entry */
    }					/* "targetEntry" allocated */

    return status;
}
Esempio n. 7
0
void R_ut_init(const int *print_warning_on_failure) {
  ut_status stat;

  ut_set_error_message_handler((ut_error_message_handler) Rvprintf);
  if (sys != NULL) {
    ut_free_system(sys);
  }
  ut_set_error_message_handler(ut_ignore);
  sys = ut_read_xml(NULL);
  ut_set_error_message_handler((ut_error_message_handler) Rvprintf);
  if (sys == NULL) {
    stat = ut_get_status();
    if (*print_warning_on_failure)
		ut_handle_error_message("Warning in R_ut_init: %s\n", ut_status_strings[stat]);
    return;
  }
  enc = UT_UTF8;
  return;
}