mathematical 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/mathematical/extconf.rb +6 -1
- data/ext/mathematical/lasem/src/lsmdomcharacterdata.c +17 -0
- data/ext/mathematical/lasem/src/lsmdomdocument.c +17 -0
- data/ext/mathematical/lasem/src/lsmmathmlfencedelement.c +8 -6
- data/ext/mathematical/lasem/src/lsmmathmloperatorelement.c +8 -6
- data/ext/mathematical/lasem/src/lsmmathmlview.c +12 -7
- data/ext/mathematical/lasem/src/lsmmathmlview.h +2 -0
- data/ext/mathematical/lasem/src/lsmsvgsymbolelement.c +74 -0
- data/ext/mathematical/lasem/src/lsmsvgsymbolelement.h +3 -0
- data/ext/mathematical/lasem/src/lsmsvguseelement.c +10 -9
- data/ext/mathematical/lasem/src/lsmsvgview.c +12 -0
- data/ext/mathematical/lasem/src/lsmsvgview.h +1 -0
- data/ext/mathematical/lasem/tests/lsmtest.c +1 -1
- data/ext/mathematical/lasem/tests/suite.c +18 -1
- data/ext/mathematical/mtex2MML/src/lex.yy.c +4454 -4090
- data/ext/mathematical/mtex2MML/src/mtex2MML.h +1 -0
- data/ext/mathematical/mtex2MML/src/parse_extras.c +176 -41
- data/ext/mathematical/mtex2MML/src/parse_extras.h +30 -8
- data/ext/mathematical/mtex2MML/src/string_extras.c +5 -26
- data/ext/mathematical/mtex2MML/src/string_extras.h +1 -6
- data/ext/mathematical/mtex2MML/src/y.tab.c +6600 -5492
- data/ext/mathematical/mtex2MML/src/y.tab.h +572 -525
- data/lib/mathematical/version.rb +1 -1
- data/mathematical.gemspec +1 -1
- data/test/mathematical/basic_test.rb +1 -1
- data/test/mathematical/corrections_test.rb +1 -1
- data/test/mathematical/fixtures_test.rb +1 -1
- data/test/mathematical/maliciousness_test.rb +17 -17
- data/test/mathematical/mathjax_test.rb +2 -3
- data/test/mathematical/mathml_test.rb +1 -1
- data/test/mathematical/multiples_test.rb +1 -1
- data/test/mathematical/performance_test.rb +6 -8
- data/test/mathematical/png_test.rb +1 -1
- data/test/test_helper.rb +2 -2
- metadata +6 -6
@@ -7,29 +7,46 @@
|
|
7
7
|
|
8
8
|
void env_replacements(UT_array **environment_data_stack, encaseType * encase, const char *environment)
|
9
9
|
{
|
10
|
+
const char *from = "\\begin", *until = "\\end",
|
11
|
+
*begin_svg = "begin{svg}";
|
12
|
+
|
13
|
+
// if not an environment, don't bother going on
|
14
|
+
if ((strstr(environment, from) == NULL && strstr(environment, until) == NULL) || strstr(environment, begin_svg)) {
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
|
10
18
|
UT_array *array_stack;
|
11
19
|
UT_array *row_spacing_stack;
|
12
20
|
UT_array *rowlines_stack;
|
13
21
|
|
14
|
-
char *tok = NULL, *at_top = NULL
|
22
|
+
char *tok = NULL, *at_top = NULL,
|
23
|
+
*temp = "", **last_stack_item,
|
24
|
+
*a, *em_str;
|
25
|
+
|
26
|
+
envType environmentType = OTHER;
|
27
|
+
if (strstr(environment, "\\end{smallmatrix}") != NULL) {
|
28
|
+
environmentType = ENV_SMALLMATRIX;
|
29
|
+
} else if (strstr(environment, "\\end{gathered}") != NULL) {
|
30
|
+
environmentType = ENV_GATHERED;
|
31
|
+
} else if (strstr(environment, "\\end{eqnarray") != NULL) {
|
32
|
+
environmentType = ENV_EQNARRAY;
|
33
|
+
} else if (strstr(environment, "\\end{multline") != NULL) {
|
34
|
+
environmentType = ENV_MULTLINE;
|
35
|
+
} else if (strstr(environment, "\\end{alignat") != NULL) {
|
36
|
+
environmentType = ENV_ALIGNAT;
|
37
|
+
}else if (strstr(environment, "\\end{aligned}") != NULL) {
|
38
|
+
environmentType = ENV_ALIGNED;
|
39
|
+
}
|
15
40
|
|
16
|
-
char *
|
17
|
-
char *a, *em_str;
|
18
|
-
const char *from = "\\begin", *until = "\\end", *hline = "\\hline", *hdashline = "\\hdashline",
|
41
|
+
const char *hline = "\\hline", *hdashline = "\\hdashline",
|
19
42
|
*line_separator = "\\\\",
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
*is_smallmatrix = NULL, *is_gathered = NULL;
|
43
|
+
*cr_separator = "\\cr",
|
44
|
+
*newline_separator = "\\newline",
|
45
|
+
*em_pattern_begin = "\\[", *em_pattern_end = "]";
|
24
46
|
|
25
47
|
int rowlines_stack_len = 0, em_offset = 0;
|
26
48
|
|
27
|
-
|
28
|
-
if ( ((strstr(environment, from) == NULL && strstr(environment, until) == NULL)) || strstr(environment, "begin{svg}")) {
|
29
|
-
return;
|
30
|
-
}
|
31
|
-
|
32
|
-
char *dupe_environment = dupe_string(environment);
|
49
|
+
char *dupe_environment = strdup(environment);
|
33
50
|
char *line = strtok(dupe_environment, "\n");
|
34
51
|
|
35
52
|
// set up the array stack
|
@@ -49,8 +66,8 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
49
66
|
|
50
67
|
// we've reached the top, but there looks like there might be some data
|
51
68
|
if (at_top != NULL && strstr(*last_stack_item, line_separator) == NULL && \
|
52
|
-
|
53
|
-
|
69
|
+
strstr(*last_stack_item, cr_separator) == NULL && \
|
70
|
+
strstr(*last_stack_item, newline_separator) == NULL) {
|
54
71
|
if (strstr(*last_stack_item, hline) != NULL || strstr(*last_stack_item, hdashline) != NULL) {
|
55
72
|
*encase = TOPENCLOSE;
|
56
73
|
}
|
@@ -78,24 +95,28 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
78
95
|
|
79
96
|
// if there's a line break...
|
80
97
|
if (strstr(*last_stack_item, line_separator) != NULL || \
|
81
|
-
|
82
|
-
|
98
|
+
strstr(*last_stack_item, cr_separator) != NULL || \
|
99
|
+
strstr(*last_stack_item, newline_separator) != NULL) {
|
83
100
|
// when an emphasis match, add it...
|
84
101
|
if ( (tok = strstr(*last_stack_item, em_pattern_begin)) != NULL) {
|
85
102
|
temp = tok + 2; // skip the first part ("\[")
|
86
103
|
if ( (tok = strstr(temp, em_pattern_end)) != NULL) {
|
87
104
|
em_offset = (int)(tok - temp);
|
88
|
-
char *s =
|
105
|
+
char *s = strndup(temp, em_offset);
|
89
106
|
utarray_push_back(row_spacing_stack, &s);
|
90
107
|
free(s);
|
91
108
|
}
|
92
109
|
}
|
93
110
|
// otherwise, use the default
|
94
111
|
else {
|
95
|
-
if (
|
112
|
+
if (environmentType == ENV_SMALLMATRIX) {
|
96
113
|
em_str = "0.2em";
|
97
|
-
} else if (
|
114
|
+
} else if (environmentType == ENV_GATHERED) {
|
98
115
|
em_str = "1.0ex";
|
116
|
+
} else if (environmentType == ENV_EQNARRAY || environmentType == ENV_ALIGNAT || environmentType == ENV_ALIGNED) {
|
117
|
+
em_str = "3pt";
|
118
|
+
} else if (environmentType == ENV_MULTLINE) {
|
119
|
+
em_str = "0.5em";
|
99
120
|
} else {
|
100
121
|
em_str = "0.5ex";
|
101
122
|
}
|
@@ -111,13 +132,9 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
111
132
|
break;
|
112
133
|
}
|
113
134
|
}
|
114
|
-
if (at_top != NULL) {
|
115
|
-
is_smallmatrix = strstr(at_top, "\\begin{smallmatrix}");
|
116
|
-
is_gathered = strstr(at_top, "\\begin{gathered}");
|
117
|
-
}
|
118
135
|
|
119
136
|
if ((rowlines_stack_len != 0 || utarray_len(row_spacing_stack))) {
|
120
|
-
perform_replacement(environment_data_stack, rowlines_stack,
|
137
|
+
perform_replacement(environment_data_stack, rowlines_stack, environmentType, row_spacing_stack);
|
121
138
|
}
|
122
139
|
|
123
140
|
utarray_clear(row_spacing_stack);
|
@@ -134,16 +151,18 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
134
151
|
free(dupe_environment);
|
135
152
|
}
|
136
153
|
|
137
|
-
void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack,
|
154
|
+
void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, envType environmentType, UT_array *row_spacing_stack)
|
138
155
|
{
|
139
156
|
char *a, *attr_rowlines, *attr_rowspacing;
|
140
|
-
envdata_t
|
157
|
+
envdata_t env_data;
|
141
158
|
|
142
159
|
// we cut the last char because we can always skip the first row
|
143
160
|
utarray_pop_back(rowlines_stack);
|
144
161
|
|
162
|
+
int line_count = utarray_len(rowlines_stack);
|
163
|
+
|
145
164
|
// empty rowlines should be reset
|
146
|
-
if (
|
165
|
+
if (line_count == 0) {
|
147
166
|
a = "none";
|
148
167
|
utarray_push_back(rowlines_stack, &a);
|
149
168
|
}
|
@@ -168,9 +187,9 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
|
|
168
187
|
utstring_new(s);
|
169
188
|
char **p=NULL;
|
170
189
|
while ( (p=(char**)utarray_prev(row_spacing_stack,p))) {
|
171
|
-
if (
|
190
|
+
if (environmentType == ENV_SMALLMATRIX && strcmp(*p, "0.5ex") == 0) {
|
172
191
|
utstring_printf(s, "%s ", "0.2em");
|
173
|
-
} else if (
|
192
|
+
} else if (environmentType == ENV_GATHERED && strcmp(*p, "0.5ex") == 0) {
|
174
193
|
utstring_printf(s, "%s ", "1.0ex");
|
175
194
|
} else {
|
176
195
|
utstring_printf(s, "%s ", *p);
|
@@ -181,26 +200,29 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
|
|
181
200
|
if (strlen(attr_rowspacing) > 0) {
|
182
201
|
remove_last_char(attr_rowspacing); // remove the final space
|
183
202
|
} else {
|
184
|
-
if (
|
203
|
+
if (environmentType == ENV_SMALLMATRIX) {
|
185
204
|
attr_rowspacing = "0.2em";
|
186
|
-
} else if (
|
205
|
+
} else if (environmentType == ENV_GATHERED) {
|
187
206
|
attr_rowspacing = "1.0ex";
|
188
207
|
} else {
|
189
208
|
attr_rowspacing = "0.5ex";
|
190
209
|
}
|
191
210
|
}
|
192
211
|
|
193
|
-
|
194
|
-
|
212
|
+
// store pertinent metadata
|
213
|
+
env_data.rowspacing = attr_rowspacing;
|
214
|
+
env_data.rowlines = attr_rowlines;
|
215
|
+
env_data.environmentType = environmentType;
|
216
|
+
env_data.line_count = line_count;
|
195
217
|
|
196
|
-
utarray_push_back(*environment_data_stack, &
|
218
|
+
utarray_push_back(*environment_data_stack, &env_data);
|
197
219
|
utstring_free(l);
|
198
220
|
utstring_free(s);
|
199
221
|
}
|
200
222
|
|
201
223
|
const char *vertical_pipe_extract(const char *string)
|
202
224
|
{
|
203
|
-
char *dupe =
|
225
|
+
char *dupe = strdup(string);
|
204
226
|
UT_string *columnlines, *border;
|
205
227
|
char *previous_column = "", *attr_columnlines, *attr_border;
|
206
228
|
int i = 0;
|
@@ -253,9 +275,10 @@ const char *vertical_pipe_extract(const char *string)
|
|
253
275
|
utstring_printf(columnlines, "%s", "none");
|
254
276
|
}
|
255
277
|
|
256
|
-
attr_columnlines = utstring_body(columnlines);
|
278
|
+
attr_columnlines = strdup(utstring_body(columnlines));
|
257
279
|
free(dupe);
|
258
280
|
utstring_free(border);
|
281
|
+
utstring_free(columnlines);
|
259
282
|
|
260
283
|
return attr_columnlines;
|
261
284
|
}
|
@@ -265,7 +288,7 @@ const char *remove_excess_pipe_chars(const char *string)
|
|
265
288
|
UT_string *columnalign;
|
266
289
|
utstring_new(columnalign);
|
267
290
|
|
268
|
-
char *dupe =
|
291
|
+
char *dupe = strdup(string);
|
269
292
|
char *token = strtok(dupe, " ");
|
270
293
|
char *attr_columnalign;
|
271
294
|
|
@@ -276,8 +299,9 @@ const char *remove_excess_pipe_chars(const char *string)
|
|
276
299
|
token = strtok(NULL, " ");
|
277
300
|
}
|
278
301
|
|
279
|
-
attr_columnalign = utstring_body(columnalign);
|
302
|
+
attr_columnalign = strdup(utstring_body(columnalign));
|
280
303
|
free(dupe);
|
304
|
+
utstring_free(columnalign);
|
281
305
|
|
282
306
|
if (strlen(attr_columnalign) > 0) {
|
283
307
|
remove_last_char(attr_columnalign); // remove the final space
|
@@ -307,8 +331,119 @@ const char *combine_row_data(UT_array **environment_data_stack)
|
|
307
331
|
// combine the row spacing and row lines data
|
308
332
|
utstring_printf(row_attr_data, "%s%s\" %s\"", "rowspacing=\"", row_spacing_data, row_lines_data);
|
309
333
|
|
310
|
-
row_attr =
|
334
|
+
row_attr = strdup(utstring_body(row_attr_data));
|
311
335
|
utarray_erase(*environment_data_stack, 0, 1);
|
312
336
|
|
337
|
+
utstring_free(row_attr_data);
|
338
|
+
|
313
339
|
return row_attr;
|
314
340
|
}
|
341
|
+
|
342
|
+
const float extract_number_from_pxstring(const char * str)
|
343
|
+
{
|
344
|
+
float dbl;
|
345
|
+
int match = 0;
|
346
|
+
|
347
|
+
match = sscanf (str, "%*[^-0123456789]%f", &dbl);
|
348
|
+
if (match == 1) {
|
349
|
+
return dbl;
|
350
|
+
}
|
351
|
+
|
352
|
+
// must not be a float.
|
353
|
+
sscanf (str, "%d", &match);
|
354
|
+
return (float) match;
|
355
|
+
}
|
356
|
+
|
357
|
+
const char *extract_string_from_pxstring(const char * str)
|
358
|
+
{
|
359
|
+
char *pixel;
|
360
|
+
float dbl;
|
361
|
+
pixel = malloc(3*sizeof(char));
|
362
|
+
sscanf (str, "%f%s", &dbl, pixel);
|
363
|
+
return pixel;
|
364
|
+
}
|
365
|
+
|
366
|
+
const char * dbl2em(const char *str)
|
367
|
+
{
|
368
|
+
UT_string *em;
|
369
|
+
utstring_new(em);
|
370
|
+
|
371
|
+
float dbl = extract_number_from_pxstring(str);
|
372
|
+
dbl *= 0.056;
|
373
|
+
|
374
|
+
utstring_printf(em, "%.3fem", dbl);
|
375
|
+
char * em_str = strdup(utstring_body(em));
|
376
|
+
|
377
|
+
utstring_free(em);
|
378
|
+
|
379
|
+
return em_str;
|
380
|
+
}
|
381
|
+
|
382
|
+
const char * double_pixel(float f, char *pixel)
|
383
|
+
{
|
384
|
+
UT_string *em;
|
385
|
+
utstring_new(em);
|
386
|
+
|
387
|
+
float dbl = f * 2;
|
388
|
+
utstring_printf(em, "%.3f%s", dbl, pixel);
|
389
|
+
char * em_str = strdup(utstring_body(em));
|
390
|
+
|
391
|
+
utstring_free(em);
|
392
|
+
|
393
|
+
return em_str;
|
394
|
+
}
|
395
|
+
|
396
|
+
const char * implement_skew(char *base_str, char *em_skew, char *pattern)
|
397
|
+
{
|
398
|
+
UT_string *skew_mathml;
|
399
|
+
utstring_new(skew_mathml);
|
400
|
+
|
401
|
+
utstring_printf(skew_mathml, "%s%s%s", "<mrow><mrow><mrow><mover><mrow>", base_str, "<mspace width=\"");
|
402
|
+
utstring_printf(skew_mathml, "%s%s%s", em_skew, "\" /></mrow>", "<mo stretchy=\"false\">");
|
403
|
+
utstring_printf(skew_mathml, "%s%s%s", pattern, "</mo></mover></mrow><mspace width=\"-", em_skew);
|
404
|
+
utstring_printf(skew_mathml, "%s", "\" /></mrow><mrow></mrow></mrow>");
|
405
|
+
|
406
|
+
char * skew_mathml_str = strdup(utstring_body(skew_mathml));
|
407
|
+
|
408
|
+
utstring_free(skew_mathml);
|
409
|
+
|
410
|
+
return skew_mathml_str;
|
411
|
+
}
|
412
|
+
|
413
|
+
const char * root_pos_to_em(const char * str)
|
414
|
+
{
|
415
|
+
UT_string *em;
|
416
|
+
utstring_new(em);
|
417
|
+
|
418
|
+
float dbl = extract_number_from_pxstring(str);
|
419
|
+
dbl /= 15;
|
420
|
+
|
421
|
+
utstring_printf(em, "%.3fem", dbl);
|
422
|
+
char * em_str = strdup(utstring_body(em));
|
423
|
+
|
424
|
+
utstring_free(em);
|
425
|
+
|
426
|
+
return em_str;
|
427
|
+
}
|
428
|
+
|
429
|
+
envType current_env_type(UT_array **environment_data_stack)
|
430
|
+
{
|
431
|
+
if (utarray_len(*environment_data_stack) == 0) {
|
432
|
+
return -1;
|
433
|
+
}
|
434
|
+
|
435
|
+
envdata_t *row_data_elem = (envdata_t*) utarray_front(*environment_data_stack);
|
436
|
+
|
437
|
+
return row_data_elem->environmentType;
|
438
|
+
}
|
439
|
+
|
440
|
+
int current_env_line_count(UT_array **environment_data_stack)
|
441
|
+
{
|
442
|
+
if (utarray_len(*environment_data_stack) == 0) {
|
443
|
+
return -1;
|
444
|
+
}
|
445
|
+
|
446
|
+
envdata_t *row_data_elem = (envdata_t*) utarray_front(*environment_data_stack);
|
447
|
+
|
448
|
+
return row_data_elem->line_count;
|
449
|
+
}
|
@@ -9,18 +9,15 @@ extern "C" {
|
|
9
9
|
#endif
|
10
10
|
|
11
11
|
typedef enum {NONE = 0, TOPENCLOSE} encaseType;
|
12
|
+
typedef enum {OTHER = 0, ENV_ALIGNAT, ENV_ALIGNED, ENV_GATHERED, ENV_EQNARRAY, ENV_MULTLINE, ENV_SMALLMATRIX} envType;
|
12
13
|
|
13
14
|
typedef struct {
|
14
15
|
char *rowspacing;
|
15
16
|
char *rowlines;
|
16
|
-
|
17
|
+
envType environmentType;
|
18
|
+
int line_count;
|
17
19
|
} envdata_t;
|
18
20
|
|
19
|
-
typedef struct {
|
20
|
-
char *attribute;
|
21
|
-
int offset_pos;
|
22
|
-
} symbolData;
|
23
|
-
|
24
21
|
struct css_colors {
|
25
22
|
char name[22]; /* key */
|
26
23
|
char color[10];
|
@@ -58,11 +55,11 @@ struct css_colors {
|
|
58
55
|
//
|
59
56
|
// The env_replacements function will push every line onto a stack. When an \end
|
60
57
|
// is detected, it starts popping off the stack until it reaches the corresponding
|
61
|
-
// \begin. It then modifies that stack with attribute strings, an arrangement of
|
58
|
+
// \begin. It then modifies that stack with attribute strings, an arrangement of
|
62
59
|
// the symbols encountered while popping lines off.
|
63
60
|
extern void env_replacements(UT_array **environment_data_stack, encaseType *encase, const char *environment);
|
64
61
|
|
65
|
-
extern void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack,
|
62
|
+
extern void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, envType environmentType, UT_array *row_spacing_stack);
|
66
63
|
|
67
64
|
// determines the column border arrangement from the array environment definition (c|cc|c...)
|
68
65
|
extern const char *vertical_pipe_extract(const char *string);
|
@@ -74,6 +71,31 @@ extern const char *remove_excess_pipe_chars(const char *string);
|
|
74
71
|
// return the proper rowlines information
|
75
72
|
extern const char *combine_row_data(UT_array **environment_data_stack);
|
76
73
|
|
74
|
+
// given a pixel string, retrieve the numeric portion from it
|
75
|
+
extern const float extract_number_from_pxstring(const char * str);
|
76
|
+
|
77
|
+
// given a pixel string, retrieve the pixel type portion from it
|
78
|
+
extern const char *extract_string_from_pxstring(const char * str);
|
79
|
+
|
80
|
+
// given a number, return it as an em
|
81
|
+
extern const char * dbl2em(const char *str);
|
82
|
+
|
83
|
+
// given a number, return it as a root position
|
84
|
+
// taken straight from MathJax
|
85
|
+
extern const char * root_pos_to_em(const char * str);
|
86
|
+
|
87
|
+
// given a number and a pixel string, return the doubled number
|
88
|
+
extern const char * double_pixel(float f, char *pixel);
|
89
|
+
|
90
|
+
// construct a skew sequence
|
91
|
+
extern const char * implement_skew(char *base_str, char *em_skew, char *pattern);
|
92
|
+
|
93
|
+
// get the environment type of the top-most item
|
94
|
+
extern envType current_env_type(UT_array **environment_data_stack);
|
95
|
+
|
96
|
+
// get the line count of the top-most item
|
97
|
+
extern int current_env_line_count(UT_array **environment_data_stack);
|
98
|
+
|
77
99
|
#ifdef __cplusplus
|
78
100
|
}
|
79
101
|
#endif
|
@@ -15,24 +15,6 @@ void remove_first_char(char* str)
|
|
15
15
|
memmove(str, str + 1, len);
|
16
16
|
}
|
17
17
|
|
18
|
-
char *dupe_string(const char * str)
|
19
|
-
{
|
20
|
-
int len = strlen(str) + 1;
|
21
|
-
char *buf = malloc(len);
|
22
|
-
if (buf) { memcpy(buf, str, len); }
|
23
|
-
return buf;
|
24
|
-
}
|
25
|
-
|
26
|
-
char *dupe_string_n(const char *s, size_t n)
|
27
|
-
{
|
28
|
-
char* buf = malloc(n + 1);
|
29
|
-
if (buf) {
|
30
|
-
strncpy(buf, s, n);
|
31
|
-
buf[n] = '\0';
|
32
|
-
}
|
33
|
-
return buf;
|
34
|
-
}
|
35
|
-
|
36
18
|
char * str_replace (char *string, const char *substr, const char *replacement)
|
37
19
|
{
|
38
20
|
char *tok = NULL;
|
@@ -41,22 +23,19 @@ char * str_replace (char *string, const char *substr, const char *replacement)
|
|
41
23
|
|
42
24
|
/* if either substr or replacement is NULL, duplicate string a let caller handle it */
|
43
25
|
|
44
|
-
if ( substr == NULL || replacement == NULL )
|
45
|
-
|
46
|
-
return dupe_string (string);
|
26
|
+
if ( substr == NULL || replacement == NULL ) {
|
27
|
+
return strdup(string);
|
47
28
|
}
|
48
29
|
|
49
|
-
newstr =
|
30
|
+
newstr = strdup(string);
|
50
31
|
|
51
|
-
while ( ( tok = strstr( newstr, substr ) ) )
|
52
|
-
{
|
32
|
+
while ( ( tok = strstr( newstr, substr ) ) ) {
|
53
33
|
|
54
34
|
oldstr = newstr;
|
55
35
|
newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) + 1 );
|
56
36
|
|
57
37
|
/* If failed to alloc mem, free old string and return NULL */
|
58
|
-
if ( newstr == NULL )
|
59
|
-
{
|
38
|
+
if ( newstr == NULL ) {
|
60
39
|
free (oldstr);
|
61
40
|
return NULL;
|
62
41
|
}
|