Ticket #1994: versionsort.patch

File versionsort.patch, 5.8 KB (added by bvk, 14 years ago)
  • lib/strutil.h

    diff --git a/lib/strutil.h b/lib/strutil.h
    index 264d30f..2c5252d 100644
    a b int str_isutf8 (const char *codeset_name); 
    508508 
    509509const char *str_detect_termencoding (void); 
    510510 
     511int str_verscmp(const char *s1, const char *s2); 
    511512#endif                          /* MC_STRUTIL_H*/ 
  • lib/strutil/Makefile.am

    diff --git a/lib/strutil/Makefile.am b/lib/strutil/Makefile.am
    index 488833f..e7aceaf 100644
    a b libmcstrutil_la_SOURCES = \ 
    55        strutil8bit.c \ 
    66        strutilascii.c \ 
    77        strutil.c \ 
    8         strutilutf8.c 
     8        strutilutf8.c \ 
     9        strverscmp.c 
    910 
    1011 
    1112 
  • lib/strutil/strverscmp.c

    diff --git a/lib/strutil/strverscmp.c b/lib/strutil/strverscmp.c
    index e69de29..59eac76 100644
    a b  
     1/* Compare strings while treating digits characters numerically. 
     2   Copyright (C) 1997, 2002 Free Software Foundation, Inc. 
     3   This file is part of the GNU C Library. 
     4   Contributed by Jean-Fran�ois Bignolles <bignolle ecoledoc ibp fr>, 1997. 
     5 
     6   The GNU C Library is free software; you can redistribute it and/or 
     7   modify it under the terms of the GNU Lesser General Public 
     8   License as published by the Free Software Foundation; either 
     9   version 2.1 of the License, or (at your option) any later version. 
     10 
     11   The GNU C Library is distributed in the hope that it will be useful, 
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     14   Lesser General Public License for more details. 
     15 
     16   You should have received a copy of the GNU Lesser General Public 
     17   License along with the GNU C Library; if not, write to the Free 
     18   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
     19   02111-1307 USA.  */ 
     20 
     21#include <ctype.h> 
     22#include "lib/strutil.h" 
     23 
     24/* states: S_N: normal, S_I: comparing integral part, S_F: comparing 
     25           fractionnal parts, S_Z: idem but with leading Zeroes only */ 
     26#define  S_N    0x0 
     27#define  S_I    0x4 
     28#define  S_F    0x8 
     29#define  S_Z    0xC 
     30 
     31/* result_type: CMP: return diff; LEN: compare using len_diff/diff */ 
     32#define  CMP    2 
     33#define  LEN    3 
     34 
     35 
     36/* Compare S1 and S2 as strings holding indices/version numbers, 
     37   returning less than, equal to or greater than zero if S1 is less than, 
     38   equal to or greater than S2 (for more info, see the texinfo doc). 
     39*/ 
     40 
     41int str_verscmp (const char *s1, const char *s2) 
     42{ 
     43  unsigned char *p1 = (unsigned char *) s1; 
     44  unsigned char *p2 = (unsigned char *) s2; 
     45  unsigned char c1, c2; 
     46  int state; 
     47  int diff; 
     48 
     49  /* Symbol(s)    0       [1-9]   others  (padding) 
     50     Transition   (10) 0  (01) d  (00) x  (11) -   */ 
     51  static const unsigned int next_state[] = 
     52  { 
     53      /* state    x    d    0    - */ 
     54      /* S_N */  S_N, S_I, S_Z, S_N, 
     55      /* S_I */  S_N, S_I, S_I, S_I, 
     56      /* S_F */  S_N, S_F, S_F, S_F, 
     57      /* S_Z */  S_N, S_F, S_Z, S_Z 
     58  }; 
     59 
     60  static const int result_type[] = 
     61  { 
     62      /* state   x/x  x/d  x/0  x/-  d/x  d/d  d/0  d/- 
     63                 0/x  0/d  0/0  0/-  -/x  -/d  -/0  -/- */ 
     64 
     65      /* S_N */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, 
     66                 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 
     67      /* S_I */  CMP, -1,  -1,  CMP, +1,  LEN, LEN, CMP, 
     68                 +1,  LEN, LEN, CMP, CMP, CMP, CMP, CMP, 
     69      /* S_F */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, 
     70                 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 
     71      /* S_Z */  CMP, +1,  +1,  CMP, -1,  CMP, CMP, CMP, 
     72                 -1,  CMP, CMP, CMP 
     73  }; 
     74 
     75  if (p1 == p2) 
     76    return 0; 
     77 
     78  c1 = *p1++; 
     79  c2 = *p2++; 
     80  /* Hint: '0' is a digit too.  */ 
     81  state = S_N | ((c1 == '0') + (isdigit (c1) != 0)); 
     82 
     83  while ((diff = c1 - c2) == 0 && c1 != '\0') 
     84    { 
     85      state = next_state[state]; 
     86      c1 = *p1++; 
     87      c2 = *p2++; 
     88      state |= (c1 == '0') + (isdigit (c1) != 0); 
     89    } 
     90 
     91  state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))]; 
     92 
     93  switch (state) 
     94  { 
     95    case CMP: 
     96      return diff; 
     97 
     98    case LEN: 
     99      while (isdigit (*p1++)) 
     100        if (!isdigit (*p2++)) 
     101          return 1; 
     102 
     103      return isdigit (*p2) ? -1 : diff; 
     104 
     105    default: 
     106      return state; 
     107  } 
     108} 
  • src/dir.c

    diff --git a/src/dir.c b/src/dir.c
    index 034467b..78bc435 100644
    a b sort_name (file_entry *a, file_entry *b) 
    9898} 
    9999 
    100100int 
     101sort_vers (file_entry *a, file_entry *b) 
     102{ 
     103    int ad = MY_ISDIR (a); 
     104    int bd = MY_ISDIR (b); 
     105     
     106    if (ad == bd || mix_all_files) { 
     107        return str_verscmp(a->fname, b->fname) * reverse; 
     108    } else { 
     109        return bd - ad; 
     110    } 
     111} 
     112 
     113int 
    101114sort_ext (file_entry *a, file_entry *b) 
    102115{ 
    103116    int r; 
  • src/dir.h

    diff --git a/src/dir.h b/src/dir.h
    index 30431aa..c7f5c66 100644
    a b int handle_path (dir_list *list, const char *path, struct stat *buf1, 
    5454/* Sorting functions */ 
    5555int unsorted   (file_entry *a, file_entry *b); 
    5656int sort_name  (file_entry *a, file_entry *b); 
     57int sort_vers  (file_entry *a, file_entry *b); 
    5758int sort_ext   (file_entry *a, file_entry *b); 
    5859int sort_time  (file_entry *a, file_entry *b); 
    5960int sort_atime (file_entry *a, file_entry *b); 
  • src/screen.c

    diff --git a/src/screen.c b/src/screen.c
    index 778c2b3..2b1c7a8 100644
    a b panel_field_t panel_fields [] = { 
    448448        (sortfn *) sort_name 
    449449    }, 
    450450    { 
     451        "version", 12, 1, J_LEFT_FIT, 
     452        /* TRANSLATORS: one single character to represent 'version' sort mode  */ 
     453        /* TRANSLATORS: no need to translate 'sort', it's just a context prefix  */ 
     454        N_("sort|v"), 
     455        N_("&Version"), TRUE, FALSE, 
     456        string_file_name, 
     457        (sortfn *) sort_vers 
     458    }, 
     459    { 
    451460        "extension", 12, 1, J_LEFT_FIT, 
    452461        /* TRANSLATORS: one single character to represent 'extension' sort mode  */ 
    453462        /* TRANSLATORS: no need to translate 'sort', it's just a context prefix  */