1414 * Plus, test framework cannot pass -fno-builtin-... per-file, only globally
1515 */
1616
17- /* TODO remove when libc supports pointers to flash */
18- #undef PSTR
19- #define PSTR (X ) X
20-
21- #if 1
22-
2317#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)\
2519{\
2620 return NAME (dst, src, n);\
2721}
2822
2923xDST_SRC_N (void , memcpy )
24+ xDST_SRC_N (void , memmove )
3025xDST_SRC_N (char , strncat )
3126xDST_SRC_N (char , strncpy )
3227
3328#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)\
3530{\
3631 return NAME (dst, src);\
3732}
@@ -40,31 +35,38 @@ xDST_SRC (char, strcat)
4035xDST_SRC (char , strcpy )
4136
4237#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)\
4439{\
4540 return NAME (s1, s2, n);\
4641}
4742
4843xS1_S2_N (int , void , memcmp )
4944xS1_S2_N (int , char , strncmp )
5045
51- int __attribute__((noinline )) xstrcmp (const char * s1 , const char * s2 )
46+ static int __attribute__((used , noinline )) xstrcmp (const char * s1 , const char * s2 )
5247{
5348 return strcmp (s1 , s2 );
5449}
5550
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 )
5752{
5853 return memchr (s , c , n );
5954}
6055
61- size_t __attribute__((noinline )) xstrlen (const char * s )
56+ static size_t __attribute__((used , noinline )) xstrlen (const char * s )
6257{
6358 return strlen (s );
6459}
6560
61+ #if 0
62+
63+ /* TODO remove when libc supports pointers to flash */
64+ #undef PSTR
65+ #define PSTR (X ) X
66+
6667#define memcmp (s1 ,s2 ,n ) xmemcmp(s1,PSTR(s2),n)
6768#define memcpy (dest ,src ,n ) xmemcpy(dest,PSTR(src),n)
69+ #define memmove (dest ,src ,n ) xmemmove(dest,PSTR(src),n)
6870#define memchr (s ,c ,n ) xmemchr(PSTR(s),c,n)
6971#define strcat (dst ,src ) xstrcat(dst,PSTR(src))
7072#define strncat (dst ,src ,ssize ) xstrncat(dst,PSTR(src),ssize)
@@ -78,20 +80,23 @@ size_t __attribute__((noinline)) xstrlen (const char* s)
7880
7981/* in case wrapped calls are not required */
8082
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)
9194
9295#endif
9396
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. */
95100static int errors = 0 ;
96101
97102/* Complain if condition is not true. */
@@ -104,7 +109,7 @@ static void checkit(int ok, int l)
104109
105110 if (!ok )
106111 {
107- printf ("string.c:%d %s\n" , l , it );
112+ printf (PSTR ( "string.c:%d %s\n" ) , l , it );
108113 ++ errors ;
109114 }
110115}
@@ -119,9 +124,9 @@ static void funcqual(const char *a, const char *b, int l)
119124 // line(l);
120125 if (a == NULL && b == NULL )
121126 return ;
122- if (xstrcmp (a , b ))
127+ if (strcmp_P (a , b ))
123128 {
124- printf ("string.c:%d (%s)\n" , l , it );
129+ printf (PSTR ( "string.c:%d (%s)\n" ) , l , it );
125130 }
126131}
127132
@@ -131,7 +136,7 @@ static char two[50];
131136void libm_test_string ()
132137{
133138 /* Test strcmp first because we use it to test other things. */
134- it = "strcmp" ;
139+ it = PSTR ( "strcmp" ) ;
135140 check (strcmp ("" , "" ) == 0 ); /* Trivial case. */
136141 check (strcmp ("a" , "a" ) == 0 ); /* Identity. */
137142 check (strcmp ("abc" , "abc" ) == 0 ); /* Multicharacter. */
@@ -143,8 +148,8 @@ void libm_test_string()
143148 check (strcmp ("a\103" , "a\003" ) > 0 );
144149
145150 /* 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. */
148153 equal (one , "abcd" ); /* Basic test. */
149154
150155 (void )strcpy (one , "x" );
@@ -160,9 +165,9 @@ void libm_test_string()
160165 equal (one , "" ); /* Boundary condition. */
161166
162167 /* strcat. */
163- it = "strcat" ;
168+ it = PSTR ( "strcat" ) ;
164169 (void )strcpy (one , "ijk" );
165- check (strcat_P (one , "lmn" ) == one ); /* Returned value. */
170+ check (strcat (one , "lmn" ) == one ); /* Returned value. */
166171 equal (one , "ijklmn" ); /* Basic test. */
167172
168173 (void )strcpy (one , "x" );
@@ -188,11 +193,11 @@ void libm_test_string()
188193
189194 /* strncat - first test it as strcat, with big counts,
190195 then test the count mechanism. */
191- it = "strncat" ;
196+ it = PSTR ( "strncat" ) ;
192197 (void )strcpy (one , "ijk" );
193198#pragma GCC diagnostic push
194199#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. */
196201#pragma GCC diagnostic pop
197202 equal (one , "ijklmn" ); /* Basic test. */
198203
@@ -248,7 +253,7 @@ void libm_test_string()
248253 (void )strncat (one , "gh" , 2 );
249254#pragma GCC diagnostic pop
250255 equal (one , "abcdgh" ); /* Count _AND length equal. */
251- it = "strncmp" ;
256+ it = PSTR ( "strncmp" ) ;
252257 /* strncmp - first test as strcmp with big counts";*/
253258 check (strncmp ("" , "" , 99 ) == 0 ); /* Trivial case. */
254259 check (strncmp ("a" , "a" , 99 ) == 0 ); /* Identity. */
@@ -263,8 +268,8 @@ void libm_test_string()
263268 check (strncmp ("abc" , "def" , 0 ) == 0 ); /* Zero count. */
264269
265270 /* 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. */
268273 equal (one , "abc" ); /* Did the copy go right? */
269274
270275 (void )strcpy (one , "abcdefgh" );
@@ -310,13 +315,13 @@ void libm_test_string()
310315 equal (one , "hi there" ); /* Stomped on source? */
311316
312317 /* strlen. */
313- it = "strlen" ;
318+ it = PSTR ( "strlen" ) ;
314319 check (strlen ("" ) == 0 ); /* Empty. */
315320 check (strlen ("a" ) == 1 ); /* Single char. */
316321 check (strlen ("abcd" ) == 4 ); /* Multiple chars. */
317322
318323 /* strchr. */
319- it = "strchr" ;
324+ it = PSTR ( "strchr" ) ;
320325 check (strchr ("abcd" , 'z' ) == NULL ); /* Not found. */
321326 (void )strcpy (one , "abcd" );
322327 check (strchr (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -330,7 +335,7 @@ void libm_test_string()
330335 check (strchr (one , '\0' ) == one ); /* NUL in empty string. */
331336
332337 /* index - just like strchr. */
333- it = "index" ;
338+ it = PSTR ( "index" ) ;
334339 check (index ("abcd" , 'z' ) == NULL ); /* Not found. */
335340 (void )strcpy (one , "abcd" );
336341 check (index (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -344,7 +349,7 @@ void libm_test_string()
344349 check (index (one , '\0' ) == one ); /* NUL in empty string. */
345350
346351 /* strrchr. */
347- it = "strrchr" ;
352+ it = PSTR ( "strrchr" ) ;
348353 check (strrchr ("abcd" , 'z' ) == NULL ); /* Not found. */
349354 (void )strcpy (one , "abcd" );
350355 check (strrchr (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -358,7 +363,7 @@ void libm_test_string()
358363 check (strrchr (one , '\0' ) == one ); /* NUL in empty string. */
359364
360365 /* rindex - just like strrchr. */
361- it = "rindex" ;
366+ it = PSTR ( "rindex" ) ;
362367 check (rindex ("abcd" , 'z' ) == NULL ); /* Not found. */
363368 (void )strcpy (one , "abcd" );
364369 check (rindex (one , 'c' ) == one + 2 ); /* Basic test. */
@@ -372,7 +377,7 @@ void libm_test_string()
372377 check (rindex (one , '\0' ) == one ); /* NUL in empty string. */
373378
374379 /* strpbrk - somewhat like strchr. */
375- it = "strpbrk" ;
380+ it = PSTR ( "strpbrk" ) ;
376381 check (strpbrk ("abcd" , "z" ) == NULL ); /* Not found. */
377382 (void )strcpy (one , "abcd" );
378383 check (strpbrk (one , "c" ) == one + 2 ); /* Basic test. */
@@ -389,7 +394,7 @@ void libm_test_string()
389394 check (strpbrk (one , "" ) == NULL ); /* Both strings empty. */
390395
391396 /* strstr - somewhat like strchr. */
392- it = "strstr" ;
397+ it = PSTR ( "strstr" ) ;
393398 check (strstr ("z" , "abcd" ) == NULL ); /* Not found. */
394399 check (strstr ("abx" , "abcd" ) == NULL ); /* Dead end. */
395400 (void )strcpy (one , "abcd" );
@@ -412,23 +417,23 @@ void libm_test_string()
412417 check (strstr (one , "bbca" ) == one + 1 ); /* With overlap. */
413418
414419 /* strspn. */
415- it = "strspn" ;
420+ it = PSTR ( "strspn" ) ;
416421 check (strspn ("abcba" , "abc" ) == 5 ); /* Whole string. */
417422 check (strspn ("abcba" , "ab" ) == 2 ); /* Partial. */
418423 check (strspn ("abc" , "qx" ) == 0 ); /* None. */
419424 check (strspn ("" , "ab" ) == 0 ); /* Null string. */
420425 check (strspn ("abc" , "" ) == 0 ); /* Null search list. */
421426
422427 /* strcspn. */
423- it = "strcspn" ;
428+ it = PSTR ( "strcspn" ) ;
424429 check (strcspn ("abcba" , "qx" ) == 5 ); /* Whole string. */
425430 check (strcspn ("abcba" , "cx" ) == 2 ); /* Partial. */
426431 check (strcspn ("abc" , "abc" ) == 0 ); /* None. */
427432 check (strcspn ("" , "ab" ) == 0 ); /* Null string. */
428433 check (strcspn ("abc" , "" ) == 3 ); /* Null search list. */
429434
430435 /* strtok - the hard one. */
431- it = "strtok" ;
436+ it = PSTR ( "strtok" ) ;
432437 (void )strcpy (one , "first, second, third" );
433438 equal (strtok (one , ", " ), "first" ); /* Basic test. */
434439 equal (one , "first" );
@@ -475,7 +480,7 @@ void libm_test_string()
475480 equal (one + 4 , "c" );
476481
477482 /* memcmp. */
478- it = "memcmp" ;
483+ it = PSTR ( "memcmp" ) ;
479484 check (memcmp ("a" , "a" , 1 ) == 0 ); /* Identity. */
480485 check (memcmp ("abc" , "abc" , 3 ) == 0 ); /* Multicharacter. */
481486 check (memcmp ("abcd" , "abce" , 4 ) < 0 ); /* Honestly unequal. */
@@ -490,7 +495,7 @@ void libm_test_string()
490495 check (xmemcmp (one , two , 1 ) > 0 );
491496
492497 /* memchr. */
493- it = "memchr" ;
498+ it = PSTR ( "memchr" ) ;
494499 check (memchr ("abcd" , 'z' , 4 ) == NULL ); /* Not found. */
495500 (void )strcpy (one , "abcd" );
496501 check (xmemchr (one , 'c' , 4 ) == one + 2 ); /* Basic test. */
@@ -505,8 +510,8 @@ void libm_test_string()
505510 check (xmemchr (one , 0203 , 3 ) == one + 1 ); /* Unsignedness. */
506511
507512 /* 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. */
510515 equal (one , "abc" ); /* Did the copy go right? */
511516
512517 (void )strcpy (one , "abcdefgh" );
@@ -522,10 +527,10 @@ void libm_test_string()
522527 (void )xmemcpy (two , one , 9 );
523528 equal (two , "hi there" ); /* Just paranoia. */
524529 equal (one , "hi there" ); /* Stomped on source? */
525- #if 0
530+ #if 1
526531 /* 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. */
529534 equal (one , "abc" ); /* Did the copy go right? */
530535
531536 (void ) strcpy (one , "abcdefgh" );
@@ -538,28 +543,28 @@ void libm_test_string()
538543
539544 (void ) strcpy (one , "hi there" );
540545 (void ) strcpy (two , "foo" );
541- (void ) memmove (two , one , 9 );
546+ (void ) xmemmove (two , one , 9 );
542547 equal (two , "hi there" ); /* Just paranoia. */
543548 equal (one , "hi there" ); /* Stomped on source? */
544549
545550 (void ) strcpy (one , "abcdefgh" );
546- (void ) memmove (one + 1 , one , 9 );
551+ (void ) xmemmove (one + 1 , one , 9 );
547552 equal (one , "aabcdefgh" ); /* Overlap, right-to-left. */
548553
549554 (void ) strcpy (one , "abcdefgh" );
550- (void ) memmove (one + 1 , one + 2 , 7 );
555+ (void ) xmemmove (one + 1 , one + 2 , 7 );
551556 equal (one , "acdefgh" ); /* Overlap, left-to-right. */
552557
553558 (void ) strcpy (one , "abcdefgh" );
554- (void ) memmove (one , one , 9 );
559+ (void ) xmemmove (one , one , 9 );
555560 equal (one , "abcdefgh" ); /* 100% overlap. */
556561#endif
557562#if 0
558563 /* memccpy - first test like memcpy, then the search part
559564 The SVID, the only place where memccpy is mentioned, says
560565 overlap might fail, so we don't try it. Besides, it's hard
561566 to see the rationale for a non-left-to-right memccpy. */
562- it = "memccpy" ;
567+ it = PSTR ( "memccpy" ) ;
563568 check (memccpy (one , "abc" , 'q' , 4 ) == NULL ); /* Returned value. */
564569 equal (one , "abc" ); /* Did the copy go right? */
565570
@@ -594,7 +599,7 @@ void libm_test_string()
594599 equal (two , "xbcdlebee" );
595600#endif
596601 /* memset. */
597- it = "memset" ;
602+ it = PSTR ( "memset" ) ;
598603 (void )strcpy (one , "abcdefgh" );
599604 check (memset (one + 1 , 'x' , 3 ) == one + 1 ); /* Return value. */
600605 equal (one , "axxxefgh" ); /* Basic test. */
@@ -614,7 +619,7 @@ void libm_test_string()
614619
615620 /* bcopy - much like memcpy.
616621 Berklix manual is silent about overlap, so don't test it. */
617- it = "bcopy" ;
622+ it = PSTR ( "bcopy" ) ;
618623 (void )bcopy ("abc" , one , 4 );
619624 equal (one , "abc" ); /* Simple copy. */
620625
@@ -633,7 +638,7 @@ void libm_test_string()
633638 equal (one , "hi there" ); /* Stomped on source? */
634639
635640 /* bzero. */
636- it = "bzero" ;
641+ it = PSTR ( "bzero" ) ;
637642 (void )strcpy (one , "abcdef" );
638643 bzero (one + 2 , 2 );
639644 equal (one , "ab" ); /* Basic test. */
@@ -645,7 +650,7 @@ void libm_test_string()
645650 equal (one , "abcdef" ); /* Zero-length copy. */
646651
647652 /* bcmp - somewhat like memcmp. */
648- it = "bcmp" ;
653+ it = PSTR ( "bcmp" ) ;
649654 check (bcmp ("a" , "a" , 1 ) == 0 ); /* Identity. */
650655 check (bcmp ("abc" , "abc" , 3 ) == 0 ); /* Multicharacter. */
651656 check (bcmp ("abcd" , "abce" , 4 ) != 0 ); /* Honestly unequal. */
0 commit comments