Mercurial > hg > toybox
comparison toys/sort.c @ 433:9e7aaecf0683
Fix sort -uc (pointer vs pointer to pointer confusion, covered by typecast).
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 07 Feb 2012 00:31:37 -0600 |
parents | 87edfe8ae99e |
children | 55d815926c5c |
comparison
equal
deleted
inserted
replaced
432:01473712c9fe | 433:9e7aaecf0683 |
---|---|
257 | 257 |
258 // Callback from qsort(): Iterate through key_list and perform comparisons. | 258 // Callback from qsort(): Iterate through key_list and perform comparisons. |
259 static int compare_keys(const void *xarg, const void *yarg) | 259 static int compare_keys(const void *xarg, const void *yarg) |
260 { | 260 { |
261 int flags = toys.optflags, retval = 0; | 261 int flags = toys.optflags, retval = 0; |
262 char *x, *y, **xx = (char **)xarg, **yy = (char **)yarg; | 262 char *x, *y, *xx = *(char **)xarg, *yy = *(char **)yarg; |
263 struct sort_key *key; | 263 struct sort_key *key; |
264 | 264 |
265 if (CFG_SORT_BIG) { | 265 if (CFG_SORT_BIG) { |
266 for (key=(struct sort_key *)TT.key_list; !retval && key; | 266 for (key=(struct sort_key *)TT.key_list; !retval && key; |
267 key = key->next_key) | 267 key = key->next_key) |
268 { | 268 { |
269 flags = key->flags ? key->flags : toys.optflags; | 269 flags = key->flags ? key->flags : toys.optflags; |
270 | 270 |
271 // Chop out and modify key chunks, handling -dfib | 271 // Chop out and modify key chunks, handling -dfib |
272 | 272 |
273 x = get_key_data(*xx, key, flags); | 273 x = get_key_data(xx, key, flags); |
274 y = get_key_data(*yy, key, flags); | 274 y = get_key_data(yy, key, flags); |
275 | 275 |
276 retval = compare_values(flags, x, y); | 276 retval = compare_values(flags, x, y); |
277 | 277 |
278 // Free the copies get_key_data() made. | 278 // Free the copies get_key_data() made. |
279 | 279 |
280 if (x != *xx) free(x); | 280 if (x != xx) free(x); |
281 if (y != *yy) free(y); | 281 if (y != yy) free(y); |
282 | 282 |
283 if (retval) break; | 283 if (retval) break; |
284 } | 284 } |
285 } else retval = compare_values(flags, *xx, *yy); | 285 } else retval = compare_values(flags, xx, yy); |
286 | 286 |
287 // Perform fallback sort if necessary | 287 // Perform fallback sort if necessary |
288 if (!retval && !(CFG_SORT_BIG && (toys.optflags&FLAG_s))) { | 288 if (!retval && !(CFG_SORT_BIG && (toys.optflags&FLAG_s))) { |
289 retval = strcmp(*xx, *yy); | 289 retval = strcmp(xx, yy); |
290 flags = toys.optflags; | 290 flags = toys.optflags; |
291 } | 291 } |
292 | 292 |
293 return retval * ((flags&FLAG_r) ? -1 : 1); | 293 return retval * ((flags&FLAG_r) ? -1 : 1); |
294 } | 294 } |
306 | 306 |
307 // handle -c here so we don't allocate more memory than necessary. | 307 // handle -c here so we don't allocate more memory than necessary. |
308 if (CFG_SORT_BIG && (toys.optflags&FLAG_c)) { | 308 if (CFG_SORT_BIG && (toys.optflags&FLAG_c)) { |
309 int j = (toys.optflags&FLAG_u) ? -1 : 0; | 309 int j = (toys.optflags&FLAG_u) ? -1 : 0; |
310 | 310 |
311 if (TT.linecount && compare_keys((char *)TT.lines,line)>j) | 311 if (TT.lines && compare_keys((char **)&TT.lines, &line)>j) |
312 error_exit("%s: Check line %d\n", name, TT.linecount); | 312 error_exit("%s: Check line %d\n", name, TT.linecount); |
313 | 313 free(TT.lines); |
314 if (TT.lines) free(TT.lines); | |
315 else TT.linecount = 0; | |
316 TT.lines = (char **)line; | 314 TT.lines = (char **)line; |
317 } else { | 315 } else { |
318 if (!(TT.linecount&63)) | 316 if (!(TT.linecount&63)) |
319 TT.lines = xrealloc(TT.lines, sizeof(char *)*(TT.linecount+64)); | 317 TT.lines = xrealloc(TT.lines, sizeof(char *)*(TT.linecount+64)); |
320 TT.lines[TT.linecount] = line; | 318 TT.lines[TT.linecount] = line; |
389 // Open input files and read data, populating TT.lines[TT.linecount] | 387 // Open input files and read data, populating TT.lines[TT.linecount] |
390 loopfiles(toys.optargs, sort_read); | 388 loopfiles(toys.optargs, sort_read); |
391 | 389 |
392 // The compare (-c) logic was handled in sort_read(), | 390 // The compare (-c) logic was handled in sort_read(), |
393 // so if we got here, we're done. | 391 // so if we got here, we're done. |
394 if (CFG_SORT_BIG && (toys.optflags&FLAG_c)) return; | 392 if (CFG_SORT_BIG && (toys.optflags&FLAG_c)) goto exit_now; |
395 | 393 |
396 // Perform the actual sort | 394 // Perform the actual sort |
397 qsort(TT.lines, TT.linecount, sizeof(char *), compare_keys); | 395 qsort(TT.lines, TT.linecount, sizeof(char *), compare_keys); |
398 | 396 |
399 // handle unique (-u) | 397 // handle unique (-u) |
414 xwrite(fd, s, strlen(s)); | 412 xwrite(fd, s, strlen(s)); |
415 if (CFG_TOYBOX_FREE) free(s); | 413 if (CFG_TOYBOX_FREE) free(s); |
416 xwrite(fd, "\n", 1); | 414 xwrite(fd, "\n", 1); |
417 } | 415 } |
418 | 416 |
417 exit_now: | |
419 if (CFG_TOYBOX_FREE) { | 418 if (CFG_TOYBOX_FREE) { |
420 if (fd != 1) close(fd); | 419 if (fd != 1) close(fd); |
421 free(TT.lines); | 420 free(TT.lines); |
422 } | 421 } |
423 } | 422 } |