Mercurial > vim
diff src/ex_cmds.c @ 7689:20dc2763a3b9 v7.4.1143
commit https://github.com/vim/vim/commit/f7edf40448a09e04eec3bd05e043f7fea93b07c9
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 19 23:36:15 2016 +0100
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().
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 19 Jan 2016 23:45:05 +0100 |
parents | 1fded31d9e04 |
children | fd4175b669e2 |
line wrap: on
line diff
--- a/src/ex_cmds.c +++ b/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_abort; /* flag to indicate if sorting has been interrupted */ +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 */ /* 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;