You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.2KB

  1. /*
  2. * "$Id: numericsort.c 8074 2010-12-20 13:45:26Z ianmacarthur $"
  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. #if !defined(WIN32) || defined(__CYGWIN__)
  34. # ifdef HAVE_DIRENT_H
  35. # include <dirent.h>
  36. # else
  37. # define dirent direct
  38. # if HAVE_SYS_NDIR_H
  39. # include <sys/ndir.h>
  40. # endif /* HAVE_SYS_NDIR_H */
  41. # if HAVE_SYS_DIR_H
  42. # include <sys/dir.h>
  43. # endif /* HAVE_SYS_DIR_H */
  44. # if HAVE_NDIR_H
  45. # include <ndir.h>
  46. # endif /* HAVE_NDIR_H */
  47. # endif /* HAVE_DIRENT_H */
  48. #else /* For WIN32 variants */
  49. # include <FL/filename.H>
  50. #endif /* !WIN32 || __CYGWIN__ */
  51. /*
  52. * 'numericsort()' - Compare two directory entries, possibly with
  53. * a case-insensitive comparison...
  54. */
  55. static int numericsort(struct dirent **A, struct dirent **B, int cs) {
  56. const char* a = (*A)->d_name;
  57. const char* b = (*B)->d_name;
  58. int ret = 0;
  59. for (;;) {
  60. if (isdigit(*a & 255) && isdigit(*b & 255)) {
  61. int diff,magdiff;
  62. while (*a == '0') a++;
  63. while (*b == '0') b++;
  64. while (isdigit(*a & 255) && *a == *b) {a++; b++;}
  65. diff = (isdigit(*a & 255) && isdigit(*b & 255)) ? *a - *b : 0;
  66. magdiff = 0;
  67. while (isdigit(*a & 255)) {magdiff++; a++;}
  68. while (isdigit(*b & 255)) {magdiff--; b++;}
  69. if (magdiff) {ret = magdiff; break;} /* compare # of significant digits*/
  70. if (diff) {ret = diff; break;} /* compare first non-zero digit */
  71. } else {
  72. if (cs) {
  73. /* compare case-sensitive */
  74. if ((ret = *a-*b)) break;
  75. } else {
  76. /* compare case-insensitve */
  77. if ((ret = tolower(*a & 255)-tolower(*b & 255))) break;
  78. }
  79. if (!*a) break;
  80. a++; b++;
  81. }
  82. }
  83. if (!ret) return 0;
  84. else return (ret < 0) ? -1 : 1;
  85. }
  86. /*
  87. * 'fl_casenumericsort()' - Compare directory entries with case-sensitivity.
  88. */
  89. int fl_casenumericsort(struct dirent **A, struct dirent **B) {
  90. return numericsort(A, B, 0);
  91. }
  92. /*
  93. * 'fl_numericsort()' - Compare directory entries with case-sensitivity.
  94. */
  95. int fl_numericsort(struct dirent **A, struct dirent **B) {
  96. return numericsort(A, B, 1);
  97. }
  98. /*
  99. * End of "$Id: numericsort.c 8074 2010-12-20 13:45:26Z ianmacarthur $".
  100. */