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
Below is a proof of concept that encodes some of our actual filenames.
The salient lines of code are:
    static const char hex[] = "0123456789ABCDEF";
    if (isalnum(ch) || (ch == '_') || (ch == '-')) {
    *out++ = '%';
These all use C's idea of the character set.
Here's the full program:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *escape(const char *prefix, const char *page, const char *suffix)
{
    static const char hex[] = "0123456789ABCDEF";
    const char *in;
    char *out;
    char *result;
    size_t size;
    int ch;
    size = strlen(prefix) + strlen(suffix) + 1;
    size += 3 * strlen(page);  /* Worst case: every char hex-escaped. */
    if ((result = calloc(1, size)) == NULL) {
        return NULL;
    }
    out = result;
    for (in = prefix; (ch = *in); in++) {
        *out++ = ch;
    }
    for (in = page; (ch = *in); in++) {
        if (isalnum(ch) || (ch == '_') || (ch == '-')) {
            *out++ = ch;
        } else {
            *out++ = '%';
            *out++ = hex[ch / 16];
            *out++ = hex[ch % 16];
        }
    }
    for (in = suffix; (ch = *in); in++) {
        *out++ = ch;
    }
    *out = 0;
    return result;
}
static void demo(const char *page)
{
    const char suffix[] = ".3scm.gz";
    printf("%s%s -> %s\n", page, suffix, escape("", page, suffix));
}
int main(void)
{
    demo("&assertion");
    demo("call/cc");
    demo("hash-table?");
    demo("string->number");
    return EXIT_SUCCESS;
}
Here's how you could look for the files (not tested):
int try_open(char *path)
{
    int fd, save;
    if (path == NULL) {
        out_of_memory();
    }
    if ((fd = open(path, O_RDONLY)) == -1) {
        save = errno;
        free(path);
        errno = save;
        return -1;
    }
    free(path);
    return fd;
}
int find(const char *mandir, const char *page, const char *suffix)
{
    int fd;
    if ((fd = try_open(concat_3_strings(mandir, page, suffix))) != -1) {
        return fd;
    }
    if ((fd = try_open(escape(mandir, page, suffix))) != -1) {
        return fd;
    }
    return -1;
}
Home |
Main Index |
Thread Index |
Old Index