| 6 |  | */ | 
| 7 |  |  | 
| 8 |  | #include <stdlib.h> | 
| 9 | – | #include <unistd.h> | 
| 9 |  | #include <string.h> | 
| 10 |  | #include <ctype.h> | 
| 11 |  | #include "platform.h" | 
| 12 |  | #include "rtio.h" | 
| 13 |  | #include "resolu.h" | 
| 14 | < | #ifndef _WIN32 | 
| 14 | > | #ifdef _WIN32 | 
| 15 | > | #undef ftello | 
| 16 | > | #define ftello  ftell | 
| 17 | > | #undef ssize_t | 
| 18 | > | #define ssize_t size_t | 
| 19 | > | #else | 
| 20 |  | #include <sys/mman.h> | 
| 21 |  | #endif | 
| 22 |  |  | 
| 39 |  | char    *rec[1];        /* record array (extends struct) */ | 
| 40 |  | } RECINDEX; | 
| 41 |  |  | 
| 42 | + | int             warnings = 1;   /* report warnings? */ | 
| 43 | + |  | 
| 44 |  | /* free loaded file */ | 
| 45 |  | static void | 
| 46 |  | free_load(MEMLOAD *mp) | 
| 79 |  | mp->len = (size_t)(flen - skip); | 
| 80 |  | #ifdef MAP_FILE | 
| 81 |  | if (mp->len > 1L<<20) {         /* map file if > 1 MByte */ | 
| 82 | < | mp->base = mmap(NULL, mp->len, PROT_READ|PROT_WRITE, | 
| 77 | < | MAP_PRIVATE, fd, skip); | 
| 82 | > | mp->base = mmap(NULL, mp->len, PROT_READ, MAP_PRIVATE, fd, skip); | 
| 83 |  | if (mp->base != MAP_FAILED) { | 
| 84 |  | mp->mapped = 1; | 
| 85 |  | return(1);      /* mmap() success */ | 
| 103 |  | static int | 
| 104 |  | load_stream(MEMLOAD *mp, FILE *fp) | 
| 105 |  | { | 
| 106 | + | size_t  alloced = 0; | 
| 107 |  | char    buf[8192]; | 
| 108 |  | size_t  nr; | 
| 109 |  |  | 
| 115 |  | if (fp == NULL) | 
| 116 |  | return(-1); | 
| 117 |  | while ((nr = fread(buf, 1, sizeof(buf), fp)) > 0) { | 
| 118 | < | if (!mp->len) | 
| 118 | > | if (!alloced) | 
| 119 |  | mp->base = malloc(nr); | 
| 120 | < | else | 
| 121 | < | mp->base = realloc(mp->base, mp->len+nr); | 
| 120 | > | else if (mp->len+nr > alloced) | 
| 121 | > | mp->base = realloc(mp->base, | 
| 122 | > | alloced = alloced*(2+(nr==sizeof(buf)))/2+nr); | 
| 123 |  | if (mp->base == NULL) | 
| 124 |  | return(-1); | 
| 125 |  | memcpy((char *)mp->base + mp->len, buf, nr); | 
| 129 |  | free_load(mp); | 
| 130 |  | return(-1); | 
| 131 |  | } | 
| 132 | + | if (alloced > mp->len*5/4)      /* don't waste too much space */ | 
| 133 | + | mp->base = realloc(mp->base, mp->len); | 
| 134 |  | return(mp->len > 0); | 
| 135 |  | } | 
| 136 |  |  | 
| 282 |  | RECINDEX                *rp = NULL; | 
| 283 |  | long                    nrecords; | 
| 284 |  | int                     i, j; | 
| 285 | + | /* propogate sizes */ | 
| 286 | + | if (ni_rows <= 0) | 
| 287 | + | ni_rows = no_columns; | 
| 288 | + | if (ni_columns <= 0) | 
| 289 | + | ni_columns = no_rows; | 
| 290 |  | /* get # records (& index) */ | 
| 291 |  | if (record_width > 0) { | 
| 292 |  | if ((rp = index_records(mp, record_width)) == NULL) | 
| 294 |  | if (ni_columns <= 0) | 
| 295 |  | ni_columns = count_columns(rp); | 
| 296 |  | nrecords = rp->nrecs; | 
| 297 | < | } else if ((ni_rows > 0) & (ni_columns > 0)) | 
| 297 | > | } else if ((ni_rows > 0) & (ni_columns > 0)) { | 
| 298 |  | nrecords = ni_rows*ni_columns; | 
| 299 | < | else | 
| 299 | > | if (nrecords > mp->len / -record_width) { | 
| 300 | > | fprintf(stderr, | 
| 301 | > | "Input too small for specified size and type\n"); | 
| 302 | > | return(0); | 
| 303 | > | } | 
| 304 | > | } else | 
| 305 |  | nrecords = mp->len / -record_width; | 
| 306 |  | /* check sizes */ | 
| 288 | – | if (ni_rows <= 0) | 
| 289 | – | ni_rows = no_columns; | 
| 290 | – | if (ni_columns <= 0) | 
| 291 | – | ni_columns = no_rows; | 
| 307 |  | if ((ni_rows <= 0) & (ni_columns > 0)) | 
| 308 |  | ni_rows = nrecords/ni_columns; | 
| 309 |  | if ((ni_columns <= 0) & (ni_rows > 0)) | 
| 394 |  | putc('\t', stdout); | 
| 395 |  | } while (--records2go);                 /* expected EOD? */ | 
| 396 |  | done: | 
| 397 | < | if (columns2go != no_columns) | 
| 397 | > | if (warnings && columns2go != no_columns) | 
| 398 |  | fprintf(stderr, "Warning -- incomplete final row\n"); | 
| 399 | < | if (fget_word(word, fp) != NULL) | 
| 400 | < | fprintf(stderr, "Warning -- data beyond expected EOF\n"); | 
| 399 | > | if (warnings && fget_word(word, fp) != NULL) | 
| 400 | > | fprintf(stderr, "Warning -- characters beyond expected EOD\n"); | 
| 401 |  | return(1); | 
| 402 |  | } | 
| 403 |  |  | 
| 480 |  | record_width *= atoi(argv[i]+3); | 
| 481 |  | } | 
| 482 |  | break; | 
| 483 | + | case 'w':                       /* warnings on/off */ | 
| 484 | + | warnings = !warnings; | 
| 485 | + | break; | 
| 486 |  | default: | 
| 487 |  | goto userr; | 
| 488 |  | } | 
| 502 |  | /* check for no-op */ | 
| 503 |  | if (!transpose && (record_width < 0 || | 
| 504 |  | (no_columns == ni_columns) & (no_rows == ni_rows))) { | 
| 505 | < | fprintf(stderr, "%s: no-op -- copying input verbatim\n", | 
| 505 | > | if (warnings) | 
| 506 | > | fprintf(stderr, "%s: no-op -- copying input verbatim\n", | 
| 507 |  | argv[0]); | 
| 508 |  | if (!output_stream(stdin)) | 
| 509 |  | return(1); | 
| 537 |  | return(0); | 
| 538 |  | userr: | 
| 539 |  | fprintf(stderr, | 
| 540 | < | "Usage: %s [-h][-f[afdb][N]][-t][-ic in_col][-ir in_row][-oc out_col][-or out_row] [input.dat]\n", | 
| 540 | > | "Usage: %s [-h][-w][-f[afdb][N]][-t][-ic in_col][-ir in_row][-oc out_col][-or out_row] [input.dat]\n", | 
| 541 |  | argv[0]); | 
| 542 |  | return(1); | 
| 543 |  | } |