numericsort.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * "$Id: numericsort.c 7903 2010-11-28 21:06:39Z matt $"
  3. *
  4. * Numeric sorting routine for the Fast Light Tool Kit (FLTK).
  5. *
  6. * Copyright 1998-2010 by Bill Spitzak and others.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Library General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Library General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Library General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. * USA.
  22. *
  23. * Please report all bugs and problems on the following page:
  24. *
  25. * http://www.fltk.org/str.php
  26. */
  27. /* My own scandir sorting function, useful for the film industry where
  28. we have many files with numbers in their names: */
  29. #include <config.h>
  30. #include <ctype.h>
  31. #include <stdlib.h>
  32. #include <sys/types.h>
  33. #include <FL/filename.H>
  34. #if !defined(WIN32) || defined(__CYGWIN__)
  35. # ifdef HAVE_DIRENT_H
  36. # include <dirent.h>
  37. # else
  38. # define dirent direct
  39. # if HAVE_SYS_NDIR_H
  40. # include <sys/ndir.h>
  41. # endif /* HAVE_SYS_NDIR_H */
  42. # if HAVE_SYS_DIR_H
  43. # include <sys/dir.h>
  44. # endif /* HAVE_SYS_DIR_H */
  45. # if HAVE_NDIR_H
  46. # include <ndir.h>
  47. # endif /* HAVE_NDIR_H */
  48. # endif /* HAVE_DIRENT_H */
  49. #endif /* !WIN32 || __CYGWIN__ */
  50. /*
  51. * 'numericsort()' - Compare two directory entries, possibly with
  52. * a case-insensitive comparison...
  53. */
  54. static int numericsort(struct dirent **A, struct dirent **B, int cs) {
  55. const char* a = (*A)->d_name;
  56. const char* b = (*B)->d_name;
  57. int ret = 0;
  58. for (;;) {
  59. if (isdigit(*a & 255) && isdigit(*b & 255)) {
  60. int diff,magdiff;
  61. while (*a == '0') a++;
  62. while (*b == '0') b++;
  63. while (isdigit(*a & 255) && *a == *b) {a++; b++;}
  64. diff = (isdigit(*a & 255) && isdigit(*b & 255)) ? *a - *b : 0;
  65. magdiff = 0;
  66. while (isdigit(*a & 255)) {magdiff++; a++;}
  67. while (isdigit(*b & 255)) {magdiff--; b++;}
  68. if (magdiff) {ret = magdiff; break;} /* compare # of significant digits*/
  69. if (diff) {ret = diff; break;} /* compare first non-zero digit */
  70. } else {
  71. if (cs) {
  72. /* compare case-sensitive */
  73. if ((ret = *a-*b)) break;
  74. } else {
  75. /* compare case-insensitve */
  76. if ((ret = tolower(*a & 255)-tolower(*b & 255))) break;
  77. }
  78. if (!*a) break;
  79. a++; b++;
  80. }
  81. }
  82. if (!ret) return 0;
  83. else return (ret < 0) ? -1 : 1;
  84. }
  85. /*
  86. * 'fl_casenumericsort()' - Compare directory entries with case-sensitivity.
  87. */
  88. int fl_casenumericsort(struct dirent **A, struct dirent **B) {
  89. return numericsort(A, B, 0);
  90. }
  91. /*
  92. * 'fl_numericsort()' - Compare directory entries with case-sensitivity.
  93. */
  94. int fl_numericsort(struct dirent **A, struct dirent **B) {
  95. return numericsort(A, B, 1);
  96. }
  97. /*
  98. * End of "$Id: numericsort.c 7903 2010-11-28 21:06:39Z matt $".
  99. */