Esempio n. 1
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. 2
0
/*
 * Removes an entry from a unit-to-identifier map.
 *
 * Arguments:
 *	map		Pointer to the unit-to-identifier map.
 *	unit		The unit.  May be freed upon return.
 *	encoding	The encoding to be removed.
 * Returns:
 *	UT_SUCCESS	Success.
 */
static ut_status
utimRemove(
    UnitToIdMap* const	map,
    const ut_unit*	unit,
    ut_encoding		encoding)
{
    ut_status		status;
    UnitAndId		targetEntry;
    UnitAndId**		treeEntry;

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

    targetEntry.unit = (ut_unit*)unit;
    treeEntry = tfind(&targetEntry, selectTree(map, encoding), compareUnits);

    if (treeEntry == NULL || *treeEntry == NULL) {
	status = UT_SUCCESS;
    }
    else {
	UnitAndId*	uai = *treeEntry;

	(void)tdelete(uai, selectTree(map, encoding), compareUnits);
	uaiFree(uai);
    }

    return status;
}
Esempio n. 3
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. 4
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. 5
0
/*
 * Frees an identifier-to-unit map.  All entries are freed.
 *
 * Arguments:
 *	map		Pointer to the identifier-to-unit map.
 * Returns:
 */
static void
itumFree(
    IdToUnitMap*	map)
{
    if (map != NULL) {
	while (map->tree != NULL) {
	    UnitAndId*	uai = *(UnitAndId**)map->tree;

	    (void)tdelete(uai, &map->tree, map->compare);
	    uaiFree(uai);
	}

	free(map);
    }					/* valid arguments */
}
Esempio n. 6
0
/*
 * Frees a unit-to-identifier map.  All entries in all encodings are freed.
 *
 * Arguments:
 *	map		Pointer to the map to be freed.
 */
static void
utimFree(
    UnitToIdMap*	map)
{
    if (map != NULL) {
	ut_encoding	encodings[] = {UT_ASCII, UT_LATIN1, UT_UTF8};
	int		i;

	for (i = 0; i < sizeof(encodings)/sizeof(encodings[0]); ++i) {
	    void**	rootp = selectTree(map, encodings[i]);

	    while (*rootp != NULL) {
		UnitAndId*	uai = **(UnitAndId***)rootp;

		(void)tdelete(uai, rootp, compareUnits);
		uaiFree(uai);
	    }
	}

	free(map);
    }
}
Esempio n. 7
0
/*
 * Removes an entry to an identifier-to-unit map.
 *
 * Arguments:
 *	map		The database.
 *	id		The identifier.  May be freed upon return.
 * Returns:
 *	UT_SUCCESS	Success.
 */
static ut_status
itumRemove(
    IdToUnitMap*	map,
    const char* const	id)
{
    UnitAndId		targetEntry;
    UnitAndId**		treeEntry;

    assert(map != NULL);
    assert(id != NULL);
    
    targetEntry.id = (char*)id;
    treeEntry = tfind(&targetEntry, &map->tree, map->compare);

    if (treeEntry != NULL) {
	UnitAndId*	uai = *treeEntry;

	(void)tdelete(uai, &map->tree, map->compare);
	uaiFree(uai);
    }

    return UT_SUCCESS;
}