C-Typen in die Laufzeitumgebung heben

written by Martin Häcker on

Wendet man @encode() jetzt auf ein paar Deklarationen an, erhält man folgende Ergebnisse:

#define LOG(what) [[Log sharedLog] logObjcType:@encode(typeof(what)) arguments:(void *)what]

LOG(@"fnord"); // @
LOG("foo"); // [3c]
char *string = "fnord";
LOG(string); // *

Ich parse das so:

#define RAISE_UNSUPPORTED_TYPE(encodedType) \
    [NSException raise:NSInvalidArgumentException \
        format:@" you are trying to log something that is not a string: %s", encodedType]

- stringFromType:(char *)encodedType inArray:(void *)what; {
    if ('[' != *encodedType) RAISE_UNSUPPORTED_TYPE(encodedType);

    encodedType++;
    unsigned length = strtol(encodedType, &encodedType, 10);
    if ('c' != *encodedType) RAISE_UNSUPPORTED_TYPE(encodedType);

    return [NSString stringWithCString:what length:length-1]; // \0 ignored
}

- stringFromType:(char *)encodedType inValue:(void *)what; {
    if ('@' == *encodedType) return [(id)what description];
    if ('*' == *encodedType) return [NSString stringWithCString:(char *)what];
    if ('[' == *encodedType) return [self stringFromType:encodedType inArray:what];
    RAISE_UNSUPPORTED_TYPE(encodedType);
    return nil; /* never reached */
}

(Vorschläge wie man das besser machen kann, bitte gerne an mich! ( z.B. via spamfaenger ät gmx de))

Fehlt nur noch die Erweiterung auf beliebig viele Argumente. Dazu aber morgen mehr. :)