/* Add new alias. */ static void add_alias (char *rp, void *modules) { /* We now expect two more string. The strings are normalized (converted to UPPER case) and strored in the alias database. */ char *from, *to, *wp; while (__isspace_l (*rp, _nl_C_locobj_ptr)) ++rp; from = wp = rp; while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr)) *wp++ = __toupper_l (*rp++, _nl_C_locobj_ptr); if (*rp == '\0') /* There is no `to' string on the line. Ignore it. */ return; *wp++ = '\0'; to = ++rp; while (__isspace_l (*rp, _nl_C_locobj_ptr)) ++rp; while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr)) *wp++ = __toupper_l (*rp++, _nl_C_locobj_ptr); if (to == wp) /* No `to' string, ignore the line. */ return; *wp++ = '\0'; add_alias2 (from, to, wp, modules); }
/* Add new alias. */ static inline void add_alias (char *rp, void *modules) { /* We now expect two more string. The strings are normalized (converted to UPPER case) and strored in the alias database. */ struct gconv_alias *new_alias; char *from, *to, *wp; while (__isspace_l (*rp, &_nl_C_locobj)) ++rp; from = wp = rp; while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj)) *wp++ = __toupper_l (*rp++, &_nl_C_locobj); if (*rp == '\0') /* There is no `to' string on the line. Ignore it. */ return; *wp++ = '\0'; to = ++rp; while (__isspace_l (*rp, &_nl_C_locobj)) ++rp; while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj)) *wp++ = __toupper_l (*rp++, &_nl_C_locobj); if (to == wp) /* No `to' string, ignore the line. */ return; *wp++ = '\0'; /* Test whether this alias conflicts with any available module. */ if (detect_conflict (from)) /* It does conflict, don't add the alias. */ return; new_alias = (struct gconv_alias *) malloc (sizeof (struct gconv_alias) + (wp - from)); if (new_alias != NULL) { void **inserted; new_alias->fromname = memcpy ((char *) new_alias + sizeof (struct gconv_alias), from, wp - from); new_alias->toname = new_alias->fromname + (to - from); inserted = (void **) __tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare); if (inserted == NULL || *inserted != new_alias) /* Something went wrong, free this entry. */ free (new_alias); } }
/* Add new module. */ static void internal_function add_module (char *rp, const char *directory, size_t dir_len, void **modules, size_t *nmodules, int modcounter) { /* We expect now 1. `from' name 2. `to' name 3. filename of the module 4. an optional cost value */ struct gconv_alias fake_alias; struct gconv_module *new_module; char *from, *to, *module, *wp; int need_ext; int cost_hi; while (__isspace_l (*rp, &_nl_C_locobj)) ++rp; from = rp; while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj)) { *rp = __toupper_l (*rp, &_nl_C_locobj); ++rp; } if (*rp == '\0') return; *rp++ = '\0'; to = wp = rp; while (__isspace_l (*rp, &_nl_C_locobj)) ++rp; while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj)) *wp++ = __toupper_l (*rp++, &_nl_C_locobj); if (*rp == '\0') return; *wp++ = '\0'; do ++rp; while (__isspace_l (*rp, &_nl_C_locobj)); module = wp; while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj)) *wp++ = *rp++; if (*rp == '\0') { /* There is no cost, use one by default. */ *wp++ = '\0'; cost_hi = 1; } else { /* There might be a cost value. */ char *endp; *wp++ = '\0'; cost_hi = strtol (rp, &endp, 10); if (rp == endp || cost_hi < 1) /* No useful information. */ cost_hi = 1; } if (module[0] == '\0') /* No module name given. */ return; if (module[0] == '/') dir_len = 0; /* See whether we must add the ending. */ need_ext = 0; if (wp - module < (ptrdiff_t) sizeof (gconv_module_ext) || memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext, sizeof (gconv_module_ext)) != 0) /* We must add the module extension. */ need_ext = sizeof (gconv_module_ext) - 1; /* See whether we have already an alias with this name defined. */ fake_alias.fromname = strndupa (from, to - from); if (__tfind (&fake_alias, &__gconv_alias_db, __gconv_alias_compare) != NULL) /* This module duplicates an alias. */ return; new_module = (struct gconv_module *) calloc (1, sizeof (struct gconv_module) + (wp - from) + dir_len + need_ext); if (new_module != NULL) { char *tmp; new_module->from_string = tmp = (char *) (new_module + 1); tmp = __mempcpy (tmp, from, to - from); new_module->to_string = tmp; tmp = __mempcpy (tmp, to, module - to); new_module->cost_hi = cost_hi; new_module->cost_lo = modcounter; new_module->module_name = tmp; if (dir_len != 0) tmp = __mempcpy (tmp, directory, dir_len); tmp = __mempcpy (tmp, module, wp - module); if (need_ext) memcpy (tmp - 1, gconv_module_ext, sizeof (gconv_module_ext)); /* Now insert the new module data structure in our search tree. */ insert_module (new_module, 1); } }