/*
Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
Copyright (C) 2001 Anthony Towns <aj@azure.humbug.org.au>
- Copyright (C) 2008 Free Software Foundation, Inc.
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <limits.h>
/* Match a file suffix defined by this regular expression:
- /(\.[A-Za-z][A-Za-z0-9]*)*$/
+ /(\.[A-Za-z~][A-Za-z0-9~]*)*$/
Scan the string *STR and return a pointer to the matching suffix, or
NULL if not found. Upon return, *STR points to terminating NUL. */
static const char *
if (read_alpha)
{
read_alpha = false;
- if (!c_isalpha (**str))
+ if (!c_isalpha (**str) && '~' != **str)
match = NULL;
}
else if ('.' == **str)
if (!match)
match = *str;
}
- else if (!c_isalnum (**str))
+ else if (!c_isalnum (**str) && '~' != **str)
match = NULL;
(*str)++;
}
{
int first_diff = 0;
while ((s1_pos < s1_len && !c_isdigit (s1[s1_pos]))
- || (s2_pos < s2_len && !c_isdigit (s2[s2_pos])))
- {
- int s1_c = (s1_pos == s1_len) ? 0 : order (s1[s1_pos]);
- int s2_c = (s2_pos == s2_len) ? 0 : order (s2[s2_pos]);
- if (s1_c != s2_c)
- return s1_c - s2_c;
- s1_pos++;
- s2_pos++;
- }
+ || (s2_pos < s2_len && !c_isdigit (s2[s2_pos])))
+ {
+ int s1_c = (s1_pos == s1_len) ? 0 : order (s1[s1_pos]);
+ int s2_c = (s2_pos == s2_len) ? 0 : order (s2[s2_pos]);
+ if (s1_c != s2_c)
+ return s1_c - s2_c;
+ s1_pos++;
+ s2_pos++;
+ }
while (s1[s1_pos] == '0')
- s1_pos++;
+ s1_pos++;
while (s2[s2_pos] == '0')
- s2_pos++;
+ s2_pos++;
while (c_isdigit (s1[s1_pos]) && c_isdigit (s2[s2_pos]))
- {
- if (!first_diff)
- first_diff = s1[s1_pos] - s2[s2_pos];
- s1_pos++;
- s2_pos++;
- }
+ {
+ if (!first_diff)
+ first_diff = s1[s1_pos] - s2[s2_pos];
+ s1_pos++;
+ s2_pos++;
+ }
if (c_isdigit (s1[s1_pos]))
- return 1;
+ return 1;
if (c_isdigit (s2[s2_pos]))
- return -1;
+ return -1;
if (first_diff)
- return first_diff;
+ return first_diff;
}
return 0;
}
int
filevercmp (const char *s1, const char *s2)
{
- const char *s1_pos = s1;
- const char *s2_pos = s2;
+ const char *s1_pos;
+ const char *s2_pos;
const char *s1_suffix, *s2_suffix;
size_t s1_len, s2_len;
int result;
if (simple_cmp == 0)
return 0;
+ /* special handle for "", "." and ".." */
+ if (!*s1)
+ return -1;
+ if (!*s2)
+ return 1;
+ if (0 == strcmp (".", s1))
+ return -1;
+ if (0 == strcmp (".", s2))
+ return 1;
+ if (0 == strcmp ("..", s1))
+ return -1;
+ if (0 == strcmp ("..", s2))
+ return 1;
+
+ /* special handle for other hidden files */
+ if (*s1 == '.' && *s2 != '.')
+ return -1;
+ if (*s1 != '.' && *s2 == '.')
+ return 1;
+ if (*s1 == '.' && *s2 == '.')
+ {
+ s1++;
+ s2++;
+ }
+
/* "cut" file suffixes */
+ s1_pos = s1;
+ s2_pos = s2;
s1_suffix = match_suffix (&s1_pos);
s2_suffix = match_suffix (&s2_pos);
s1_len = (s1_suffix ? s1_suffix : s1_pos) - s1;