<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include <err.h>
#include <sysexits.h>

#include <dlfcn.h>

static const char *program_name;

__attribute__ ((constructor))
void _set_program_name(int argc, char *argv[]) {
    program_name = argv[0];
    if (strncmp(program_name, "./", 2) == 0) {
        /* Omit the dot-slash. */
        program_name += 2;
    }
}

static void usage(FILE *output) {
    fprintf(output, "Usage:\n");
    fprintf(output, "  %s (add|mul) <i> <j>\n", program_name);
}

static void usage_error(const char *msg, ...) {
    if (msg != NULL) {
        fprintf(stderr, "%s: ", program_name);
        va_list ap;
        va_start(ap, msg);
        vfprintf(stderr, msg, ap);
        va_end(ap);
        fprintf(stderr, "\n");
    }
    usage(stderr);
    exit(EX_USAGE);
}

static int int_or_die(const char* str) {
    char *end;
    long answer = strtol(str, &end, 10);
    if (str == end) {
        usage_error("invalid integer: '%s'", str);
    }
    return answer;
}

int main(int argc, char **argv) {
    if (argc != 4) {
        usage_error("requires exactly 3 arguments");
    }
    int a = int_or_die(argv[2]), b = int_or_die(argv[3]);
    const char *library;

    if (strncmp(argv[1], "add", 4) == 0) {
        library = "binary_add.dylib";
    } else if (strncmp(argv[1], "mul", 4) == 0) {
        library = "binary_mul.dylib";
    } else {
        usage_error("invalid subcommand: '%s'", argv[1]);
    }

    void *lib = dlopen(library, RTLD_LAZY);
    if (lib == NULL) {
        errx(EX_UNAVAILABLE, "%s", dlerror());
    }
    int (*binary_op)(int, int) = dlsym(lib, "binary_op");
    char* (*binary_sym)(void) = dlsym(lib, "binary_sym");
    if ((binary_op == NULL) || (binary_sym == NULL)) {
        errx(EX_UNAVAILABLE, "%s", dlerror());
    }

    int value = binary_op(a, b);
    printf("%d %s %d = %d\n", a, binary_sym(), b, value);

    dlclose(lib);
    return 0;
}<commit_msg>Load proper shared object.<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include <err.h>
#include <sysexits.h>

#include <dlfcn.h>

#ifdef __APPLE__
#define SHARED_OBJECT(name)    (name ".dylib")
#elif __linux__
#define SHARED_OBJECT(name)    (name ".so")
#else
#   error "Unknown shared object format"
#endif

static void usage(FILE *output);
static void usage_error(const char *msg, ...);
static int int_or_die(const char* str);

static const char *program_name = __FILE__;


int main(int argc, char **argv) {
    if (argc != 4) {
        usage_error("requires exactly 3 arguments");
    }

    int a = int_or_die(argv[2]),
        b = int_or_die(argv[3]);

    const char *library;
    if (strncmp(argv[1], "add", 4) == 0) {
        library = SHARED_OBJECT("binary_add");
    } else if (strncmp(argv[1], "mul", 4) == 0) {
        library = SHARED_OBJECT("binary_mul");
    } else {
        usage_error("invalid subcommand: '%s'", argv[1]);
    }

    void *lib = dlopen(library, RTLD_LAZY);
    if (lib == NULL) {
        errx(EX_UNAVAILABLE, "%s", dlerror());
    }
    int (*binary_op)(int, int) = dlsym(lib, "binary_op");
    char* (*binary_sym)(void) = dlsym(lib, "binary_sym");
    if ((binary_op == NULL) || (binary_sym == NULL)) {
        errx(EX_UNAVAILABLE, "%s", dlerror());
    }

    int value = binary_op(a, b);
    printf("%d %s %d = %d\n", a, binary_sym(), b, value);

    dlclose(lib);
    return 0;
}


static void usage(FILE *output) {
    fprintf(output, "Usage:\n");
    fprintf(output, "  %s (add|mul) <i> <j>\n", program_name);
}


static void usage_error(const char *msg, ...) {
    if (msg != NULL) {
        fprintf(stderr, "%s: ", program_name);
        va_list ap;
        va_start(ap, msg);
        vfprintf(stderr, msg, ap);
        va_end(ap);
        fprintf(stderr, "\n");
    }
    usage(stderr);
    exit(EX_USAGE);
}


static int int_or_die(const char* str) {
    char *end;
    long answer = strtol(str, &end, 10);
    if (str == end) {
        usage_error("invalid integer: '%s'", str);
    }
    return answer;
}


/* Automatically sets the program name variable. */
__attribute__ ((constructor))
void _set_program_name(int argc, char *argv[]) {
    program_name = argv[0];
    if (strncmp(program_name, "./", 2) == 0) {
        /* Omit the dot-slash. */
        program_name += 2;
    }
}
{'fraction_non_alphanumeric': 0.17847286108555657, 'fraction_numerical': 0.00827966881324747, 'mean_word_length': 2.910971223021583, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3641835', 'n_tokens_mistral': 1645, 'n_tokens_neox': 1613, 'n_words': 391}