Example #1
0
static int dump_file(const char *input_filename) {
    int input_format = format(input_filename);
    readstat_parser_t *parser = readstat_parser_init();
    readstat_error_t error = READSTAT_OK;

    printf("Format: %s\n", format_name(input_format));

    readstat_set_error_handler(parser, &handle_error);
    readstat_set_info_handler(parser, &dump_info);
    readstat_set_metadata_handler(parser, &dump_metadata);

    error = parse_file(parser, input_filename, input_format, NULL);

    readstat_parser_free(parser);

    if (error != READSTAT_OK) {
        fprintf(stderr, "Error processing %s: %s\n", input_filename, readstat_error_message(error));
        return 1;
    }

    return 0;
}
Example #2
0
int main(int argc, char** argv) {
    struct timeval start_time, end_time;
    readstat_error_t error = READSTAT_OK;
    char *input_filename = NULL;
    char *catalog_filename = NULL;
    char *output_filename = NULL;

    if (argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) {
        print_version();
        return 0;
    } else if (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
        print_usage(argv[0]);
        return 0;
    } if (argc == 3) {
        if (!can_read(argv[1]) || !can_write(argv[2])) {
            print_usage(argv[0]);
            return 1;
        }
        input_filename = argv[1];
        output_filename = argv[2];
    } else if (argc == 4) {
        if (!can_read(argv[1]) || !is_catalog(argv[2]) || !can_write(argv[3])) {
            print_usage(argv[0]);
            return 1;
        }
        input_filename = argv[1];
        catalog_filename = argv[2];
        output_filename = argv[3];
    } else {
        print_usage(argv[0]);
        return 1;
    }

    int input_format = format(input_filename);
    int output_format = format(output_filename);

    gettimeofday(&start_time, NULL);

    int fd = open(output_filename, O_CREAT | O_WRONLY | O_EXCL, 0644);
    if (fd == -1) {
        dprintf(STDERR_FILENO, "Error opening %s for writing: %s\n", output_filename, strerror(errno));
        return 1;
    }

    readstat_parser_t *pass1_parser = readstat_parser_init();
    readstat_parser_t *pass2_parser = readstat_parser_init();
    readstat_writer_t *writer = readstat_writer_init();
    readstat_writer_set_file_label(writer, "Created by ReadStat <https://github.com/WizardMac/ReadStat>");

    rs_ctx_t *rs_ctx = ctx_init();

    rs_ctx->writer = writer;
    rs_ctx->out_fd = fd;
    rs_ctx->out_format = output_format;

    readstat_set_data_writer(writer, &write_data);

    // Pass 1 - Collect fweight and value labels
    readstat_set_error_handler(pass1_parser, &handle_error);
    readstat_set_info_handler(pass1_parser, &handle_info);
    readstat_set_value_label_handler(pass1_parser, &handle_value_label);
    readstat_set_fweight_handler(pass1_parser, &handle_fweight);

    if (catalog_filename) {
        error = parse_file(pass1_parser, catalog_filename, RS_FORMAT_SAS_CATALOG, rs_ctx);
    } else {
        error = parse_file(pass1_parser, input_filename, input_format, rs_ctx);
    }
    if (error != READSTAT_OK)
        goto cleanup;

    // Pass 2 - Parse full file
    readstat_set_error_handler(pass2_parser, &handle_error);
    readstat_set_info_handler(pass2_parser, &handle_info);
    readstat_set_variable_handler(pass2_parser, &handle_variable);
    readstat_set_value_handler(pass2_parser, &handle_value);

    error = parse_file(pass2_parser, input_filename, input_format, rs_ctx);
    if (error != READSTAT_OK)
        goto cleanup;

    gettimeofday(&end_time, NULL);

    dprintf(STDERR_FILENO, "Converted %ld variables and %ld rows in %.2lf seconds\n",
            rs_ctx->var_count, rs_ctx->row_count, 
            (end_time.tv_sec + 1e-6 * end_time.tv_usec) -
            (start_time.tv_sec + 1e-6 * start_time.tv_usec));

cleanup:
    readstat_parser_free(pass1_parser);
    readstat_parser_free(pass2_parser);
    readstat_writer_free(writer);
    ctx_free(rs_ctx);

    close(fd);

    if (error != READSTAT_OK) {
        dprintf(STDERR_FILENO, "%s\n", readstat_error_message(error));
        unlink(output_filename);
        return 1;
    }

    return 0;
}
Example #3
0
static int convert_file(const char *input_filename, const char *catalog_filename, const char *output_filename,
        rs_module_t *modules, int modules_count) {
    readstat_error_t error = READSTAT_OK;
    const char *error_filename = NULL;
    struct timeval start_time, end_time;
    int input_format = format(input_filename);
    rs_module_t *module = rs_module_for_filename(modules, modules_count, output_filename);

    gettimeofday(&start_time, NULL);

    readstat_parser_t *pass1_parser = readstat_parser_init();
    readstat_parser_t *pass2_parser = readstat_parser_init();

    rs_ctx_t *rs_ctx = calloc(1, sizeof(rs_ctx_t));

    void *module_ctx = module->init(output_filename);

    if (module_ctx == NULL)
        goto cleanup;

    rs_ctx->module = module;
    rs_ctx->module_ctx = module_ctx;

    // Pass 1 - Collect fweight and value labels
    readstat_set_error_handler(pass1_parser, &handle_error);
    readstat_set_info_handler(pass1_parser, &handle_info);
    readstat_set_value_label_handler(pass1_parser, &handle_value_label);
    readstat_set_fweight_handler(pass1_parser, &handle_fweight);

    if (catalog_filename) {
        error = parse_file(pass1_parser, catalog_filename, RS_FORMAT_SAS_CATALOG, rs_ctx);
        error_filename = catalog_filename;
    } else {
        error = parse_file(pass1_parser, input_filename, input_format, rs_ctx);
        error_filename = input_filename;
    }
    if (error != READSTAT_OK)
        goto cleanup;

    // Pass 2 - Parse full file
    readstat_set_error_handler(pass2_parser, &handle_error);
    readstat_set_info_handler(pass2_parser, &handle_info);
    readstat_set_metadata_handler(pass2_parser, &handle_metadata);
    readstat_set_note_handler(pass2_parser, &handle_note);
    readstat_set_variable_handler(pass2_parser, &handle_variable);
    readstat_set_value_handler(pass2_parser, &handle_value);

    error = parse_file(pass2_parser, input_filename, input_format, rs_ctx);
    error_filename = input_filename;
    if (error != READSTAT_OK)
        goto cleanup;

    gettimeofday(&end_time, NULL);

    fprintf(stderr, "Converted %ld variables and %ld rows in %.2lf seconds\n",
            rs_ctx->var_count, rs_ctx->row_count, 
            (end_time.tv_sec + 1e-6 * end_time.tv_usec) -
            (start_time.tv_sec + 1e-6 * start_time.tv_usec));

cleanup:
    readstat_parser_free(pass1_parser);
    readstat_parser_free(pass2_parser);

    if (module->finish) {
        module->finish(rs_ctx->module_ctx);
    }

    free(rs_ctx);

    if (error != READSTAT_OK) {
        fprintf(stderr, "Error processing %s: %s\n", error_filename, readstat_error_message(error));
        unlink(output_filename);
        return 1;
    }

    return 0;
}