tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Encoding non-alphanumeric characters in manpage filenames



Probably a more realistic refactoring of the code (not tested):

char *escape(const char *page)
{
    static const char hex[] = "0123456789ABCDEF";
    const char *in;
    char *out;
    char *result;
    size_t size;
    int ch;

    size = 3 * strlen(page) + 1;  /* Worst case: every char escaped. */
    if ((result = calloc(1, size)) == NULL) {
        out_of_memory();
    }
    out = result;
    for (in = page; (ch = *in); in++) {
        if (isalnum(ch) || (ch == '_') || (ch == '-')) {
            *out++ = ch;
        } else {
            *out++ = '%';
            *out++ = hex[ch / 16];
            *out++ = hex[ch % 16];
        }
    }
    *out = 0;
    if (out == result + strlen(page)) {  /* No chars escaped. */
        free(result);
        result = NULL;
    }
    return result;
}

char *try(const char *a, const char *b, const char *c)
{
    static struct stat st;
    size_t size;
    char *path;

    size = strlen(a) + strlen(b) + strlen(c) + 1;
    if ((path = calloc(1, size)) == NULL) {
        out_of_memory();
    }
    snprintf(path, size, "%s%s%s", a, b, c);
    if (stat(path, &st) == -1) {
        if (errno != ENOENT) {
            warn(...);
        }
        free(path);
        return NULL;
    }
    return path;
}

static int find(const char **mandirs, const char *page, const char **suffixes)
{
    char *match;
    char *epage;
    char **mandirp;
    char **suffixp;

    match = NULL;
    epage = escape(page);
    for (mandirp = mandirs; (mandir = *mandirp); mandirp++) {
        for (suffixp = suffixes; (suffix = *suffixp); suffixp++) {
            if ((match = try(mandir, page, suffix)) != NULL) {
                break;
            }
            if (epage != NULL) {
                if ((match = try(mandir, epage, suffix)) != NULL) {
                    break;
                }
            }
        }
        if (match != NULL) {
            break;
        }
    }
    free(epage);
    return match;
}


Home | Main Index | Thread Index | Old Index