mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 7.4.1143
Problem: Can't sort on floating point numbers. Solution: Add the "f" flag to ":sort". (Alex Jakushev) Also add the "f" flag to sort().
This commit is contained in:
110
src/ex_cmds.c
110
src/ex_cmds.c
@@ -275,18 +275,30 @@ linelen(has_tab)
|
||||
static char_u *sortbuf1;
|
||||
static char_u *sortbuf2;
|
||||
|
||||
static int sort_ic; /* ignore case */
|
||||
static int sort_nr; /* sort on number */
|
||||
static int sort_rx; /* sort on regex instead of skipping it */
|
||||
static int sort_ic; /* ignore case */
|
||||
static int sort_nr; /* sort on number */
|
||||
static int sort_rx; /* sort on regex instead of skipping it */
|
||||
#ifdef FEAT_FLOAT
|
||||
static int sort_flt; /* sort on floating number */
|
||||
#endif
|
||||
|
||||
static int sort_abort; /* flag to indicate if sorting has been interrupted */
|
||||
static int sort_abort; /* flag to indicate if sorting has been interrupted */
|
||||
|
||||
/* Struct to store info to be sorted. */
|
||||
typedef struct
|
||||
{
|
||||
linenr_T lnum; /* line number */
|
||||
long start_col_nr; /* starting column number or number */
|
||||
long end_col_nr; /* ending column number */
|
||||
union {
|
||||
struct
|
||||
{
|
||||
long start_col_nr; /* starting column number */
|
||||
long end_col_nr; /* ending column number */
|
||||
} line;
|
||||
long value; /* value if sorting by integer */
|
||||
#ifdef FEAT_FLOAT
|
||||
float_T value_flt; /* value if sorting by float */
|
||||
#endif
|
||||
} st_u;
|
||||
} sorti_T;
|
||||
|
||||
static int
|
||||
@@ -319,19 +331,24 @@ sort_compare(s1, s2)
|
||||
/* When sorting numbers "start_col_nr" is the number, not the column
|
||||
* number. */
|
||||
if (sort_nr)
|
||||
result = l1.start_col_nr == l2.start_col_nr ? 0
|
||||
: l1.start_col_nr > l2.start_col_nr ? 1 : -1;
|
||||
result = l1.st_u.value == l2.st_u.value ? 0
|
||||
: l1.st_u.value > l2.st_u.value ? 1 : -1;
|
||||
#ifdef FEAT_FLOAT
|
||||
else if (sort_flt)
|
||||
result = l1.st_u.value_flt == l2.st_u.value_flt ? 0
|
||||
: l1.st_u.value_flt > l2.st_u.value_flt ? 1 : -1;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* We need to copy one line into "sortbuf1", because there is no
|
||||
* guarantee that the first pointer becomes invalid when obtaining the
|
||||
* second one. */
|
||||
STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.start_col_nr,
|
||||
l1.end_col_nr - l1.start_col_nr + 1);
|
||||
sortbuf1[l1.end_col_nr - l1.start_col_nr] = 0;
|
||||
STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.start_col_nr,
|
||||
l2.end_col_nr - l2.start_col_nr + 1);
|
||||
sortbuf2[l2.end_col_nr - l2.start_col_nr] = 0;
|
||||
STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
|
||||
l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1);
|
||||
sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = 0;
|
||||
STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
|
||||
l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
|
||||
sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = 0;
|
||||
|
||||
result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
|
||||
: STRCMP(sortbuf1, sortbuf2);
|
||||
@@ -382,6 +399,9 @@ ex_sort(eap)
|
||||
goto sortend;
|
||||
|
||||
sort_abort = sort_ic = sort_rx = sort_nr = 0;
|
||||
#ifdef FEAT_FLOAT
|
||||
sort_flt = 0;
|
||||
#endif
|
||||
|
||||
for (p = eap->arg; *p != NUL; ++p)
|
||||
{
|
||||
@@ -393,9 +413,16 @@ ex_sort(eap)
|
||||
sort_rx = TRUE;
|
||||
else if (*p == 'n')
|
||||
{
|
||||
sort_nr = 2;
|
||||
sort_nr = 1;
|
||||
++format_found;
|
||||
}
|
||||
#ifdef FEAT_FLOAT
|
||||
else if (*p == 'f')
|
||||
{
|
||||
sort_flt = 1;
|
||||
++format_found;
|
||||
}
|
||||
#endif
|
||||
else if (*p == 'b')
|
||||
{
|
||||
sort_what = STR2NR_BIN + STR2NR_FORCE;
|
||||
@@ -460,7 +487,8 @@ ex_sort(eap)
|
||||
goto sortend;
|
||||
}
|
||||
|
||||
/* From here on "sort_nr" is used as a flag for any number sorting. */
|
||||
/* From here on "sort_nr" is used as a flag for any integer number
|
||||
* sorting. */
|
||||
sort_nr += sort_what;
|
||||
|
||||
/*
|
||||
@@ -494,7 +522,7 @@ ex_sort(eap)
|
||||
if (regmatch.regprog != NULL)
|
||||
end_col = 0;
|
||||
|
||||
if (sort_nr)
|
||||
if (sort_nr || sort_flt)
|
||||
{
|
||||
/* Make sure vim_str2nr doesn't read any digits past the end
|
||||
* of the match, by temporarily terminating the string there */
|
||||
@@ -503,27 +531,45 @@ ex_sort(eap)
|
||||
*s2 = NUL;
|
||||
/* Sorting on number: Store the number itself. */
|
||||
p = s + start_col;
|
||||
if (sort_what & STR2NR_HEX)
|
||||
s = skiptohex(p);
|
||||
else if (sort_what & STR2NR_BIN)
|
||||
s = skiptobin(p);
|
||||
if (sort_nr)
|
||||
{
|
||||
if (sort_what & STR2NR_HEX)
|
||||
s = skiptohex(p);
|
||||
else if (sort_what & STR2NR_BIN)
|
||||
s = skiptobin(p);
|
||||
else
|
||||
s = skiptodigit(p);
|
||||
if (s > p && s[-1] == '-')
|
||||
--s; /* include preceding negative sign */
|
||||
if (*s == NUL)
|
||||
/* empty line should sort before any number */
|
||||
nrs[lnum - eap->line1].st_u.value = -MAXLNUM;
|
||||
else
|
||||
vim_str2nr(s, NULL, NULL, sort_what,
|
||||
&nrs[lnum - eap->line1].st_u.value, NULL, 0);
|
||||
}
|
||||
#ifdef FEAT_FLOAT
|
||||
else
|
||||
s = skiptodigit(p);
|
||||
if (s > p && s[-1] == '-')
|
||||
--s; /* include preceding negative sign */
|
||||
if (*s == NUL)
|
||||
/* empty line should sort before any number */
|
||||
nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
|
||||
else
|
||||
vim_str2nr(s, NULL, NULL, sort_what,
|
||||
&nrs[lnum - eap->line1].start_col_nr, NULL, 0);
|
||||
{
|
||||
s = skipwhite(p);
|
||||
if (*s == '+')
|
||||
s = skipwhite(s + 1);
|
||||
|
||||
if (*s == NUL)
|
||||
/* empty line should sort before any number */
|
||||
nrs[lnum - eap->line1].st_u.value_flt = -DBL_MAX;
|
||||
else
|
||||
nrs[lnum - eap->line1].st_u.value_flt =
|
||||
strtod((char *)s, NULL);
|
||||
}
|
||||
#endif
|
||||
*s2 = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store the column to sort at. */
|
||||
nrs[lnum - eap->line1].start_col_nr = start_col;
|
||||
nrs[lnum - eap->line1].end_col_nr = end_col;
|
||||
nrs[lnum - eap->line1].st_u.line.start_col_nr = start_col;
|
||||
nrs[lnum - eap->line1].st_u.line.end_col_nr = end_col;
|
||||
}
|
||||
|
||||
nrs[lnum - eap->line1].lnum = lnum;
|
||||
|
Reference in New Issue
Block a user