Skip to content

Commit 73bd6f5

Browse files
committed
COMMON: mid and replace performance
1 parent 4bed426 commit 73bd6f5

File tree

6 files changed

+152
-51
lines changed

6 files changed

+152
-51
lines changed

src/common/blib_func.c

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,9 @@ void date_fmt(char *fmt, char *buf, long d, long m, long y) {
397397
// full name
398398
strcat(buf, date_mN_table[m - 1]);
399399
}
400-
} else
400+
} else {
401401
strcat(buf, "***");
402+
}
402403
}
403404

404405
mc = 0;
@@ -1300,7 +1301,9 @@ void cmd_str0(long funcCode, var_t *r) {
13001301
// str <- FUNC (...)
13011302
//
13021303
void cmd_strN(long funcCode, var_t *r) {
1303-
var_t arg1;
1304+
var_t arg1, arg2;
1305+
var_t *var_p1 = NULL;
1306+
var_t *var_p2 = NULL;
13041307
var_int_t i, count, lsrc, len, start, pc;
13051308
char tmp[2], *tmp_p;
13061309
char *s1 = NULL, *s2 = NULL, *s3 = NULL;
@@ -1334,8 +1337,9 @@ void cmd_strN(long funcCode, var_t *r) {
13341337
r->v.p.ptr[strlen(r->v.p.ptr) - 1] = '\0';
13351338
r->type = V_STR;
13361339
r->v.p.size = strlen(r->v.p.ptr) + 1;
1337-
} else
1340+
} else {
13381341
v_zerostr(r);
1342+
}
13391343
}
13401344
break;
13411345
case kwSTRING:
@@ -1497,8 +1501,9 @@ void cmd_strN(long funcCode, var_t *r) {
14971501
strcpy(r->v.p.ptr, s1);
14981502
r->v.p.size = l;
14991503
*p = lc;
1500-
} else
1504+
} else {
15011505
v_zerostr(r);
1506+
}
15021507
}
15031508
break;
15041509

@@ -1612,13 +1617,15 @@ void cmd_strN(long funcCode, var_t *r) {
16121617
//
16131618
// str <- REPLACE$ ( source, pos, str [, len] )
16141619
//
1615-
count = -1;
1616-
par_massget("SISi", &s1, &start, &s2, &count);
1617-
if (!prog_error) {
1618-
int ls1, ls2;
1620+
v_init(&arg2);
16191621

1620-
ls1 = strlen(s1);
1621-
ls2 = strlen(s2);
1622+
var_p1 = par_next_str(&arg1, 1);
1623+
start = par_next_int(1);
1624+
var_p2 = par_next_str(&arg2, 0);
1625+
count = par_getval(-1);
1626+
if (!prog_error) {
1627+
int ls1 = v_strlen(var_p1);
1628+
int ls2 = v_strlen(var_p2);
16221629

16231630
start--;
16241631
if (start < 0 || start > ls1) {
@@ -1630,50 +1637,51 @@ void cmd_strN(long funcCode, var_t *r) {
16301637

16311638
// copy the left-part
16321639
if (start > 0) {
1633-
memcpy(r->v.p.ptr, s1, start);
1640+
memcpy(r->v.p.ptr, var_p1->v.p.ptr, start);
16341641
r->v.p.ptr[start] = '\0';
1635-
} else
1642+
} else {
16361643
*r->v.p.ptr = '\0';
1637-
1644+
}
16381645
// insert the string
1639-
strcat(r->v.p.ptr, s2);
1646+
strcat(r->v.p.ptr, var_p2->v.p.ptr);
16401647

16411648
// add the right-part
16421649
if (count == -1) {
16431650
count = ls2;
16441651
}
16451652
if (start + count < ls1) {
1646-
strcat(r->v.p.ptr, (s1 + start + count));
1653+
strcat(r->v.p.ptr, (var_p1->v.p.ptr + start + count));
16471654
}
16481655
r->v.p.ptr[ls1 + ls2] = '\0';
16491656
r->v.p.size = ls1 + ls2 + 1;
16501657
}
1651-
1658+
v_free(&arg2);
16521659
break;
16531660

16541661
case kwMID:
16551662
//
16561663
// str <- MID$ ( str, start [, len] )
16571664
//
1658-
len = -1;
1659-
par_massget("SIi", &s1, &start, &len);
1665+
var_p1 = par_next_str(&arg1, 1);
1666+
start = par_next_int(0);
1667+
len = par_getval(-1);
16601668
if (!prog_error) {
1661-
lsrc = strlen(s1);
1662-
if (start <= 0 || start > (int) strlen(s1)) {
1669+
lsrc = v_strlen(var_p1);
1670+
if (start <= 0 || start > lsrc) {
16631671
err_stridx(start);
16641672
} else {
16651673
start--;
16661674
if (len < 0 || len + start >= lsrc) {
16671675
len = lsrc - start;
16681676
}
16691677
r->v.p.ptr = malloc(len + 1);
1670-
memcpy(r->v.p.ptr, s1 + start, len);
1678+
memcpy(r->v.p.ptr, var_p1->v.p.ptr + start, len);
16711679
r->v.p.ptr[len] = '\0';
16721680
r->v.p.size = len + 1;
16731681
}
16741682
}
1675-
16761683
break;
1684+
16771685
default:
16781686
rt_raise("Unsupported built-in function call %ld, please report this bug (7)", funcCode);
16791687
}
@@ -1873,7 +1881,6 @@ void cmd_intN(long funcCode, var_t *r) {
18731881
code_skipnext();
18741882
var_p = tvar[code_getaddr()];
18751883
if (var_p->type == V_ARRAY) {
1876-
18771884
l = 1;
18781885
if (code_peek() == kwTYPE_SEP) {
18791886
par_getcomma();
@@ -2471,10 +2478,11 @@ void cmd_genfunc(long funcCode, var_t *r) {
24712478

24722479
r->type = V_NUM;
24732480

2474-
if (funcCode == kwPTDISTLN)
2481+
if (funcCode == kwPTDISTLN) {
24752482
r->v.n = geo_distfromline(B.x, B.y, C.x, C.y, A.x, A.y);
2476-
else
2483+
} else {
24772484
r->v.n = geo_distfromseg(B.x, B.y, C.x, C.y, A.x, A.y);
2485+
}
24782486
}
24792487
break;
24802488
//
@@ -2554,12 +2562,13 @@ void cmd_genfunc(long funcCode, var_t *r) {
25542562
if (first) {
25552563
dar_first(funcCode, r, elem_p);
25562564
first = 0;
2557-
} else
2565+
} else {
25582566
dar_next(funcCode, r, elem_p);
2559-
2567+
}
25602568
tcount++;
2561-
} else
2569+
} else {
25622570
return;
2571+
}
25632572
}
25642573
break;
25652574
}
@@ -2573,12 +2582,13 @@ void cmd_genfunc(long funcCode, var_t *r) {
25732582
if (first) {
25742583
dar_first(funcCode, r, &arg);
25752584
first = 0;
2576-
} else
2585+
} else {
25772586
dar_next(funcCode, r, &arg);
2578-
2587+
}
25792588
tcount++;
2580-
} else
2589+
} else {
25812590
return;
2591+
}
25822592
v_free(&arg);
25832593
}
25842594

src/common/pproc.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,24 @@ var_num_t par_getnum(void);
196196

197197
#define par_getreal() par_getnum()
198198

199+
/**
200+
* @ingroup par
201+
*
202+
* get next parameter as integer
203+
*
204+
* @return the integer
205+
*/
206+
var_int_t par_next_int(int sep);
207+
208+
/**
209+
* @ingroup par
210+
*
211+
* get next parameter as string
212+
*
213+
* @return the string var
214+
*/
215+
var_t *par_next_str(var_t *arg, int sep);
216+
199217
/**
200218
* @ingroup par
201219
*

src/common/proc.c

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -471,19 +471,67 @@ var_num_t par_getnum() {
471471
return f;
472472
}
473473

474-
var_int_t par_getval(var_int_t def) {
474+
var_int_t par_next_int(int sep) {
475475
var_int_t result;
476-
byte code = code_peek();
477-
if (code == kwTYPE_VAR) {
476+
if (prog_error) {
477+
result = 0;
478+
} else {
478479
result = par_getint();
479-
} else if (code == kwTYPE_INT) {
480-
code_skipnext();
481-
result = code_getint();
482-
} else if (code == kwTYPE_NUM) {
483-
code_skipnext();
484-
result = code_getreal();
480+
}
481+
if (!prog_error && (sep || code_peek() == kwTYPE_SEP)) {
482+
par_getcomma();
483+
}
484+
return result;
485+
}
486+
487+
var_t *par_next_str(var_t *arg, int sep) {
488+
var_t *result;
489+
if (prog_error) {
490+
result = NULL;
491+
} else if (code_isvar()) {
492+
result = code_getvarptr();
485493
} else {
494+
eval(arg);
495+
result = arg;
496+
}
497+
if (result && result->type != V_STR) {
498+
err_syntax(-1, "%S");
499+
}
500+
if (!prog_error && (sep || code_peek() == kwTYPE_SEP)) {
501+
par_getcomma();
502+
}
503+
return result;
504+
}
505+
506+
var_int_t par_getval(var_int_t def) {
507+
var_int_t result;
508+
if (prog_error) {
486509
result = def;
510+
} else {
511+
var_t var;
512+
switch (code_peek()) {
513+
case kwTYPE_INT:
514+
code_skipnext();
515+
result = code_getint();
516+
break;
517+
case kwTYPE_NUM:
518+
code_skipnext();
519+
result = code_getreal();
520+
break;
521+
case kwTYPE_LINE:
522+
case kwTYPE_EOC:
523+
case kwTYPE_SEP:
524+
case kwTYPE_LEVEL_END:
525+
result = def;
526+
break;
527+
default:
528+
eval(&var);
529+
if (!prog_error) {
530+
result = v_getint(&var);
531+
}
532+
v_free(&var);
533+
break;
534+
}
487535
}
488536
return result;
489537
}

src/common/scan.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,20 @@ int comp_is_external_func(const char *name) {
244244
* error messages
245245
*/
246246
void sc_raise(const char *fmt, ...) {
247-
char *buff;
248-
va_list ap;
247+
if (!prog_error) {
248+
char *buff;
249+
va_list ap;
249250

250-
va_start(ap, fmt);
251-
comp_error = 1;
251+
va_start(ap, fmt);
252+
comp_error = 1;
252253

253-
buff = malloc(SB_SOURCELINE_SIZE + 1);
254-
vsnprintf(buff, SB_SOURCELINE_SIZE, fmt, ap);
255-
va_end(ap);
254+
buff = malloc(SB_SOURCELINE_SIZE + 1);
255+
vsnprintf(buff, SB_SOURCELINE_SIZE, fmt, ap);
256+
va_end(ap);
256257

257-
sc_raise2(comp_bc_sec, comp_line, buff); // sberr.h
258-
free(buff);
258+
sc_raise2(comp_bc_sec, comp_line, buff); // sberr.h
259+
free(buff);
260+
}
259261
}
260262

261263
/*

src/common/var.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var_t *v_new() {
3232
int v_isempty(var_t *var) {
3333
switch (var->type) {
3434
case V_STR:
35-
return (strlen(var->v.p.ptr) == 0);
35+
return (v_strlen(var) == 0);
3636
case V_INT:
3737
return (var->v.i == 0);
3838
case V_MAP:
@@ -50,6 +50,19 @@ int v_isempty(var_t *var) {
5050
return 1;
5151
}
5252

53+
int v_strlen(var_t *v) {
54+
int result;
55+
if (v->type == V_STR) {
56+
result = v->v.p.size;
57+
if (result && v->v.p.ptr[result - 1] == '\0') {
58+
result--;
59+
}
60+
} else {
61+
result = 0;
62+
}
63+
return result;
64+
}
65+
5366
/*
5467
* returns the length of the variable
5568
*/
@@ -58,7 +71,7 @@ int v_length(var_t *var) {
5871

5972
switch (var->type) {
6073
case V_STR:
61-
return strlen(var->v.p.ptr);
74+
return v_strlen(var);
6275
case V_MAP:
6376
return map_length(var);
6477
case V_PTR:

src/common/var.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,16 @@ void v_input2var(const char *str, var_t *var);
651651
*/
652652
char *v_getstr(var_t *v);
653653

654+
/**
655+
* @ingroup var
656+
*
657+
* returns the length of the var string
658+
*
659+
* @param v is the variable
660+
* @return the string length
661+
*/
662+
int v_strlen(var_t *v);
663+
654664
/**
655665
* @ingroup var
656666
*

0 commit comments

Comments
 (0)