Skip to content

Commit 140f047

Browse files
authored
Enhance missing value handling for multiple data types in JSON output (#348)
1 parent 43c1b7c commit 140f047

1 file changed

Lines changed: 141 additions & 9 deletions

File tree

src/bin/write/json/write_missing_values.c

Lines changed: 141 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,58 @@ static void handle_missing_discrete(struct context *ctx, readstat_variable_t *va
2020
for (int i=0; i<missing_ranges_count; i++) {
2121
readstat_value_t lo_val = readstat_variable_get_missing_range_lo(variable, i);
2222
readstat_value_t hi_val = readstat_variable_get_missing_range_hi(variable, i);
23+
readstat_type_t lo_type = readstat_value_type(lo_val);
24+
2325
if (i>=1) {
2426
fprintf(ctx->fp, ", ");
2527
}
2628

27-
if (readstat_value_type(lo_val) == READSTAT_TYPE_DOUBLE) {
29+
if (lo_type == READSTAT_TYPE_STRING) {
30+
const char *lo = readstat_string_value(lo_val);
31+
const char *hi = readstat_string_value(hi_val);
32+
if (strcmp(lo, hi) == 0) {
33+
fprintf(ctx->fp, "\"%s\"", lo);
34+
} else {
35+
fprintf(stderr, "%s:%d column %s unsupported string range lo '%s' hi '%s'\n", __FILE__, __LINE__, variable->name, lo, hi);
36+
exit(EXIT_FAILURE);
37+
}
38+
} else if (lo_type == READSTAT_TYPE_INT8) {
39+
char lo = readstat_int8_value(lo_val);
40+
char hi = readstat_int8_value(hi_val);
41+
if (lo == hi) {
42+
fprintf(ctx->fp, "%d", (int)lo);
43+
} else {
44+
fprintf(stderr, "%s:%d column %s unsupported lo %d hi %d\n", __FILE__, __LINE__, variable->name, (int)lo, (int)hi);
45+
exit(EXIT_FAILURE);
46+
}
47+
} else if (lo_type == READSTAT_TYPE_INT16) {
48+
int16_t lo = readstat_int16_value(lo_val);
49+
int16_t hi = readstat_int16_value(hi_val);
50+
if (lo == hi) {
51+
fprintf(ctx->fp, "%d", (int)lo);
52+
} else {
53+
fprintf(stderr, "%s:%d column %s unsupported lo %d hi %d\n", __FILE__, __LINE__, variable->name, (int)lo, (int)hi);
54+
exit(EXIT_FAILURE);
55+
}
56+
} else if (lo_type == READSTAT_TYPE_INT32) {
57+
int32_t lo = readstat_int32_value(lo_val);
58+
int32_t hi = readstat_int32_value(hi_val);
59+
if (lo == hi) {
60+
fprintf(ctx->fp, "%d", lo);
61+
} else {
62+
fprintf(stderr, "%s:%d column %s unsupported lo %d hi %d\n", __FILE__, __LINE__, variable->name, lo, hi);
63+
exit(EXIT_FAILURE);
64+
}
65+
} else if (lo_type == READSTAT_TYPE_FLOAT) {
66+
float lo = readstat_float_value(lo_val);
67+
float hi = readstat_float_value(hi_val);
68+
if (lo == hi) {
69+
fprintf(ctx->fp, "%g", lo);
70+
} else {
71+
fprintf(stderr, "%s:%d column %s unsupported lo %f hi %f\n", __FILE__, __LINE__, variable->name, lo, hi);
72+
exit(EXIT_FAILURE);
73+
}
74+
} else if (lo_type == READSTAT_TYPE_DOUBLE) {
2875
double lo = readstat_double_value(lo_val);
2976
double hi = readstat_double_value(hi_val);
3077
if (lo == hi && spss_date) {
@@ -42,7 +89,7 @@ static void handle_missing_discrete(struct context *ctx, readstat_variable_t *va
4289
exit(EXIT_FAILURE);
4390
}
4491
} else {
45-
fprintf(stderr, "%s:%d unsupported missing type\n", __FILE__, __LINE__);
92+
fprintf(stderr, "%s:%d unsupported missing type %d\n", __FILE__, __LINE__, lo_type);
4693
exit(EXIT_FAILURE);
4794
}
4895
}
@@ -58,11 +105,53 @@ static void handle_missing_range(struct context *ctx, readstat_variable_t *varia
58105
for (int i=0; i<missing_ranges_count; i++) {
59106
readstat_value_t lo_val = readstat_variable_get_missing_range_lo(variable, i);
60107
readstat_value_t hi_val = readstat_variable_get_missing_range_hi(variable, i);
108+
readstat_type_t lo_type = readstat_value_type(lo_val);
109+
61110
if (i>=1) {
62111
fprintf(ctx->fp, ", ");
63112
}
64113

65-
if (readstat_value_type(lo_val) == READSTAT_TYPE_DOUBLE) {
114+
if (lo_type == READSTAT_TYPE_STRING) {
115+
const char *lo = readstat_string_value(lo_val);
116+
const char *hi = readstat_string_value(hi_val);
117+
if (strcmp(lo, hi) == 0) {
118+
fprintf(ctx->fp, "\"discrete-value\": \"%s\"", lo);
119+
} else {
120+
fprintf(ctx->fp, "\"low\": \"%s\", \"high\": \"%s\"", lo, hi);
121+
}
122+
} else if (lo_type == READSTAT_TYPE_INT8) {
123+
char lo = readstat_int8_value(lo_val);
124+
char hi = readstat_int8_value(hi_val);
125+
if (lo == hi) {
126+
fprintf(ctx->fp, "\"discrete-value\": %d", (int)lo);
127+
} else {
128+
fprintf(ctx->fp, "\"low\": %d, \"high\": %d", (int)lo, (int)hi);
129+
}
130+
} else if (lo_type == READSTAT_TYPE_INT16) {
131+
int16_t lo = readstat_int16_value(lo_val);
132+
int16_t hi = readstat_int16_value(hi_val);
133+
if (lo == hi) {
134+
fprintf(ctx->fp, "\"discrete-value\": %d", (int)lo);
135+
} else {
136+
fprintf(ctx->fp, "\"low\": %d, \"high\": %d", (int)lo, (int)hi);
137+
}
138+
} else if (lo_type == READSTAT_TYPE_INT32) {
139+
int32_t lo = readstat_int32_value(lo_val);
140+
int32_t hi = readstat_int32_value(hi_val);
141+
if (lo == hi) {
142+
fprintf(ctx->fp, "\"discrete-value\": %d", lo);
143+
} else {
144+
fprintf(ctx->fp, "\"low\": %d, \"high\": %d", lo, hi);
145+
}
146+
} else if (lo_type == READSTAT_TYPE_FLOAT) {
147+
float lo = readstat_float_value(lo_val);
148+
float hi = readstat_float_value(hi_val);
149+
if (lo == hi) {
150+
fprintf(ctx->fp, "\"discrete-value\": %g", lo);
151+
} else {
152+
fprintf(ctx->fp, "\"low\": %g, \"high\": %g", lo, hi);
153+
}
154+
} else if (lo_type == READSTAT_TYPE_DOUBLE) {
66155
double lo = readstat_double_value(lo_val);
67156
double hi = readstat_double_value(hi_val);
68157
if (spss_date) {
@@ -91,7 +180,7 @@ static void handle_missing_range(struct context *ctx, readstat_variable_t *varia
91180
}
92181
}
93182
} else {
94-
fprintf(stderr, "%s:%d unsupported missing type\n", __FILE__, __LINE__);
183+
fprintf(stderr, "%s:%d unsupported missing type %d\n", __FILE__, __LINE__, lo_type);
95184
exit(EXIT_FAILURE);
96185
}
97186
}
@@ -106,12 +195,55 @@ void add_missing_values(struct context *ctx, readstat_variable_t *variable) {
106195

107196
int is_range = 0;
108197
int discrete = 0;
109-
int only_double = 1;
198+
int supported_type = 1;
110199

111200
for (int i=0; i<missing_ranges_count; i++) {
112201
readstat_value_t lo_val = readstat_variable_get_missing_range_lo(variable, i);
113202
readstat_value_t hi_val = readstat_variable_get_missing_range_hi(variable, i);
114-
if (readstat_value_type(lo_val) == READSTAT_TYPE_DOUBLE && readstat_value_type(hi_val) == READSTAT_TYPE_DOUBLE) {
203+
readstat_type_t lo_type = readstat_value_type(lo_val);
204+
205+
// Check if types are supported (STRING, INT8, INT16, INT32, FLOAT, DOUBLE)
206+
if (lo_type == READSTAT_TYPE_STRING) {
207+
const char *lo = readstat_string_value(lo_val);
208+
const char *hi = readstat_string_value(hi_val);
209+
if (strcmp(lo, hi) != 0) {
210+
is_range = 1;
211+
} else {
212+
discrete = 1;
213+
}
214+
} else if (lo_type == READSTAT_TYPE_INT8) {
215+
char lo = readstat_int8_value(lo_val);
216+
char hi = readstat_int8_value(hi_val);
217+
if (lo != hi) {
218+
is_range = 1;
219+
} else {
220+
discrete = 1;
221+
}
222+
} else if (lo_type == READSTAT_TYPE_INT16) {
223+
int16_t lo = readstat_int16_value(lo_val);
224+
int16_t hi = readstat_int16_value(hi_val);
225+
if (lo != hi) {
226+
is_range = 1;
227+
} else {
228+
discrete = 1;
229+
}
230+
} else if (lo_type == READSTAT_TYPE_INT32) {
231+
int32_t lo = readstat_int32_value(lo_val);
232+
int32_t hi = readstat_int32_value(hi_val);
233+
if (lo != hi) {
234+
is_range = 1;
235+
} else {
236+
discrete = 1;
237+
}
238+
} else if (lo_type == READSTAT_TYPE_FLOAT) {
239+
float lo = readstat_float_value(lo_val);
240+
float hi = readstat_float_value(hi_val);
241+
if (lo != hi) {
242+
is_range = 1;
243+
} else {
244+
discrete = 1;
245+
}
246+
} else if (lo_type == READSTAT_TYPE_DOUBLE) {
115247
double lo = readstat_double_value(lo_val);
116248
double hi = readstat_double_value(hi_val);
117249
if (lo != hi) {
@@ -120,12 +252,12 @@ void add_missing_values(struct context *ctx, readstat_variable_t *variable) {
120252
discrete = 1;
121253
}
122254
} else {
123-
only_double = 0;
255+
supported_type = 0;
124256
}
125257
}
126258

127-
if (!only_double) {
128-
fprintf(stderr, "%s:%d only implemented double support for missing values\n", __FILE__, __LINE__);
259+
if (!supported_type) {
260+
fprintf(stderr, "%s:%d unsupported type for missing values\n", __FILE__, __LINE__);
129261
exit(EXIT_FAILURE);
130262
}
131263

0 commit comments

Comments
 (0)