1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/* $Id: strsep_P.c,v 1.1.2.1 2008/03/20 21:42:30 joerg_wunsch Exp $ */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "progmem.h"
#ifndef __AVR__
# define PRINTFLN(line, fmt, ...) \
printf("\nLine %d: " fmt "\n", line, ##__VA_ARGS__)
# define EXIT(code) exit ((code) < 255 ? (code) : 255)
# define memcmp_P memcmp
# define strsep_P strsep
#else
# if defined(__AVR_ATmega128__)
/* ATmega128 has enough RAM for sprintf(), print to 0x2000 in XRAM. */
# define PRINTFLN(line, fmt, ...) \
sprintf ((char *)0x2000, "\nLine %d: " fmt "\n", line, ##__VA_ARGS__)
# else
/* small AVR */
# define PRINTFLN(args...)
# endif
# define EXIT exit
#endif
void Check (int line, const char *s1, const char *s2, int clr, int pnt)
{
char t1[300];
char *sp;
char *rp;
if (strlen_P(s1) > sizeof(t1) - 1)
exit (1);
strcpy_P (t1, s1);
sp = t1;
rp = strsep_P (&sp, s2);
if (rp != t1) {
PRINTFLN (line, "false return value");
EXIT (5000 + line);
}
if (clr < 0) {
if (strcmp_P (t1, s1)) {
PRINTFLN (line, "string is changed");
EXIT (line);
}
} else {
if (strlen (t1) != (size_t)clr) {
PRINTFLN (line, "strlen: expect= %d result= %d",
clr, strlen (t1));
EXIT (1000 + line);
}
if (memcmp_P (t1, s1, clr)
|| t1[clr]
|| strcmp_P (t1 + clr + 1, s1 + clr + 1))
{
PRINTFLN (line, "string mismatch");
EXIT (2000 + line);
}
}
if (pnt < 0) {
if (sp) {
PRINTFLN (line, "sp is not a NULL");
EXIT (3000 + line);
}
} else {
if (sp != t1 + pnt) {
PRINTFLN (line, "sp: expect= %d result= %d",
pnt, sp - t1);
EXIT (4000 + line);
}
}
}
/* Args:
s - string to parse
delim - delimeter list
clr - if (clr >= 0) s[cln] must be cleared
pnt - if (pnt >= 0) s[pnt] must be pointed, else NULL
*/
#define CHECK(s, delim, clr, pnt) do { \
Check (__LINE__, PSTR(s), PSTR(delim), clr, pnt); \
} while (0)
int main ()
{
char *p;
/* NULL at first call */
p = 0;
if (strsep_P (&p, "") || p) exit (__LINE__);
if (strsep_P (&p, "abc") || p) exit (__LINE__);
/* Empty string */
CHECK ("", "", -1, -1);
CHECK ("", "abc", -1, -1);
/* Empty delimeter list */
CHECK ("a", "", -1, -1);
CHECK ("12345678", "", -1, -1);
/* No delimeter symbols are founded */
CHECK ("\tabc", " ", -1, -1);
CHECK ("THE QUICK BROWN FOX", "thequickbrownfox", -1, -1);
/* delim is 1 byte long */
CHECK (".", ".", 0, 1);
CHECK ("abc", "a", 0, 1);
CHECK ("abc", "b", 1, 2);
CHECK ("abc", "c", 2, 3);
/* delim is 2 bytes long */
CHECK ("0", "01", 0, 1);
CHECK ("1", "01", 0, 1);
CHECK ("A.", "AB", 0, 1);
CHECK ("B.", "AB", 0, 1);
CHECK ("CAD", "AB", 1, 2);
CHECK ("CDB", "AB", 2, 3);
/* delim length > 2 bytes */
CHECK ("the quick", "0123456789 ", 3, 4);
/* Very long string */
CHECK ("................................................................"
"................................................................"
"................................................................"
"...............................................................*",
"*", 255, 256);
CHECK ("................................................................"
"................................................................"
"................................................................"
"................................................................"
"*", "*", 256, 257);
/* Non ASCII bytes */
CHECK ("\001\002\377", "\001", 0, 1);
CHECK ("\001\002\377", "\377", 2, 3);
}
|