--- uniq.c Wed Sep 5 20:36:20 2007 +++ uniq.c-modified Wed Sep 5 20:24:01 2007 @@ -55,8 +55,6 @@ #include #include -#define MAXLINELEN (8 * 1024) - int cflag, dflag, uflag; int numchars, numfields, repeats; @@ -72,7 +70,8 @@ char *t1, *t2; FILE *ifp = NULL, *ofp = NULL; int ch; - char *prevline, *thisline; + char *prevline, *thisline, *p; + size_t prevlinesize, thislinesize, psize; obsolete(argv); while ((ch = getopt(argc, argv, "cdf:s:u")) != -1) { @@ -135,15 +134,25 @@ usage(); } - prevline = malloc(MAXLINELEN); - thisline = malloc(MAXLINELEN); - if (prevline == NULL || thisline == NULL) + if ((p = fgetln(ifp, &psize)) == NULL) + return 0; + prevlinesize = psize; + if ((prevline = malloc(prevlinesize + 1)) == NULL) err(1, "malloc"); + (void)memcpy(prevline, p, prevlinesize); + prevline[prevlinesize] = '\0'; - if (fgets(prevline, MAXLINELEN, ifp) == NULL) - exit(0); + thislinesize = psize; + if ((thisline = malloc(thislinesize + 1)) == NULL) + err(1, "malloc"); + while ((p = fgetln(ifp, &psize)) != NULL) { + if (psize > thislinesize) { + if ((thisline = realloc(thisline, psize + 1)) == NULL) + err(1, "realloc"); + thislinesize = psize; + } + (void)memcpy(thisline, p, psize); - while (fgets(thisline, MAXLINELEN, ifp)) { /* If requested get the chosen fields + character offsets. */ if (numfields || numchars) { t1 = skip(thisline); @@ -155,15 +164,22 @@ /* If different, print; set previous to new value. */ if (strcmp(t1, t2)) { + size_t ts; + show(ofp, prevline); t1 = prevline; prevline = thisline; thisline = t1; + ts = prevlinesize; + prevlinesize = thislinesize; + thislinesize = ts; repeats = 0; } else ++repeats; } show(ofp, prevline); + free(prevline); + free(thisline); exit(0); }