more ProOpen and PostOpen hook points
[nedit-bw.git] / guaranty-order-for-numeric-keys.patch
blob5e3b9b15be1f10e395a3e1106042b1a69d22dfa0
1 From: Bert Wesarg <bert.wesarg@googlemail.com>
2 Subject: [PATCH v2] 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:
12 arr[10] = "ten"
13 arr[ 2] = "two"
14 arr[ 1] = "one"
16 for (k in arr) {
17 t_print(k "\n")
20 And this too:
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"
32 for (k in arr) {
33 t_print(k "\n")
36 And this too:
38 arr["c",10] = "c,ten"
39 arr["c", 2] = "c,two"
40 arr["c", 1] = "c,one"
41 arr["b",10] = "b,ten"
42 arr["b", 2] = "b,two"
43 arr["b", 1] = "b,one"
44 arr["a",10] = "a,ten"
45 arr["a", 2] = "a,two"
46 arr["a", 1] = "a,one"
48 for (k in arr) {
49 t_print(k "\n")
52 There is one semantic change with this:
54 arr[1] = "one"
56 would be overridden by this:
58 arr["01"] = "zeroone"
60 ---
62 v2:
63 * replace strtol with a modifified StringToNum
65 source/interpret.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++--
66 source/interpret.h | 1
67 2 files changed, 80 insertions(+), 3 deletions(-)
69 diff --quilt old/source/interpret.c new/source/interpret.c
70 --- old/source/interpret.c
71 +++ new/source/interpret.c
72 @@ -2368,10 +2368,82 @@ static int arrayEntryCopyToNode(rbTreeNo
75 ** compare two array nodes returning an integer value similar to strcmp()
76 +**
77 +** take care of numeric keys and sort them right, also with multi dimensions
79 static int arrayEntryCompare(rbTreeNode *left, rbTreeNode *right)
81 - return(strcmp(((SparseArrayEntry *)left)->key, ((SparseArrayEntry *)right)->key));
82 + const char *keya = ((SparseArrayEntry *)left)->key;
83 + const char *keya_end = keya + strlen(keya);
84 + const char *keyb = ((SparseArrayEntry *)right)->key;
85 + const char *keyb_end = keyb + strlen(keyb);
86 + size_t seplen = strlen(ARRAY_DIM_SEP);
87 + int cmp;
89 + while (1) {
90 + int numa;
91 + int numb;
92 + long dima_len;
93 + long dimb_len;
94 + const char *dima_end = strstr(keya, ARRAY_DIM_SEP);
95 + const char *dimb_end = strstr(keyb, ARRAY_DIM_SEP);
97 + if (!dima_end) {
98 + dima_end = keya_end;
99 + }
100 + dima_len = dima_end - keya;
102 + if (!dimb_end) {
103 + dimb_end = keyb_end;
105 + dimb_len = dimb_end - keyb;
107 + /*
108 + ** if both StringToNum end at ARRAY_DIM_SEP, we have
109 + ** successfully parsded two numbers
110 + */
111 + if (StringToNumEnd(keya, dima_end, &numa)
112 + && StringToNumEnd(keyb, dimb_end, &numb)) {
113 + /* successfully parsed numbers
114 + ** even empty parts
115 + */
117 + /* compare the numbers */
118 + cmp = (numa > numb) - (numa < numb);
119 + if (cmp != 0) {
120 + return cmp;
123 + } else {
125 + /* if the length differ, just compare the remainder */
126 + if (dima_len != dimb_len) {
127 + return strcmp(keya, keyb);
130 + /* compare this dimension */
131 + cmp = strncmp(keya, keyb, dima_len);
132 + if (cmp != 0) {
133 + return cmp;
137 + /* eat this dimension */
138 + keya = dima_end;
139 + keyb = dimb_end;
141 + /*
142 + ** break condition:
143 + ** at least one key is fully eaten, compare the remainder
144 + */
145 + if (dima_end == keya_end || dimb_end == keyb_end) {
146 + return strcmp(keya, keyb);
149 + /* both dim ends point to a ARRAY_DIM_SEP => skip */
150 + keya += seplen;
151 + keyb += seplen;
156 @@ -2910,7 +2982,7 @@ static int execError(const char *s1, con
157 return STAT_ERROR;
160 -int StringToNum(const char *string, int *number)
161 +int StringToNumEnd(const char *string, const char *end, int *number)
163 const char *c = string;
165 @@ -2926,7 +2998,7 @@ int StringToNum(const char *string, int
166 while (*c == ' ' || *c == '\t') {
167 ++c;
169 - if (*c) {
170 + if (end ? end != c : *c) {
171 /* if everything went as expected, we should be at end, but we're not */
172 return False;
174 @@ -2939,6 +3011,10 @@ int StringToNum(const char *string, int
175 return True;
178 +int StringToNum(const char *string, int *number)
180 + return StringToNumEnd(string, NULL, number);
183 static const char *tagToStr(enum typeTags tag)
185 diff --quilt old/source/interpret.h new/source/interpret.h
186 --- old/source/interpret.h
187 +++ new/source/interpret.h
188 @@ -185,5 +185,6 @@ WindowInfo *MacroFocusWindow(void);
189 void SetMacroFocusWindow(WindowInfo *window);
190 /* function used for implicit conversion from string to number */
191 int StringToNum(const char *string, int *number);
192 +int StringToNumEnd(const char *string, const char *end, int *number);
194 #endif /* NEDIT_INTERPRET_H_INCLUDED */