1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
#include "setest.h"
entry get_required_entry( const char *name, const st_type type, const test_context *ctx);
#include "multivalues.h"
entry get_entry(
const char *name,
const st_type type,
const test_context *ctx) {
int mv = -1, n;
char *value = NULL;
entry result = { .not_found = false };
strcpy(result.pair.name,name);
// Is it an already known multivalue entry?
mv = multivalues_get_index(name, ctx->multivalues);
if (mv >= 0) {
result.pair.tvalue = *(multivalues_get_next(mv,ctx->multivalues));
} else {
// Get entry from parameter file if given
if (ctx->parameters.source) {
value = read_value( &ctx->parameters, name, GENERAL, GENERAL);
}
// Get entry from reader if found
if (!value) {
value = read_value( &ctx->reader, name, ctx->current.section, GENERAL);
}
// Not found - leave function with not_found = true
if (!value) {
if (ctx->verbose) {
printf("Couldn't read value for '%s'\n",name);
}
result.not_found = true;
return result;
}
// Is it a (new) multivalue field?
if (is_multivalue(type,value)) {
mv = multivalues_add_index(name,type,value,ctx->multivalues);
result.pair.tvalue = *(multivalues_get_next(mv,ctx->multivalues));
} else {
switch (type) {
case D:
result.pair.tvalue.type = D;
n = sscanf(value,"%lf", &result.pair.tvalue.value.d);
if (n == 0) {
fprintf(stderr,"Couldn't scan double from '%s' in get_entry()\n",value);
exit(EXIT_FAILURE);
}
break;
case I:
result.pair.tvalue.type = I;
n = sscanf(value,"%d", &result.pair.tvalue.value.i);
if (n == 0 && *value == '\'') {
n = sscanf(value + 1,"%c", &result.pair.tvalue.value.c);
}
if (n == 0) {
fprintf(stderr,"Couldn't scan integer from '%s' in get_entry()\n",value);
exit(EXIT_FAILURE);
}
break;
case S:
result.pair.tvalue.type = S;
result.pair.tvalue.value.s = value; // copy_string(value);
break;
default:
fprintf(stderr,"Illegal type %d in get_entry()\n",type);
exit(EXIT_FAILURE);
}
}
}
if (ctx->verbose) {
printf(" read %s -> ",name);
print_value( &result.pair.tvalue, stdout );
printf(" %s\n", (mv < 0) ? "" : "(multivalue)" );
}
return result;
}
// Like get_entry, but with error on 'not found'
entry get_required_entry(
const char *name,
const st_type type,
const test_context *ctx) {
entry result = get_entry(name, type, ctx);
if (result.not_found) {
fprintf(stderr,
"Error (%s %d.%d.%d): Name '%s' could not be resolved.\n",
ctx->current.file,
ctx->current.suite.id,
ctx->current.testcase.id,
ctx->current.iteration.id,
name);
exit(EXIT_FAILURE);
}
return result;
}
double get_d( const char* name, const test_context *ctx) {
pair p = get_required_entry(name,D,ctx).pair;
print_if(!ctx->testmode,&p, ctx->out);
return p.tvalue.value.d;
}
int get_i( const char* name, const test_context *ctx) {
pair p = get_required_entry(name,I,ctx).pair;
print_if(!ctx->testmode,&p, ctx->out);
return p.tvalue.value.i;
}
const char* get_s( const char* name, const test_context *ctx) {
pair p = get_required_entry(name,S,ctx).pair;
print_if(!ctx->testmode,&p, ctx->out);
return p.tvalue.value.s;
}
void print_if( const bool condition, const pair *rec, FILE *out) {
if (condition) {
fprintf(out," %s: ",rec->name);
print_value( & rec->tvalue, out );
print_comment( rec, out );
fprintf(out,"\n");
}
}
void print_value( const typed_value *value, FILE *out ) {
switch (value->type) {
case D:
fprintf(out,"%.20lf",value->value.d);
break;
case I:
fprintf(out,"%d",value->value.i);
break;
case S:
fprintf(out,"%s",value->value.s);
default:
break;
}
}
void print_comment(const pair *rec,FILE *out) {
int ival = rec->tvalue.value.i;
if (equals(rec->name,"ipl")) {
char name[50];
swe_get_planet_name(rec->tvalue.value.i,name);
fprintf(out," # %s",name);
return;
} else if (equals(rec->name,"iflag")||equals(rec->name,"iephe")) {
int iflags = rec->tvalue.value.i,
i = 0;
bool first = true;
fprintf(out," # ");
while (iflags != 0) {
if (equals(SEFLG[i],"")) {
fprintf(out,"%s2^%d",first?"":"+",i);
break;
}
else {
if (iflags % 2 == 1) {
fprintf(out,"%s%s",first?"":"+",SEFLG[i]);
first = false;
}
i++;
}
iflags >>= 1;
}
} else if (equals(rec->name,"jd") || equals(rec->name,"jd_ut") || equals(rec->name,"jx")) {
int day, month, year, ihour, imin, isec, isgn;
double ut, dfr;
swe_revjul(rec->tvalue.value.d,1,&year,&month,&day,&ut);
swe_split_deg(ut, SE_SPLIT_DEG_ROUND_SEC, &ihour, &imin, &isec, &dfr, &isgn);
fprintf(out," # %d.%d.%d %02d:%02d:%02d",day,month,year,ihour, imin, isec);
} else if (rec->tvalue.type == I && ival >=32 && ival < 128 ) {
fprintf(out," # '%c'", ival);
}
}
void st_free( const typed_value *v) {
if (!v->on_heap) return;
if (v->type == P && v->value.p != 0) free(v->value.p);
// Normally, it's weird casting const to non-const, but at the end of it's lifecycle it's OK:
if (v->type == S && v->value.s != 0) free((char *)v->value.s);
}
#undef SETEST_H_PRIVATE
|