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; }
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; }
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; }