Skip to content

Commit ab50aad

Browse files
ParadoxV5vuvova
authored andcommitted
Remove `%s` %b %M %T from my_vsnprintf`
MDEV-21978 introduces more preferrable alternatives to those extensions. This commit removes the above old and deprecated syntax. With the code for the old extension formats gone, this commit also improves the code around the new extension suffixes: * Remove code for formatting ``%`T`` * Those code are now dead, for the new suffix-based syntax does not recognize `%sQT`/`%sTQ`. * `suffix_q= TRUE` now additionally replaces `…|= ESCAPED_ARG`. * Flatten `flag= true if /%iE/` and `do_iE if flag` code together [Breaking] This commit removes obsolete features. Although my earlier work (should have) migrated every usages direct or indirect in the entire MariaDB/server, other codebases might still be using them. This final change will break *everything* in those outdated foreign lands.
1 parent 6a18255 commit ab50aad

File tree

2 files changed

+16
-133
lines changed

2 files changed

+16
-133
lines changed

strings/my_vsnprintf.c

Lines changed: 15 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#define LENGTH_ARG 1
2929
#define WIDTH_ARG 2
3030
#define PREZERO_ARG 4
31-
#define ESCAPED_ARG 8
3231

3332
typedef struct pos_arg_info ARGS_INFO;
3433
typedef struct print_info PRINT_INFO;
@@ -153,15 +152,12 @@ static const char *check_longlong(const char *fmt, uint *have_longlong)
153152
*/
154153

155154
static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
156-
char *par, size_t par_len, char quote_char,
157-
my_bool cut)
155+
char *par, size_t par_len, char quote_char)
158156
{
159-
char *last[3]= {0,0,0};
160157
uint char_len;
161158
char *start= to;
162159
char *par_end= par + par_len;
163160
size_t buff_length= (size_t) (end - to);
164-
uint index= 0;
165161

166162
if (buff_length <= par_len)
167163
goto err;
@@ -170,11 +166,6 @@ static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
170166
for ( ; par < par_end; par+= char_len)
171167
{
172168
uchar c= *(uchar *) par;
173-
if (cut)
174-
{
175-
last[index]= start;
176-
index= (index + 1) % 3;
177-
}
178169
char_len= my_ci_charlen_fix(cs, (const uchar *) par, (const uchar *) par_end);
179170
if (char_len == 1 && c == (uchar) quote_char )
180171
{
@@ -190,26 +181,6 @@ static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
190181
if (start + 1 >= end)
191182
goto err;
192183

193-
if (cut)
194-
{
195-
uint dots= 0;
196-
start= NULL;
197-
for (; dots < 3; dots++)
198-
{
199-
if (index == 0)
200-
index= 2;
201-
else
202-
index--;
203-
if (!last[index])
204-
break;
205-
start= last[index];
206-
}
207-
if (start == NULL)
208-
goto err; // there was no characters at all
209-
for (; dots; dots--)
210-
*start++= '.';
211-
212-
}
213184
*start++= quote_char;
214185
return start;
215186

@@ -225,7 +196,7 @@ static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
225196

226197
static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
227198
longlong length_arg, size_t width, char *par,
228-
uint print_type, my_bool nice_cut)
199+
my_bool escaped_arg, my_bool nice_cut)
229200
{
230201
int well_formed_error;
231202
uint dots= 0;
@@ -284,10 +255,10 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
284255
}
285256

286257
plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error);
287-
if (print_type & ESCAPED_ARG)
258+
if (escaped_arg)
288259
{
289260
const char *org_to= to;
290-
to= backtick_string(cs, to, end, par, plen + dots, '`', MY_TEST(dots));
261+
to= backtick_string(cs, to, end, par, plen + dots, '`');
291262
plen= (size_t) (to - org_to);
292263
dots= 0;
293264
}
@@ -431,11 +402,6 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
431402
/* Here we are at the beginning of positional argument, right after $ */
432403
arg_index--;
433404
print_arr[idx].flags= 0;
434-
if (*fmt == '`')
435-
{
436-
print_arr[idx].flags|= ESCAPED_ARG;
437-
fmt++;
438-
}
439405
if (*fmt == '-')
440406
fmt++;
441407
print_arr[idx].length= print_arr[idx].width= 0;
@@ -485,8 +451,6 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
485451
{
486452
switch (arg_type= args_arr[i].arg_type) {
487453
case 's':
488-
case 'b':
489-
case 'T':
490454
args_arr[i].str_arg= va_arg(ap, char *);
491455
break;
492456
case 'f':
@@ -507,7 +471,6 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
507471
else
508472
args_arr[i].longlong_arg= va_arg(ap, uint);
509473
break;
510-
case 'M':
511474
case 'c':
512475
args_arr[i].longlong_arg= va_arg(ap, int);
513476
break;
@@ -521,15 +484,13 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
521484
size_t width= 0, length= 0;
522485
switch (arg_type= print_arr[i].arg_type) {
523486
case 's':
524-
case 'T':
525-
case 'b':
526487
{
527488
char *par= args_arr[print_arr[i].arg_idx].str_arg;
528-
my_bool suffix_b= arg_type == 'b', suffix_t= arg_type == 'T';
489+
my_bool suffix_q= FALSE, suffix_b= FALSE, suffix_t= FALSE;
529490
switch (*print_arr[i].begin) // look at the start of the next chunk
530491
{
531492
case 'Q':
532-
print_arr[i].flags|= ESCAPED_ARG;
493+
suffix_q= TRUE;
533494
++print_arr[i].begin;
534495
break;
535496
case 'B':
@@ -554,7 +515,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
554515
? args_arr[print_arr[i].length].longlong_arg
555516
: (longlong) print_arr[i].length;
556517
to= process_str_arg(cs, to, end, min_field_width, width, par,
557-
print_arr[i].flags, suffix_t);
518+
suffix_q, suffix_t);
558519
}
559520
break;
560521
}
@@ -581,20 +542,14 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
581542
case 'X':
582543
case 'o':
583544
case 'p':
584-
case 'M':
585545
{
586546
/* Integer parameter */
587547
longlong larg= args_arr[print_arr[i].arg_idx].longlong_arg;
588-
my_bool suffix_e= arg_type == 'M';
589548
// look at the start of the next chunk
590549
if (arg_type == 'i' && *print_arr[i].begin == 'E')
591-
{
592-
suffix_e= TRUE;
593-
++print_arr[i].begin; // roll forward to consume the char
594-
}
595-
if (suffix_e)
596550
{
597551
const char *real_end;
552+
++print_arr[i].begin; // roll forward to consume the char
598553
width= (print_arr[i].flags & WIDTH_ARG)
599554
? (size_t)args_arr[print_arr[i].width].longlong_arg
600555
: print_arr[i].width;
@@ -607,7 +562,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
607562
*to++= '"';
608563
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
609564
to= process_str_arg(cs, to, real_end, 0, width, errmsg_buff,
610-
print_arr[i].flags, 1);
565+
FALSE, TRUE);
611566
if (real_end > to)
612567
*to++= '"';
613568
}
@@ -707,11 +662,6 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
707662
}
708663
else
709664
{
710-
if (*fmt == '`')
711-
{
712-
print_type|= ESCAPED_ARG;
713-
fmt++;
714-
}
715665
if (*fmt == '-')
716666
fmt++;
717667
if (*fmt == '*')
@@ -742,16 +692,14 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
742692

743693
switch (arg_type= *fmt) {
744694
case 's':
745-
case 'T':
746-
case 'b':
747695
{
748696
/* String parameter */
749697
reg2 char *par= va_arg(ap, char *);
750-
my_bool suffix_b= arg_type == 'b', suffix_t= arg_type == 'T';
698+
my_bool suffix_q= FALSE, suffix_b= FALSE, suffix_t= FALSE;
751699
switch (fmt[1]) // look-ahead (will at most land on the terminating `\0`)
752700
{
753701
case 'Q':
754-
print_type|= ESCAPED_ARG;
702+
suffix_q= TRUE;
755703
++fmt;
756704
break;
757705
case 'B':
@@ -768,7 +716,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
768716
to= (suffix_b)
769717
? process_bin_arg(to, end, width, par)
770718
: process_str_arg(cs, to, end, (longlong) length, width, par,
771-
print_type, suffix_t);
719+
suffix_q, suffix_t);
772720
continue;
773721
}
774722
case 'f':
@@ -792,25 +740,19 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
792740
case 'X':
793741
case 'o':
794742
case 'p':
795-
case 'M':
796743
{
797744
/* Integer parameter */
798745
longlong larg;
799-
my_bool suffix_e= arg_type == 'M';
800746
if (have_longlong)
801747
larg= va_arg(ap,longlong);
802-
else if (arg_type == 'd' || arg_type == 'i' || suffix_e)
748+
else if (arg_type == 'd' || arg_type == 'i')
803749
larg= va_arg(ap, int);
804750
else
805751
larg= va_arg(ap, uint);
806752
if (arg_type == 'i' && fmt[1] == 'E') // look-ahead
807-
{
808-
suffix_e= TRUE;
809-
++fmt;
810-
}
811-
if (suffix_e)
812753
{
813754
const char *real_end= MY_MIN(to + width, end);
755+
++fmt;
814756
to= process_int_arg(to, real_end, 0, larg, 'd', print_type);
815757
if (real_end - to >= 3)
816758
{
@@ -819,7 +761,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
819761
*to++= '"';
820762
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
821763
to= process_str_arg(cs, to, real_end, 0, width, errmsg_buff,
822-
print_type, 1);
764+
FALSE, TRUE);
823765
if (real_end > to)
824766
*to++= '"';
825767
}

unittest/mysys/my_vsnprintf-t.c

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static void test_many(const char **res, const char *fmt, ...)
6161

6262
int main(void)
6363
{
64-
plan(62);
64+
plan(45);
6565

6666
test1("Constant string",
6767
"Constant string");
@@ -70,8 +70,6 @@ int main(void)
7070

7171
test1("Format specifier s works",
7272
"Format specifier s %s", "works");
73-
test1("Format specifier b works (mysql extension)",
74-
"Format specifier b %.5b (mysql extension)", "works!!!");
7573
test1("Format specifier c !",
7674
"Format specifier c %c", '!');
7775
test1("Format specifier d 1",
@@ -106,8 +104,6 @@ int main(void)
106104

107105
test1("Precision works for strings <abcde>",
108106
"Precision works for strings <%.5s>", "abcdef!");
109-
test1("Precision works for strings <ab...>",
110-
"Precision works for strings <%.5T>", "abcdef!");
111107

112108
// MDEV-21978, tests based on those for their previous incarnations
113109

@@ -152,30 +148,6 @@ int main(void)
152148
test1("sT with small width: <.> <...>",
153149
"sT with small width: <%.1sT> <%.3sT>", "abcd", "opqrst");
154150

155-
test1("Flag '`' (backtick) works: `abcd` `op``q` (mysql extension)",
156-
"Flag '`' (backtick) works: %`s %`.4s (mysql extension)",
157-
"abcd", "op`qrst");
158-
159-
test1("Flag '`' (backtick) works: `abcd` `op``q...` (mysql extension)",
160-
"Flag '`' (backtick) works: %`T %`.7T (mysql extension)",
161-
"abcd", "op`qrstuuuuuuuuu");
162-
163-
test1("Flag '`' (backtick) works: `abcd` `.` (mysql extension)",
164-
"Flag '`' (backtick) works: %`T %`.1T (mysql extension)",
165-
"abcd", "op`qrstuuuuuuuuu");
166-
167-
test1("Flag '`' (backtick) works: `abcd` `...` (mysql extension)",
168-
"Flag '`' (backtick) works: %`T %`.3T (mysql extension)",
169-
"abcd", "op`qrstuuuuuuuuu");
170-
171-
test1("Flag '`' (backtick) works: `abcd` `op...` (mysql extension)",
172-
"Flag '`' (backtick) works: %`T %`.5T (mysql extension)",
173-
"abcd", "op`qrstuuuuuuuuu");
174-
175-
test1("Flag '`' (backtick) works: `abcd` `op``...` (mysql extension)",
176-
"Flag '`' (backtick) works: %`T %`.6T (mysql extension)",
177-
"abcd", "op`qrstuuuuuuuuu");
178-
179151
test1("Length modifiers work: 1 * -1 * 2 * 3",
180152
"Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3);
181153

@@ -202,8 +174,6 @@ int main(void)
202174
"Asterisk '*' as a precision works: <%.*s>", 6, "qwertyuiop");
203175
test1("Asterisk '*' as a precision works: <qwe...>",
204176
"Asterisk '*' as a precision works: <%.*sT>", 6, "qwertyuiop");
205-
test1("Asterisk '*' as a precision works: <qwe...>",
206-
"Asterisk '*' as a precision works: <%.*T>", 6, "qwertyuiop");
207177

208178
test1("Positional arguments for a width: < 4>",
209179
"Positional arguments for a width: <%1$*2$d>", 4, 5);
@@ -212,8 +182,6 @@ int main(void)
212182
"Positional arguments for a precision: <%1$.*2$s>", "qwertyuiop", 6);
213183
test1("Positional arguments for a precision: <qwe...>",
214184
"Positional arguments for a precision: <%1$.*2$sT>", "qwertyuiop", 6);
215-
test1("Positional arguments for a precision: <qwe...>",
216-
"Positional arguments for a precision: <%1$.*2$T>", "qwertyuiop", 6);
217185

218186
test1("Positional arguments and a width: <0000ab>",
219187
"Positional arguments and a width: <%1$06x>", 0xab);
@@ -231,32 +199,5 @@ int main(void)
231199
test1("G with a width (ignored) and precision: <12.35>",
232200
"G with a width (ignored) and precision: <%10.5g>", 12.3456789);
233201

234-
{
235-
/* Test that %M works */
236-
const char *results[]=
237-
{
238-
"Error 1 \"Operation not permitted\"", /* Linux */
239-
"Error 1 \"Not owner\"", /* Solaris */
240-
NullS
241-
};
242-
test_many(results, "Error %M", 1);
243-
}
244-
245-
test1("M with 0 error code: 0 \"Internal error/check (Not system error)\"",
246-
"M with 0 error code: %M", 0);
247-
248-
test1("M with positional: 0 \"Internal error/check (Not system error)\"",
249-
"M with positional: %1$M", 0);
250-
251-
test1("M with width: 0 \"Internal error...",
252-
"M with width: %.20M", 0);
253-
test1("M with width positional: 0 \"Internal error...",
254-
"M with width positional: %2$.*1$M", 20, 0);
255-
256-
test_w_len("M small buf: 0 \"..",
257-
19, "M small buf: %M", 0);
258-
test_w_len("M small buf positional: 0 \"..",
259-
30, "M small buf positional: %1$M", 0);
260-
261202
return exit_status();
262203
}

0 commit comments

Comments
 (0)