1 From: Bert Wesarg <bert.wesarg@googlemail.com>
2 Subject: [PATCH] guaranty order for numeric array keys
4 Currently ther is no order guaranty for array keys in the for loops, this is
5 for numeric keys a little amberressing.
7 Use a new compare routine that takes care of numeric keys. This works also
8 for multi-dimensional keys with sub dimensional numeric keys.
10 Therefore, this do the right thing:
22 arr[10,10] = "ten,ten"
23 arr[10, 2] = "ten,two"
24 arr[10, 1] = "ten,one"
25 arr[ 2,10] = "two,ten"
26 arr[ 2, 2] = "two,two"
27 arr[ 2, 1] = "two,one"
28 arr[ 1,10] = "one,ten"
29 arr[ 1, 2] = "one,two"
30 arr[ 1, 1] = "one,one"
52 There is one semantic change with this:
56 would be overridden by this:
62 source/interpret.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++--
63 source/interpret.h | 1
64 2 files changed, 82 insertions(+), 3 deletions(-)
66 diff --quilt old/source/interpret.c new/source/interpret.c
67 --- old/source/interpret.c
68 +++ new/source/interpret.c
69 @@ -2368,10 +2368,84 @@ static int arrayEntryCopyToNode(rbTreeNo
72 ** compare two array nodes returning an integer value similar to strcmp()
74 +** take care of numeric keys and sort them right, also with multi dimensions
76 static int arrayEntryCompare(rbTreeNode *left, rbTreeNode *right)
78 - return(strcmp(((SparseArrayEntry *)left)->key, ((SparseArrayEntry *)right)->key));
79 + const char *keya = ((SparseArrayEntry *)left)->key;
80 + const char *keya_end = keya + strlen(keya);
81 + const char *keyb = ((SparseArrayEntry *)right)->key;
82 + const char *keyb_end = keyb + strlen(keyb);
83 + size_t seplen = strlen(ARRAY_DIM_SEP);
91 + const char *dima_end = strstr(keya, ARRAY_DIM_SEP);
92 + const char *dimb_end = strstr(keyb, ARRAY_DIM_SEP);
97 + dima_end = keya_end;
99 + dima_len = dima_end - keya;
102 + dimb_end = keyb_end;
104 + dimb_len = dimb_end - keyb;
107 + ** if both StringToNum end at ARRAY_DIM_SEP, we have
108 + ** successfully parsded two numbers
110 + if (StringToNumEnd(keya, dima_end, &numa)
111 + && StringToNumEnd(keyb, dimb_end, &numb)) {
112 + /* successfully parsed numbers
113 + ** even empty parts
116 + /* compare the numbers */
117 + cmp = (numa > numb) - (numa < numb);
124 + /* if the length differ, just compare the remainder */
125 + if (dima_len != dimb_len) {
126 + return strcmp(keya, keyb);
129 + /* compare this dimension */
130 + cmp = strncmp(keya, keyb, dima_len);
136 + /* eat this dimension */
141 + ** break condition:
142 + ** at least one key is fully eaten, compare the remainder
144 + if (dima_end == keya_end || dimb_end == keyb_end) {
145 + return strcmp(keya, keyb);
148 + /* both dim ends point to a ARRAY_DIM_SEP => skip */
155 @@ -2910,7 +2984,7 @@ static int execError(const char *s1, con
159 -int StringToNum(const char *string, int *number)
160 +int StringToNumEnd(const char *string, const char *end, int *number)
162 const char *c = string;
164 @@ -2926,7 +3000,7 @@ int StringToNum(const char *string, int
165 while (*c == ' ' || *c == '\t') {
169 + if (end ? end == c : *c) {
170 /* if everything went as expected, we should be at end, but we're not */
173 @@ -2939,6 +3013,10 @@ int StringToNum(const char *string, int
177 +int StringToNum(const char *string, int *number)
179 + return StringToNumEnd(string, NULL, number);
182 static const char *tagToStr(enum typeTags tag)
184 diff --quilt old/source/interpret.h new/source/interpret.h
185 --- old/source/interpret.h
186 +++ new/source/interpret.h
187 @@ -185,5 +185,6 @@ WindowInfo *MacroFocusWindow(void);
188 void SetMacroFocusWindow(WindowInfo *window);
189 /* function used for implicit conversion from string to number */
190 int StringToNum(const char *string, int *number);
191 +int StringToNumEnd(const char *string, const char *end, int *number);
193 #endif /* NEDIT_INTERPRET_H_INCLUDED */