setWindowTitleFormat: fix buffer overrun
[nedit-bw.git] / macroJoin.diff
blob30c281af753b7c9e69bb991c4a250d911be71f5a
1 From: Tony Balinski <ajbj@free.fr>
2 Subject: join() macro
4 ---
6 source/built-ins.h | 1
7 source/macro.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++
8 2 files changed, 121 insertions(+)
10 diff --quilt old/source/macro.c new/source/macro.c
11 --- old/source/macro.c
12 +++ new/source/macro.c
13 @@ -4436,6 +4436,126 @@ static int splitMS(WindowInfo *window, D
17 +** This function is intended to concatenate values in an array of strings into a
18 +** single string. It acts as the inverse-operation to split().
19 +**
20 +** string = join(array, separator[, start[, end]]))
21 +**
22 +** It will only concatenate consecutive integer-indexed elements. If start and
23 +** end are given, these are the lower and upper bounds of the index range to
24 +** use; the element array[end] will not be accessed. By default, start is 0 and
25 +** end will be one beyond the last valid integer index of a contiguous sequence
26 +** starting at start.
27 +*/
28 +static int joinMS(WindowInfo *window, DataValue *argList, int nArgs,
29 + DataValue *result, char **errMsg)
31 + char stringStorage[TYPE_INT_STR_SIZE(int)];
32 + char *sepStr;
33 + int start, end, index;
34 + size_t size, sepLen, separatorLen;
35 + char indexStr[TYPE_INT_STR_SIZE(int)], *pos;
36 + DataValue *array, element;
38 + result->tag = STRING_TAG;
39 + result->val.str.rep = PERM_ALLOC_STR("");
40 + result->val.str.len = 0;
42 + if (nArgs < 1 || nArgs > 4) {
43 + return wrongNArgsErr(errMsg);
44 + }
45 + if (argList[0].tag != ARRAY_TAG) {
46 + M_FAILURE("first argument must be an array: %s");
47 + }
48 + array = &argList[0];
49 + if (nArgs >= 2) {
50 + if (!readStringArg(argList[1], &sepStr, stringStorage, errMsg)) {
51 + M_FAILURE("second argument (separator) must be scalar: %s");
52 + }
53 + }
54 + else {
55 + sepStr = stringStorage;
56 + *sepStr = '\0';
57 + }
58 + if (nArgs >= 3) {
59 + if (!readIntArg(argList[2], &start, errMsg))
60 + M_FAILURE("third argument (start index) must be numeric: %s");
61 + }
62 + else {
63 + start = 0;
64 + }
65 + if (nArgs >= 4) {
66 + if (!readIntArg(argList[3], &end, errMsg))
67 + M_FAILURE("fourth argument (end index) must be numeric: %s");
68 + if (end <= start)
69 + return True;
70 + }
71 + else {
72 + end = start - 1;
73 + }
75 + /* right: now for the real work */
76 + /* count the space we need to build the result string */
77 + size = 0;
78 + sepLen = 0;
79 + separatorLen = strlen(sepStr);
80 + for (index = start; index != end; ++index) {
81 + if (ArrayGet(array, longAsStr(index), &element)) {
82 + size += sepLen;
83 + sepLen = separatorLen;
85 + switch (element.tag) {
86 + case INT_TAG:
87 + size += strlen(longAsStr(element.val.n));
88 + break;
89 + case STRING_TAG:
90 + size += element.val.str.len;
91 + break;
92 + default:
93 + M_FAILURE("cannot append non-scalar element to string: %s");
94 + }
95 + }
96 + else
97 + break;
98 + }
99 + if (size == 0)
100 + return True;
102 + /* allocate a string result */
103 + AllocNString(&result->val.str, size + 1);
104 + M_STR_ALLOC_ASSERT(*result);
105 + pos = result->val.str.rep;
107 + /* now fill it in */
108 + sepLen = 0;
109 + for (index = start; index != end; ++index) {
110 + if (ArrayGet(array, longAsStr(index), &element)) {
111 + memcpy(pos, sepStr, sepLen);
112 + pos += sepLen;
113 + sepLen = separatorLen;
115 + switch (element.tag) {
116 + case INT_TAG:
117 + strcpy(pos, longAsStr(element.val.n));
118 + pos += strlen(pos);
119 + break;
120 + case STRING_TAG:
121 + memcpy(pos, element.val.str.rep, element.val.str.len);
122 + pos += element.val.str.len;
123 + break;
124 + default:
125 + M_FAILURE("internal error - inaccessible code attained: %s");
128 + else
129 + break;
131 + *pos = '\0';
133 + return True;
137 ** Set the backlighting string resource for the current window. If no parameter
138 ** is passed or the value "default" is passed, it attempts to set the preference
139 ** value of the resource. If the empty string is passed, the backlighting string
140 diff --quilt old/source/built-ins.h new/source/built-ins.h
141 --- old/source/built-ins.h
142 +++ new/source/built-ins.h
143 @@ -78,6 +78,7 @@ MS(timer_add, timerAdd)
144 MS(timer_remove, timerRemove)
145 MS(escape_literal, escapeLiteral)
146 MS(full_file_name, fullFileName)
147 +MS(join, join)
149 MV(cursor, cursor)
150 MV(line, line)