Skip to content

Commit

Permalink
Try working version after fixing rogue change
Browse files Browse the repository at this point in the history
  • Loading branch information
slobodan-ilic committed Jun 15, 2024
1 parent 0a76076 commit 1b5fcb7
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 82 deletions.
21 changes: 0 additions & 21 deletions src/spss/readstat_sav.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ sav_ctx_t *sav_ctx_init(sav_file_header_record_t *header, readstat_io_t *io) {
return NULL;
}

ctx->mr_sets = NULL;

ctx->io = io;

return ctx;
Expand Down Expand Up @@ -91,25 +89,6 @@ void sav_ctx_free(sav_ctx_t *ctx) {
if (ctx->variable_display_values) {
free(ctx->variable_display_values);
}
if (ctx->mr_sets) {
for (size_t i = 0; i < ctx->multiple_response_sets_length; i++) {
if (ctx->mr_sets[i].name) {
free(ctx->mr_sets[i].name);
}
if (ctx->mr_sets[i].label) {
free(ctx->mr_sets[i].label);
}
if (ctx->mr_sets[i].subvariables) {
for (size_t j = 0; j < ctx->mr_sets[i].num_subvars; j++) {
if (ctx->mr_sets[i].subvariables[j]) {
free(ctx->mr_sets[i].subvariables[j]);
}
}
free(ctx->mr_sets[i].subvariables);
}
}
free(ctx->mr_sets);
}
free(ctx);
}

73 changes: 12 additions & 61 deletions src/spss/readstat_sav_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static readstat_error_t parse_mr_counted_value(const char **next_part, mr_set_t
}
(*next_part)++;
digit_start = (*next_part);
for (int i = 0; i < internal_count && isdigit((unsigned char)*(*next_part)); i++) {
for (int i = 0; i < internal_count && isdigit(*(*next_part)); i++) {
(*next_part)++;
}
result->counted_value = (int)strtol(digit_start, NULL, 10);
Expand All @@ -177,15 +177,10 @@ static readstat_error_t parse_mr_counted_value(const char **next_part, mr_set_t
result->is_dichotomy = 0;
result->counted_value = -1;
}
else {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
cleanup:
return retval;
}


static readstat_error_t parse_mr_line(const char *line, mr_set_t *result) {
readstat_error_t retval = READSTAT_OK;
*result = (mr_set_t){0};
Expand All @@ -198,21 +193,12 @@ static readstat_error_t parse_mr_line(const char *line, mr_set_t *result) {

result->type = equals_pos[1];
int name_length = equals_pos - line;
if (name_length < 1) {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
if ((result->name = readstat_malloc(name_length + 1)) == NULL) {
if ((result->name = malloc(name_length + 1)) == NULL) {
retval = READSTAT_ERROR_MALLOC;
goto cleanup;
}
strncpy(result->name, line, name_length);
result->name[name_length] = '\0';

if (equals_pos[2] == '\0') {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
const char *next_part = equals_pos + 2; // Start after the '=' and type character
if ((retval = parse_mr_counted_value(&next_part, result)) != READSTAT_OK) goto cleanup;
if (*next_part != ' ') {
Expand All @@ -221,36 +207,21 @@ static readstat_error_t parse_mr_line(const char *line, mr_set_t *result) {
}
next_part++;
const char *digit_start = next_part;
while (isdigit((unsigned char)*next_part)) {
while (isdigit(*next_part)) {
next_part++;
}
if (*next_part != ' ') {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
if (digit_start == next_part) { // ensure digit start not empty
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
char *endptr;
size_t count = strtoul(digit_start, &endptr, 10);
if (endptr == digit_start || count == 0) {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}

next_part = endptr;
if (*next_part != ' ') {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
size_t count = strtoul(digit_start, NULL, 10);
next_part++; // Move past the space after the digits
if (strlen(next_part) < count) {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}

result->label = readstat_malloc(count + 1); // +1 for the null-terminator
result->label = malloc(count + 1); // +1 for the null-terminator
if (result->label == NULL) {
retval = READSTAT_ERROR_MALLOC;
goto cleanup;
Expand Down Expand Up @@ -279,14 +250,15 @@ static readstat_error_t parse_mr_line(const char *line, mr_set_t *result) {
}

size_t length = next_part - start;
char *subvariable = readstat_malloc(length + 1); // Allocate memory for the subvariable
char *subvariable = malloc(length + 1); // Allocate memory for the subvariable
if (subvariable == NULL) {
retval = READSTAT_ERROR_MALLOC;
for (int i = 0; i < subvar_count; i++) {
free(subvariables[i]);
subvariables[i] = NULL;
}
free(subvariables);
free(result->label);
result->label = NULL;
goto cleanup;
}
strncpy(subvariable, start, length);
Expand All @@ -298,9 +270,10 @@ static readstat_error_t parse_mr_line(const char *line, mr_set_t *result) {
free(subvariable);
for (int i = 0; i < subvar_count; i++) {
free(subvariables[i]);
subvariables[i] = NULL;
}
free(subvariables);
free(result->label);
result->label = NULL;
goto cleanup;
}
subvariables = temp;
Expand All @@ -325,16 +298,12 @@ static readstat_error_t sav_read_multiple_response_sets(size_t data_len, sav_ctx
goto cleanup;
}
mr_string[data_len] = '\0';

if (ctx->io->read(mr_string, data_len, ctx->io->io_ctx) < data_len) {
retval = READSTAT_ERROR_PARSE;
goto cleanup;
}
if (mr_string[0] != '$') {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}

fprintf(stderr, "\n\n\nDebug: MR string: '%s'\n", mr_string);
char *token = strtok(mr_string, "$\n");
int num_lines = 0;
while (token != NULL) {
Expand All @@ -350,7 +319,6 @@ static readstat_error_t sav_read_multiple_response_sets(size_t data_len, sav_ctx
ctx->multiple_response_sets_length = num_lines;

cleanup:
free(mr_string);
return retval;
}

Expand Down Expand Up @@ -925,10 +893,6 @@ static readstat_error_t sav_process_row(unsigned char *buffer, size_t buffer_len
}
if (++offset == col_info->width) {
if (++segment_offset < var_info->n_segments) {
if (raw_str_used == 0) {
retval = READSTAT_ERROR_PARSE;
goto done;
}
raw_str_used--;
}
offset = 0;
Expand Down Expand Up @@ -1548,10 +1512,6 @@ static readstat_error_t sav_parse_records_pass1(sav_ctx_t *ctx) {
if (retval != READSTAT_OK)
goto cleanup;
} else if (subtype == SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS) {
if (ctx->mr_sets != NULL) {
retval = READSTAT_ERROR_BAD_MR_STRING;
goto cleanup;
}
retval = sav_read_multiple_response_sets(data_len, ctx);
if (retval != READSTAT_OK)
goto cleanup;
Expand Down Expand Up @@ -1905,17 +1865,8 @@ readstat_error_t readstat_parse_sav(readstat_parser_t *parser, const char *path,
spss_varinfo_t *info = (spss_varinfo_t *)ck_str_hash_lookup(sv_name_upper, var_dict);
if (info) {
free(mr.subvariables[j]);
// mr.subvariables[j] = NULL;
if ((mr.subvariables[j] = readstat_malloc(strlen(info->longname) + 1)) == NULL) {
retval = READSTAT_ERROR_MALLOC;
goto cleanup;
}
// mr.subvariables[j][strlen(info->longname)] = '\0';
strcpy(mr.subvariables[j], info->longname);
// mr.subvariables[j] = info->longname;
mr.subvariables[j] = info->longname;
}
free(sv_name_upper);
// sv_name_upper = NULL;
}
}
if (var_dict)
Expand Down

0 comments on commit 1b5fcb7

Please sign in to comment.