| 217 | DISABLE_WARNING_FORMAT_NONLITERAL |
| 218 | |
| 219 | staticfn void |
| 220 | readentry(FILE *rfile, struct toptenentry *tt) |
| 221 | { |
| 222 | char inbuf[SCANBUFSZ], s1[SCANBUFSZ], s2[SCANBUFSZ], s3[SCANBUFSZ], |
| 223 | s4[SCANBUFSZ], s5[SCANBUFSZ], s6[SCANBUFSZ]; |
| 224 | |
| 225 | #ifdef NO_SCAN_BRACK /* Version_ Pts DgnLevs_ Hp___ Died__Born id */ |
| 226 | static const char fmt[] = "%d %d %d %ld %d %d %d %d %d %d %ld %ld %d%*c"; |
| 227 | static const char fmt32[] = "%c%c %s %s%*c"; |
| 228 | static const char fmt33[] = "%s %s %s %s %s %s%*c"; |
| 229 | #else |
| 230 | static const char fmt[] = "%d.%d.%d %ld %d %d %d %d %d %d %ld %ld %d "; |
| 231 | static const char fmt32[] = "%c%c %[^,],%[^\n]%*c"; |
| 232 | static const char fmt33[] = "%s %s %s %s %[^,],%[^\n]%*c"; |
| 233 | #endif |
| 234 | |
| 235 | #ifdef UPDATE_RECORD_IN_PLACE |
| 236 | /* note: input below must read the record's terminating newline */ |
| 237 | final_fpos = tt->fpos = ftell(rfile); |
| 238 | #endif |
| 239 | #define TTFIELDS 13 |
| 240 | if (fscanf(rfile, fmt, &tt->ver_major, &tt->ver_minor, &tt->patchlevel, |
| 241 | &tt->points, &tt->deathdnum, &tt->deathlev, &tt->maxlvl, |
| 242 | &tt->hp, &tt->maxhp, &tt->deaths, &tt->deathdate, |
| 243 | &tt->birthdate, &tt->uid) != TTFIELDS) { |
| 244 | #undef TTFIELDS |
| 245 | tt->points = 0; |
| 246 | discardexcess(rfile); |
| 247 | } else { |
| 248 | /* load remainder of record into a local buffer; |
| 249 | this imposes an implicit length limit of SCANBUFSZ |
| 250 | on every string field extracted from the buffer */ |
| 251 | if (!fgets(inbuf, sizeof inbuf, rfile)) { |
| 252 | /* sscanf will fail and tt->points will be set to 0 */ |
| 253 | *inbuf = '\0'; |
| 254 | } else if (!strchr(inbuf, '\n')) { |
| 255 | Strcpy(&inbuf[sizeof inbuf - 2], "\n"); |
| 256 | discardexcess(rfile); |
| 257 | } |
| 258 | /* Check for backwards compatibility */ |
| 259 | if (tt->ver_major < 3 || (tt->ver_major == 3 && tt->ver_minor < 3)) { |
| 260 | int i; |
| 261 | |
| 262 | if (sscanf(inbuf, fmt32, tt->plrole, tt->plgend, s1, s2) == 4) { |
| 263 | tt->plrole[1] = tt->plgend[1] = '\0'; /* read via %c */ |
| 264 | copynchars(tt->name, s1, (int) (sizeof tt->name) - 1); |
| 265 | copynchars(tt->death, s2, (int) (sizeof tt->death) - 1); |
| 266 | } else |
| 267 | tt->points = 0; |
| 268 | tt->plrole[1] = '\0'; |
| 269 | if ((i = str2role(tt->plrole)) >= 0) |
| 270 | Strcpy(tt->plrole, roles[i].filecode); |
| 271 | Strcpy(tt->plrace, "?"); |
| 272 | Strcpy(tt->plgend, (tt->plgend[0] == 'M') ? "Mal" : "Fem"); |
| 273 | Strcpy(tt->plalign, "?"); |
| 274 | } else if (sscanf(inbuf, fmt33, s1, s2, s3, s4, s5, s6) == 6) { |
| 275 | copynchars(tt->plrole, s1, (int) (sizeof tt->plrole) - 1); |
| 276 | copynchars(tt->plrace, s2, (int) (sizeof tt->plrace) - 1); |
no test coverage detected