14
14
* Plus, test framework cannot pass -fno-builtin-... per-file, only globally
15
15
*/
16
16
17
- /* TODO remove when libc supports pointers to flash */
18
- #undef PSTR
19
- #define PSTR (X ) X
20
-
21
- #if 1
22
-
23
17
#define xDST_SRC_N (T , NAME )\
24
- T* __attribute__((noinline)) x ## NAME (T* dst, const T* src, size_t n)\
18
+ static T* __attribute__((used, noinline)) x ## NAME (T* dst, const T* src, size_t n)\
25
19
{\
26
20
return NAME (dst, src, n);\
27
21
}
28
22
29
23
xDST_SRC_N (void , memcpy )
24
+ xDST_SRC_N (void , memmove )
30
25
xDST_SRC_N (char , strncat )
31
26
xDST_SRC_N (char , strncpy )
32
27
33
28
#define xDST_SRC (T , NAME )\
34
- T* __attribute__((noinline)) x ## NAME (T* dst, const T* src)\
29
+ static T* __attribute__((used, noinline)) x ## NAME (T* dst, const T* src)\
35
30
{\
36
31
return NAME (dst, src);\
37
32
}
@@ -40,31 +35,38 @@ xDST_SRC (char, strcat)
40
35
xDST_SRC (char , strcpy )
41
36
42
37
#define xS1_S2_N (RET , T , NAME )\
43
- RET __attribute__((noinline)) x ## NAME (const T *s1, const T *s2, size_t n)\
38
+ static RET __attribute__((used, noinline)) x ## NAME (const T *s1, const T *s2, size_t n)\
44
39
{\
45
40
return NAME (s1, s2, n);\
46
41
}
47
42
48
43
xS1_S2_N (int , void , memcmp )
49
44
xS1_S2_N (int , char , strncmp )
50
45
51
- int __attribute__((noinline )) xstrcmp (const char * s1 , const char * s2 )
46
+ static int __attribute__((used , noinline )) xstrcmp (const char * s1 , const char * s2 )
52
47
{
53
48
return strcmp (s1 , s2 );
54
49
}
55
50
56
- void * __attribute__ ( (noinline )) xmemchr (const void * s , int c , size_t n )
51
+ static void * __attribute__ ( (used , noinline )) xmemchr (const void * s , int c , size_t n )
57
52
{
58
53
return memchr (s , c , n );
59
54
}
60
55
61
- size_t __attribute__((noinline )) xstrlen (const char * s )
56
+ static size_t __attribute__((used , noinline )) xstrlen (const char * s )
62
57
{
63
58
return strlen (s );
64
59
}
65
60
61
+ #if 0
62
+
63
+ /* TODO remove when libc supports pointers to flash */
64
+ #undef PSTR
65
+ #define PSTR (X ) X
66
+
66
67
#define memcmp (s1 ,s2 ,n ) xmemcmp(s1,PSTR(s2),n)
67
68
#define memcpy (dest ,src ,n ) xmemcpy(dest,PSTR(src),n)
69
+ #define memmove (dest ,src ,n ) xmemmove(dest,PSTR(src),n)
68
70
#define memchr (s ,c ,n ) xmemchr(PSTR(s),c,n)
69
71
#define strcat (dst ,src ) xstrcat(dst,PSTR(src))
70
72
#define strncat (dst ,src ,ssize ) xstrncat(dst,PSTR(src),ssize)
@@ -78,20 +80,23 @@ size_t __attribute__((noinline)) xstrlen (const char* s)
78
80
79
81
/* in case wrapped calls are not required */
80
82
81
- #define memcmp (s1 ,s2 ,n ) memcmp(s1,PSTR(s2),n)
82
- #define memcpy (dest ,src ,n ) memcpy(dest,PSTR(src),n)
83
- #define memchr (s ,c ,n ) memchr(PSTR(s),c,n)
84
- #define strcat (dst ,src ) strcat(dst,PSTR(src))
85
- #define strncat (dst ,src ,ssize ) strncat(dst,PSTR(src),ssize)
86
- #define strcpy (dst ,src ) strcpy(dst,PSTR(src))
87
- #define strncpy (dst ,src ,dsize ) strncpy(dst,PSTR(src),dsize)
88
- #define strlen (s ) strlen(PSTR(s))
89
- #define strcmp (s1 ,s2 ) strcmp(s1,PSTR(s2))
90
- #define strncmp (s1 ,s2 ,n ) strncmp(s1,PSTR(s2),n)
83
+ #define memcmp (s1 ,s2 ,n ) memcmp_P(s1,PSTR(s2),n)
84
+ #define memcpy (dest ,src ,n ) memcpy_P(dest,PSTR(src),n)
85
+ #define memmove (dest ,src ,n ) memmove_P(dest,PSTR(src),n)
86
+ #define memchr (s ,c ,n ) memchr_P(PSTR(s),c,n)
87
+ #define strcat (dst ,src ) strcat_P(dst,PSTR(src))
88
+ #define strncat (dst ,src ,ssize ) strncat_P(dst,PSTR(src),ssize)
89
+ #define strcpy (dst ,src ) strcpy_P(dst,PSTR(src))
90
+ #define strncpy (dst ,src ,dsize ) strncpy_P(dst,PSTR(src),dsize)
91
+ #define strlen (s ) strlen_P(PSTR(s))
92
+ #define strcmp (s1 ,s2 ) strcmp_P(s1,PSTR(s2))
93
+ #define strncmp (s1 ,s2 ,n ) strncmp_P(s1,PSTR(s2),n)
91
94
92
95
#endif
93
96
94
- const char * it = "<UNSET>" ; /* Routine name for message routines. */
97
+ static const char Unset [] PROGMEM = "<UNSET>" ;
98
+
99
+ const char * it = Unset ; /* Routine name for message routines. */
95
100
static int errors = 0 ;
96
101
97
102
/* Complain if condition is not true. */
@@ -104,7 +109,7 @@ static void checkit(int ok, int l)
104
109
105
110
if (!ok )
106
111
{
107
- printf ("string.c:%d %s\n" , l , it );
112
+ printf (PSTR ( "string.c:%d %s\n" ) , l , it );
108
113
++ errors ;
109
114
}
110
115
}
@@ -119,9 +124,9 @@ static void funcqual(const char *a, const char *b, int l)
119
124
// line(l);
120
125
if (a == NULL && b == NULL )
121
126
return ;
122
- if (xstrcmp (a , b ))
127
+ if (strcmp_P (a , b ))
123
128
{
124
- printf ("string.c:%d (%s)\n" , l , it );
129
+ printf (PSTR ( "string.c:%d (%s)\n" ) , l , it );
125
130
}
126
131
}
127
132
@@ -131,7 +136,7 @@ static char two[50];
131
136
void libm_test_string ()
132
137
{
133
138
/* Test strcmp first because we use it to test other things. */
134
- it = "strcmp" ;
139
+ it = PSTR ( "strcmp" ) ;
135
140
check (strcmp ("" , "" ) == 0 ); /* Trivial case. */
136
141
check (strcmp ("a" , "a" ) == 0 ); /* Identity. */
137
142
check (strcmp ("abc" , "abc" ) == 0 ); /* Multicharacter. */
@@ -143,8 +148,8 @@ void libm_test_string()
143
148
check (strcmp ("a\103" , "a\003" ) > 0 );
144
149
145
150
/* Test strcpy next because we need it to set up other tests. */
146
- it = "strcpy" ;
147
- check (strcpy_P (one , "abcd" ) == one ); /* Returned value. */
151
+ it = PSTR ( "strcpy" ) ;
152
+ check (strcpy (one , "abcd" ) == one ); /* Returned value. */
148
153
equal (one , "abcd" ); /* Basic test. */
149
154
150
155
(void )strcpy (one , "x" );
@@ -160,9 +165,9 @@ void libm_test_string()
160
165
equal (one , "" ); /* Boundary condition. */
161
166
162
167
/* strcat. */
163
- it = "strcat" ;
168
+ it = PSTR ( "strcat" ) ;
164
169
(void )strcpy (one , "ijk" );
165
- check (strcat_P (one , "lmn" ) == one ); /* Returned value. */
170
+ check (strcat (one , "lmn" ) == one ); /* Returned value. */
166
171
equal (one , "ijklmn" ); /* Basic test. */
167
172
168
173
(void )strcpy (one , "x" );
@@ -188,11 +193,11 @@ void libm_test_string()
188
193
189
194
/* strncat - first test it as strcat, with big counts,
190
195
then test the count mechanism. */
191
- it = "strncat" ;
196
+ it = PSTR ( "strncat" ) ;
192
197
(void )strcpy (one , "ijk" );
193
198
#pragma GCC diagnostic push
194
199
#pragma GCC diagnostic ignored "-Wstringop-overflow="
195
- check (strncat_P (one , "lmn" , 99 ) == one ); /* Returned value. */
200
+ check (strncat (one , "lmn" , 99 ) == one ); /* Returned value. */
196
201
#pragma GCC diagnostic pop
197
202
equal (one , "ijklmn" ); /* Basic test. */
198
203
@@ -248,7 +253,7 @@ void libm_test_string()
248
253
(void )strncat (one , "gh" , 2 );
249
254
#pragma GCC diagnostic pop
250
255
equal (one , "abcdgh" ); /* Count _AND length equal. */
251
- it = "strncmp" ;
256
+ it = PSTR ( "strncmp" ) ;
252
257
/* strncmp - first test as strcmp with big counts";*/
253
258
check (strncmp ("" , "" , 99 ) == 0 ); /* Trivial case. */
254
259
check (strncmp ("a" , "a" , 99 ) == 0 ); /* Identity. */
@@ -263,8 +268,8 @@ void libm_test_string()
263
268
check (strncmp ("abc" , "def" , 0 ) == 0 ); /* Zero count. */
264
269
265
270
/* strncpy - testing is a bit different because of odd semantics. */
266
- it = "strncpy" ;
267
- check (strncpy_P (one , "abc" , 4 ) == one ); /* Returned value. */
271
+ it = PSTR ( "strncpy" ) ;
272
+ check (strncpy (one , "abc" , 4 ) == one ); /* Returned value. */
268
273
equal (one , "abc" ); /* Did the copy go right? */
269
274
270
275
(void )strcpy (one , "abcdefgh" );
@@ -310,13 +315,13 @@ void libm_test_string()
310
315
equal (one , "hi there" ); /* Stomped on source? */
311
316
312
317
/* strlen. */
313
- it = "strlen" ;
318
+ it = PSTR ( "strlen" ) ;
314
319
check (strlen ("" ) == 0 ); /* Empty. */
315
320
check (strlen ("a" ) == 1 ); /* Single char. */
316
321
check (strlen ("abcd" ) == 4 ); /* Multiple chars. */
317
322
318
323
/* strchr. */
319
- it = "strchr" ;
324
+ it = PSTR ( "strchr" ) ;
320
325
check (strchr ("abcd" , 'z' ) == NULL ); /* Not found. */
321
326
(void )strcpy (one , "abcd" );
322
327
check (strchr (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -330,7 +335,7 @@ void libm_test_string()
330
335
check (strchr (one , '\0' ) == one ); /* NUL in empty string. */
331
336
332
337
/* index - just like strchr. */
333
- it = "index" ;
338
+ it = PSTR ( "index" ) ;
334
339
check (index ("abcd" , 'z' ) == NULL ); /* Not found. */
335
340
(void )strcpy (one , "abcd" );
336
341
check (index (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -344,7 +349,7 @@ void libm_test_string()
344
349
check (index (one , '\0' ) == one ); /* NUL in empty string. */
345
350
346
351
/* strrchr. */
347
- it = "strrchr" ;
352
+ it = PSTR ( "strrchr" ) ;
348
353
check (strrchr ("abcd" , 'z' ) == NULL ); /* Not found. */
349
354
(void )strcpy (one , "abcd" );
350
355
check (strrchr (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -358,7 +363,7 @@ void libm_test_string()
358
363
check (strrchr (one , '\0' ) == one ); /* NUL in empty string. */
359
364
360
365
/* rindex - just like strrchr. */
361
- it = "rindex" ;
366
+ it = PSTR ( "rindex" ) ;
362
367
check (rindex ("abcd" , 'z' ) == NULL ); /* Not found. */
363
368
(void )strcpy (one , "abcd" );
364
369
check (rindex (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -372,7 +377,7 @@ void libm_test_string()
372
377
check (rindex (one , '\0' ) == one ); /* NUL in empty string. */
373
378
374
379
/* strpbrk - somewhat like strchr. */
375
- it = "strpbrk" ;
380
+ it = PSTR ( "strpbrk" ) ;
376
381
check (strpbrk ("abcd" , "z" ) == NULL ); /* Not found. */
377
382
(void )strcpy (one , "abcd" );
378
383
check (strpbrk (one , "c" ) == one + 2 ); /* Basic test. */
@@ -389,7 +394,7 @@ void libm_test_string()
389
394
check (strpbrk (one , "" ) == NULL ); /* Both strings empty. */
390
395
391
396
/* strstr - somewhat like strchr. */
392
- it = "strstr" ;
397
+ it = PSTR ( "strstr" ) ;
393
398
check (strstr ("z" , "abcd" ) == NULL ); /* Not found. */
394
399
check (strstr ("abx" , "abcd" ) == NULL ); /* Dead end. */
395
400
(void )strcpy (one , "abcd" );
@@ -412,23 +417,23 @@ void libm_test_string()
412
417
check (strstr (one , "bbca" ) == one + 1 ); /* With overlap. */
413
418
414
419
/* strspn. */
415
- it = "strspn" ;
420
+ it = PSTR ( "strspn" ) ;
416
421
check (strspn ("abcba" , "abc" ) == 5 ); /* Whole string. */
417
422
check (strspn ("abcba" , "ab" ) == 2 ); /* Partial. */
418
423
check (strspn ("abc" , "qx" ) == 0 ); /* None. */
419
424
check (strspn ("" , "ab" ) == 0 ); /* Null string. */
420
425
check (strspn ("abc" , "" ) == 0 ); /* Null search list. */
421
426
422
427
/* strcspn. */
423
- it = "strcspn" ;
428
+ it = PSTR ( "strcspn" ) ;
424
429
check (strcspn ("abcba" , "qx" ) == 5 ); /* Whole string. */
425
430
check (strcspn ("abcba" , "cx" ) == 2 ); /* Partial. */
426
431
check (strcspn ("abc" , "abc" ) == 0 ); /* None. */
427
432
check (strcspn ("" , "ab" ) == 0 ); /* Null string. */
428
433
check (strcspn ("abc" , "" ) == 3 ); /* Null search list. */
429
434
430
435
/* strtok - the hard one. */
431
- it = "strtok" ;
436
+ it = PSTR ( "strtok" ) ;
432
437
(void )strcpy (one , "first, second, third" );
433
438
equal (strtok (one , ", " ), "first" ); /* Basic test. */
434
439
equal (one , "first" );
@@ -475,7 +480,7 @@ void libm_test_string()
475
480
equal (one + 4 , "c" );
476
481
477
482
/* memcmp. */
478
- it = "memcmp" ;
483
+ it = PSTR ( "memcmp" ) ;
479
484
check (memcmp ("a" , "a" , 1 ) == 0 ); /* Identity. */
480
485
check (memcmp ("abc" , "abc" , 3 ) == 0 ); /* Multicharacter. */
481
486
check (memcmp ("abcd" , "abce" , 4 ) < 0 ); /* Honestly unequal. */
@@ -490,7 +495,7 @@ void libm_test_string()
490
495
check (xmemcmp (one , two , 1 ) > 0 );
491
496
492
497
/* memchr. */
493
- it = "memchr" ;
498
+ it = PSTR ( "memchr" ) ;
494
499
check (memchr ("abcd" , 'z' , 4 ) == NULL ); /* Not found. */
495
500
(void )strcpy (one , "abcd" );
496
501
check (xmemchr (one , 'c' , 4 ) == one + 2 ); /* Basic test. */
@@ -505,8 +510,8 @@ void libm_test_string()
505
510
check (xmemchr (one , 0203 , 3 ) == one + 1 ); /* Unsignedness. */
506
511
507
512
/* memcpy - need not work for overlap. */
508
- it = "memcpy" ;
509
- check (memcpy_P (one , "abc" , 4 ) == one ); /* Returned value. */
513
+ it = PSTR ( "memcpy" ) ;
514
+ check (memcpy (one , "abc" , 4 ) == one ); /* Returned value. */
510
515
equal (one , "abc" ); /* Did the copy go right? */
511
516
512
517
(void )strcpy (one , "abcdefgh" );
@@ -522,10 +527,10 @@ void libm_test_string()
522
527
(void )xmemcpy (two , one , 9 );
523
528
equal (two , "hi there" ); /* Just paranoia. */
524
529
equal (one , "hi there" ); /* Stomped on source? */
525
- #if 0
530
+ #if 1
526
531
/* memmove - must work on overlap. */
527
- it = "memmove" ;
528
- check (memmove (one , "abc" , 4 ) == one ); /* Returned value. */
532
+ it = PSTR ( "memmove" ) ;
533
+ check (xmemmove (one , "abc" , 4 ) == one ); /* Returned value. */
529
534
equal (one , "abc" ); /* Did the copy go right? */
530
535
531
536
(void ) strcpy (one , "abcdefgh" );
@@ -538,28 +543,28 @@ void libm_test_string()
538
543
539
544
(void ) strcpy (one , "hi there" );
540
545
(void ) strcpy (two , "foo" );
541
- (void ) memmove (two , one , 9 );
546
+ (void ) xmemmove (two , one , 9 );
542
547
equal (two , "hi there" ); /* Just paranoia. */
543
548
equal (one , "hi there" ); /* Stomped on source? */
544
549
545
550
(void ) strcpy (one , "abcdefgh" );
546
- (void ) memmove (one + 1 , one , 9 );
551
+ (void ) xmemmove (one + 1 , one , 9 );
547
552
equal (one , "aabcdefgh" ); /* Overlap, right-to-left. */
548
553
549
554
(void ) strcpy (one , "abcdefgh" );
550
- (void ) memmove (one + 1 , one + 2 , 7 );
555
+ (void ) xmemmove (one + 1 , one + 2 , 7 );
551
556
equal (one , "acdefgh" ); /* Overlap, left-to-right. */
552
557
553
558
(void ) strcpy (one , "abcdefgh" );
554
- (void ) memmove (one , one , 9 );
559
+ (void ) xmemmove (one , one , 9 );
555
560
equal (one , "abcdefgh" ); /* 100% overlap. */
556
561
#endif
557
562
#if 0
558
563
/* memccpy - first test like memcpy, then the search part
559
564
The SVID, the only place where memccpy is mentioned, says
560
565
overlap might fail, so we don't try it. Besides, it's hard
561
566
to see the rationale for a non-left-to-right memccpy. */
562
- it = "memccpy" ;
567
+ it = PSTR ( "memccpy" ) ;
563
568
check (memccpy (one , "abc" , 'q' , 4 ) == NULL ); /* Returned value. */
564
569
equal (one , "abc" ); /* Did the copy go right? */
565
570
@@ -594,7 +599,7 @@ void libm_test_string()
594
599
equal (two , "xbcdlebee" );
595
600
#endif
596
601
/* memset. */
597
- it = "memset" ;
602
+ it = PSTR ( "memset" ) ;
598
603
(void )strcpy (one , "abcdefgh" );
599
604
check (memset (one + 1 , 'x' , 3 ) == one + 1 ); /* Return value. */
600
605
equal (one , "axxxefgh" ); /* Basic test. */
@@ -614,7 +619,7 @@ void libm_test_string()
614
619
615
620
/* bcopy - much like memcpy.
616
621
Berklix manual is silent about overlap, so don't test it. */
617
- it = "bcopy" ;
622
+ it = PSTR ( "bcopy" ) ;
618
623
(void )bcopy ("abc" , one , 4 );
619
624
equal (one , "abc" ); /* Simple copy. */
620
625
@@ -633,7 +638,7 @@ void libm_test_string()
633
638
equal (one , "hi there" ); /* Stomped on source? */
634
639
635
640
/* bzero. */
636
- it = "bzero" ;
641
+ it = PSTR ( "bzero" ) ;
637
642
(void )strcpy (one , "abcdef" );
638
643
bzero (one + 2 , 2 );
639
644
equal (one , "ab" ); /* Basic test. */
@@ -645,7 +650,7 @@ void libm_test_string()
645
650
equal (one , "abcdef" ); /* Zero-length copy. */
646
651
647
652
/* bcmp - somewhat like memcmp. */
648
- it = "bcmp" ;
653
+ it = PSTR ( "bcmp" ) ;
649
654
check (bcmp ("a" , "a" , 1 ) == 0 ); /* Identity. */
650
655
check (bcmp ("abc" , "abc" , 3 ) == 0 ); /* Multicharacter. */
651
656
check (bcmp ("abcd" , "abce" , 4 ) != 0 ); /* Honestly unequal. */
0 commit comments