1*a067558eSArnaldo Carvalho de Melo #include "string2.h" 2*a067558eSArnaldo Carvalho de Melo #include <linux/kernel.h> 3*a067558eSArnaldo Carvalho de Melo #include <linux/string.h> 4*a067558eSArnaldo Carvalho de Melo #include <stdlib.h> 586470930SIngo Molnar 63d689ed6SArnaldo Carvalho de Melo #include "sane_ctype.h" 73d689ed6SArnaldo Carvalho de Melo 8d2fb8b41SHitoshi Mitake #define K 1024LL 9d2fb8b41SHitoshi Mitake /* 10d2fb8b41SHitoshi Mitake * perf_atoll() 11d2fb8b41SHitoshi Mitake * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB") 12d2fb8b41SHitoshi Mitake * and return its numeric value 13d2fb8b41SHitoshi Mitake */ 14d2fb8b41SHitoshi Mitake s64 perf_atoll(const char *str) 15d2fb8b41SHitoshi Mitake { 168ba7f6c2SAl Viro s64 length; 178ba7f6c2SAl Viro char *p; 188ba7f6c2SAl Viro char c; 19d2fb8b41SHitoshi Mitake 20d2fb8b41SHitoshi Mitake if (!isdigit(str[0])) 21d2fb8b41SHitoshi Mitake goto out_err; 22d2fb8b41SHitoshi Mitake 238ba7f6c2SAl Viro length = strtoll(str, &p, 10); 248ba7f6c2SAl Viro switch (c = *p++) { 258ba7f6c2SAl Viro case 'b': case 'B': 268ba7f6c2SAl Viro if (*p) 27d2fb8b41SHitoshi Mitake goto out_err; 2894bdd5edSArnaldo Carvalho de Melo 2994bdd5edSArnaldo Carvalho de Melo __fallthrough; 308ba7f6c2SAl Viro case '\0': 318ba7f6c2SAl Viro return length; 32d2fb8b41SHitoshi Mitake default: 33d2fb8b41SHitoshi Mitake goto out_err; 348ba7f6c2SAl Viro /* two-letter suffices */ 358ba7f6c2SAl Viro case 'k': case 'K': 368ba7f6c2SAl Viro length <<= 10; 378ba7f6c2SAl Viro break; 388ba7f6c2SAl Viro case 'm': case 'M': 398ba7f6c2SAl Viro length <<= 20; 408ba7f6c2SAl Viro break; 418ba7f6c2SAl Viro case 'g': case 'G': 428ba7f6c2SAl Viro length <<= 30; 438ba7f6c2SAl Viro break; 448ba7f6c2SAl Viro case 't': case 'T': 458ba7f6c2SAl Viro length <<= 40; 46d2fb8b41SHitoshi Mitake break; 47d2fb8b41SHitoshi Mitake } 488ba7f6c2SAl Viro /* we want the cases to match */ 498ba7f6c2SAl Viro if (islower(c)) { 508ba7f6c2SAl Viro if (strcmp(p, "b") != 0) 518ba7f6c2SAl Viro goto out_err; 528ba7f6c2SAl Viro } else { 538ba7f6c2SAl Viro if (strcmp(p, "B") != 0) 548ba7f6c2SAl Viro goto out_err; 55d2fb8b41SHitoshi Mitake } 568ba7f6c2SAl Viro return length; 57d2fb8b41SHitoshi Mitake 58d2fb8b41SHitoshi Mitake out_err: 598ba7f6c2SAl Viro return -1; 60d2fb8b41SHitoshi Mitake } 61e1c01d61SMasami Hiramatsu 62e1c01d61SMasami Hiramatsu /* 63e1c01d61SMasami Hiramatsu * Helper function for splitting a string into an argv-like array. 6425985edcSLucas De Marchi * originally copied from lib/argv_split.c 65e1c01d61SMasami Hiramatsu */ 66e1c01d61SMasami Hiramatsu static const char *skip_sep(const char *cp) 67e1c01d61SMasami Hiramatsu { 68e1c01d61SMasami Hiramatsu while (*cp && isspace(*cp)) 69e1c01d61SMasami Hiramatsu cp++; 70e1c01d61SMasami Hiramatsu 71e1c01d61SMasami Hiramatsu return cp; 72e1c01d61SMasami Hiramatsu } 73e1c01d61SMasami Hiramatsu 74e1c01d61SMasami Hiramatsu static const char *skip_arg(const char *cp) 75e1c01d61SMasami Hiramatsu { 76e1c01d61SMasami Hiramatsu while (*cp && !isspace(*cp)) 77e1c01d61SMasami Hiramatsu cp++; 78e1c01d61SMasami Hiramatsu 79e1c01d61SMasami Hiramatsu return cp; 80e1c01d61SMasami Hiramatsu } 81e1c01d61SMasami Hiramatsu 82e1c01d61SMasami Hiramatsu static int count_argc(const char *str) 83e1c01d61SMasami Hiramatsu { 84e1c01d61SMasami Hiramatsu int count = 0; 85e1c01d61SMasami Hiramatsu 86e1c01d61SMasami Hiramatsu while (*str) { 87e1c01d61SMasami Hiramatsu str = skip_sep(str); 88e1c01d61SMasami Hiramatsu if (*str) { 89e1c01d61SMasami Hiramatsu count++; 90e1c01d61SMasami Hiramatsu str = skip_arg(str); 91e1c01d61SMasami Hiramatsu } 92e1c01d61SMasami Hiramatsu } 93e1c01d61SMasami Hiramatsu 94e1c01d61SMasami Hiramatsu return count; 95e1c01d61SMasami Hiramatsu } 96e1c01d61SMasami Hiramatsu 97e1c01d61SMasami Hiramatsu /** 98e1c01d61SMasami Hiramatsu * argv_free - free an argv 99e1c01d61SMasami Hiramatsu * @argv - the argument vector to be freed 100e1c01d61SMasami Hiramatsu * 101e1c01d61SMasami Hiramatsu * Frees an argv and the strings it points to. 102e1c01d61SMasami Hiramatsu */ 103e1c01d61SMasami Hiramatsu void argv_free(char **argv) 104e1c01d61SMasami Hiramatsu { 105e1c01d61SMasami Hiramatsu char **p; 106*a067558eSArnaldo Carvalho de Melo for (p = argv; *p; p++) { 107*a067558eSArnaldo Carvalho de Melo free(*p); 108*a067558eSArnaldo Carvalho de Melo *p = NULL; 109*a067558eSArnaldo Carvalho de Melo } 110e1c01d61SMasami Hiramatsu 111e1c01d61SMasami Hiramatsu free(argv); 112e1c01d61SMasami Hiramatsu } 113e1c01d61SMasami Hiramatsu 114e1c01d61SMasami Hiramatsu /** 115e1c01d61SMasami Hiramatsu * argv_split - split a string at whitespace, returning an argv 116e1c01d61SMasami Hiramatsu * @str: the string to be split 117e1c01d61SMasami Hiramatsu * @argcp: returned argument count 118e1c01d61SMasami Hiramatsu * 119e1c01d61SMasami Hiramatsu * Returns an array of pointers to strings which are split out from 120e1c01d61SMasami Hiramatsu * @str. This is performed by strictly splitting on white-space; no 121e1c01d61SMasami Hiramatsu * quote processing is performed. Multiple whitespace characters are 122e1c01d61SMasami Hiramatsu * considered to be a single argument separator. The returned array 123e1c01d61SMasami Hiramatsu * is always NULL-terminated. Returns NULL on memory allocation 124e1c01d61SMasami Hiramatsu * failure. 125e1c01d61SMasami Hiramatsu */ 126e1c01d61SMasami Hiramatsu char **argv_split(const char *str, int *argcp) 127e1c01d61SMasami Hiramatsu { 128e1c01d61SMasami Hiramatsu int argc = count_argc(str); 129*a067558eSArnaldo Carvalho de Melo char **argv = calloc(argc + 1, sizeof(*argv)); 130e1c01d61SMasami Hiramatsu char **argvp; 131e1c01d61SMasami Hiramatsu 132e1c01d61SMasami Hiramatsu if (argv == NULL) 133e1c01d61SMasami Hiramatsu goto out; 134e1c01d61SMasami Hiramatsu 135e1c01d61SMasami Hiramatsu if (argcp) 136e1c01d61SMasami Hiramatsu *argcp = argc; 137e1c01d61SMasami Hiramatsu 138e1c01d61SMasami Hiramatsu argvp = argv; 139e1c01d61SMasami Hiramatsu 140e1c01d61SMasami Hiramatsu while (*str) { 141e1c01d61SMasami Hiramatsu str = skip_sep(str); 142e1c01d61SMasami Hiramatsu 143e1c01d61SMasami Hiramatsu if (*str) { 144e1c01d61SMasami Hiramatsu const char *p = str; 145e1c01d61SMasami Hiramatsu char *t; 146e1c01d61SMasami Hiramatsu 147e1c01d61SMasami Hiramatsu str = skip_arg(str); 148e1c01d61SMasami Hiramatsu 149e1c01d61SMasami Hiramatsu t = strndup(p, str-p); 150e1c01d61SMasami Hiramatsu if (t == NULL) 151e1c01d61SMasami Hiramatsu goto fail; 152e1c01d61SMasami Hiramatsu *argvp++ = t; 153e1c01d61SMasami Hiramatsu } 154e1c01d61SMasami Hiramatsu } 155e1c01d61SMasami Hiramatsu *argvp = NULL; 156e1c01d61SMasami Hiramatsu 157e1c01d61SMasami Hiramatsu out: 158e1c01d61SMasami Hiramatsu return argv; 159e1c01d61SMasami Hiramatsu 160e1c01d61SMasami Hiramatsu fail: 161e1c01d61SMasami Hiramatsu argv_free(argv); 162e1c01d61SMasami Hiramatsu return NULL; 163e1c01d61SMasami Hiramatsu } 164bbbb521bSMasami Hiramatsu 1656964cd2cSMasami Hiramatsu /* Character class matching */ 1666964cd2cSMasami Hiramatsu static bool __match_charclass(const char *pat, char c, const char **npat) 1676964cd2cSMasami Hiramatsu { 1686964cd2cSMasami Hiramatsu bool complement = false, ret = true; 1696964cd2cSMasami Hiramatsu 1706964cd2cSMasami Hiramatsu if (*pat == '!') { 1716964cd2cSMasami Hiramatsu complement = true; 1726964cd2cSMasami Hiramatsu pat++; 1736964cd2cSMasami Hiramatsu } 1746964cd2cSMasami Hiramatsu if (*pat++ == c) /* First character is special */ 1756964cd2cSMasami Hiramatsu goto end; 1766964cd2cSMasami Hiramatsu 1776964cd2cSMasami Hiramatsu while (*pat && *pat != ']') { /* Matching */ 1786964cd2cSMasami Hiramatsu if (*pat == '-' && *(pat + 1) != ']') { /* Range */ 1796964cd2cSMasami Hiramatsu if (*(pat - 1) <= c && c <= *(pat + 1)) 1806964cd2cSMasami Hiramatsu goto end; 1816964cd2cSMasami Hiramatsu if (*(pat - 1) > *(pat + 1)) 1826964cd2cSMasami Hiramatsu goto error; 1836964cd2cSMasami Hiramatsu pat += 2; 1846964cd2cSMasami Hiramatsu } else if (*pat++ == c) 1856964cd2cSMasami Hiramatsu goto end; 1866964cd2cSMasami Hiramatsu } 1876964cd2cSMasami Hiramatsu if (!*pat) 1886964cd2cSMasami Hiramatsu goto error; 1896964cd2cSMasami Hiramatsu ret = false; 1906964cd2cSMasami Hiramatsu 1916964cd2cSMasami Hiramatsu end: 1926964cd2cSMasami Hiramatsu while (*pat && *pat != ']') /* Searching closing */ 1936964cd2cSMasami Hiramatsu pat++; 1946964cd2cSMasami Hiramatsu if (!*pat) 1956964cd2cSMasami Hiramatsu goto error; 1966964cd2cSMasami Hiramatsu *npat = pat + 1; 1976964cd2cSMasami Hiramatsu return complement ? !ret : ret; 1986964cd2cSMasami Hiramatsu 1996964cd2cSMasami Hiramatsu error: 2006964cd2cSMasami Hiramatsu return false; 2016964cd2cSMasami Hiramatsu } 2026964cd2cSMasami Hiramatsu 2032a9c8c36SMasami Hiramatsu /* Glob/lazy pattern matching */ 20438d14f0cSAndi Kleen static bool __match_glob(const char *str, const char *pat, bool ignore_space, 20538d14f0cSAndi Kleen bool case_ins) 206bbbb521bSMasami Hiramatsu { 207bbbb521bSMasami Hiramatsu while (*str && *pat && *pat != '*') { 2082a9c8c36SMasami Hiramatsu if (ignore_space) { 2092a9c8c36SMasami Hiramatsu /* Ignore spaces for lazy matching */ 2102a9c8c36SMasami Hiramatsu if (isspace(*str)) { 2112a9c8c36SMasami Hiramatsu str++; 2122a9c8c36SMasami Hiramatsu continue; 2132a9c8c36SMasami Hiramatsu } 2142a9c8c36SMasami Hiramatsu if (isspace(*pat)) { 2152a9c8c36SMasami Hiramatsu pat++; 2162a9c8c36SMasami Hiramatsu continue; 2172a9c8c36SMasami Hiramatsu } 2182a9c8c36SMasami Hiramatsu } 2196964cd2cSMasami Hiramatsu if (*pat == '?') { /* Matches any single character */ 220bbbb521bSMasami Hiramatsu str++; 221bbbb521bSMasami Hiramatsu pat++; 2226964cd2cSMasami Hiramatsu continue; 2236964cd2cSMasami Hiramatsu } else if (*pat == '[') /* Character classes/Ranges */ 2246964cd2cSMasami Hiramatsu if (__match_charclass(pat + 1, *str, &pat)) { 2256964cd2cSMasami Hiramatsu str++; 2266964cd2cSMasami Hiramatsu continue; 227bbbb521bSMasami Hiramatsu } else 2286964cd2cSMasami Hiramatsu return false; 2296964cd2cSMasami Hiramatsu else if (*pat == '\\') /* Escaped char match as normal char */ 2306964cd2cSMasami Hiramatsu pat++; 23138d14f0cSAndi Kleen if (case_ins) { 23238d14f0cSAndi Kleen if (tolower(*str) != tolower(*pat)) 233bbbb521bSMasami Hiramatsu return false; 23438d14f0cSAndi Kleen } else if (*str != *pat) 23538d14f0cSAndi Kleen return false; 23638d14f0cSAndi Kleen str++; 23738d14f0cSAndi Kleen pat++; 238bbbb521bSMasami Hiramatsu } 239bbbb521bSMasami Hiramatsu /* Check wild card */ 240bbbb521bSMasami Hiramatsu if (*pat == '*') { 241bbbb521bSMasami Hiramatsu while (*pat == '*') 242bbbb521bSMasami Hiramatsu pat++; 243bbbb521bSMasami Hiramatsu if (!*pat) /* Tail wild card matches all */ 244bbbb521bSMasami Hiramatsu return true; 245bbbb521bSMasami Hiramatsu while (*str) 24638d14f0cSAndi Kleen if (__match_glob(str++, pat, ignore_space, case_ins)) 247bbbb521bSMasami Hiramatsu return true; 248bbbb521bSMasami Hiramatsu } 249bbbb521bSMasami Hiramatsu return !*str && !*pat; 250bbbb521bSMasami Hiramatsu } 251bbbb521bSMasami Hiramatsu 2522a9c8c36SMasami Hiramatsu /** 2532a9c8c36SMasami Hiramatsu * strglobmatch - glob expression pattern matching 2542a9c8c36SMasami Hiramatsu * @str: the target string to match 2552a9c8c36SMasami Hiramatsu * @pat: the pattern string to match 2562a9c8c36SMasami Hiramatsu * 2572a9c8c36SMasami Hiramatsu * This returns true if the @str matches @pat. @pat can includes wildcards 2582a9c8c36SMasami Hiramatsu * ('*','?') and character classes ([CHARS], complementation and ranges are 2592a9c8c36SMasami Hiramatsu * also supported). Also, this supports escape character ('\') to use special 2602a9c8c36SMasami Hiramatsu * characters as normal character. 2612a9c8c36SMasami Hiramatsu * 2622a9c8c36SMasami Hiramatsu * Note: if @pat syntax is broken, this always returns false. 2632a9c8c36SMasami Hiramatsu */ 2642a9c8c36SMasami Hiramatsu bool strglobmatch(const char *str, const char *pat) 2652a9c8c36SMasami Hiramatsu { 26638d14f0cSAndi Kleen return __match_glob(str, pat, false, false); 26738d14f0cSAndi Kleen } 26838d14f0cSAndi Kleen 26938d14f0cSAndi Kleen bool strglobmatch_nocase(const char *str, const char *pat) 27038d14f0cSAndi Kleen { 27138d14f0cSAndi Kleen return __match_glob(str, pat, false, true); 2722a9c8c36SMasami Hiramatsu } 2732a9c8c36SMasami Hiramatsu 2742a9c8c36SMasami Hiramatsu /** 2752a9c8c36SMasami Hiramatsu * strlazymatch - matching pattern strings lazily with glob pattern 2762a9c8c36SMasami Hiramatsu * @str: the target string to match 2772a9c8c36SMasami Hiramatsu * @pat: the pattern string to match 2782a9c8c36SMasami Hiramatsu * 2792a9c8c36SMasami Hiramatsu * This is similar to strglobmatch, except this ignores spaces in 2802a9c8c36SMasami Hiramatsu * the target string. 2812a9c8c36SMasami Hiramatsu */ 2822a9c8c36SMasami Hiramatsu bool strlazymatch(const char *str, const char *pat) 2832a9c8c36SMasami Hiramatsu { 28438d14f0cSAndi Kleen return __match_glob(str, pat, true, false); 2852a9c8c36SMasami Hiramatsu } 286bad03ae4SMasami Hiramatsu 287bad03ae4SMasami Hiramatsu /** 288bad03ae4SMasami Hiramatsu * strtailcmp - Compare the tail of two strings 289bad03ae4SMasami Hiramatsu * @s1: 1st string to be compared 290bad03ae4SMasami Hiramatsu * @s2: 2nd string to be compared 291bad03ae4SMasami Hiramatsu * 292bad03ae4SMasami Hiramatsu * Return 0 if whole of either string is same as another's tail part. 293bad03ae4SMasami Hiramatsu */ 294bad03ae4SMasami Hiramatsu int strtailcmp(const char *s1, const char *s2) 295bad03ae4SMasami Hiramatsu { 296bad03ae4SMasami Hiramatsu int i1 = strlen(s1); 297bad03ae4SMasami Hiramatsu int i2 = strlen(s2); 298bad03ae4SMasami Hiramatsu while (--i1 >= 0 && --i2 >= 0) { 299bad03ae4SMasami Hiramatsu if (s1[i1] != s2[i2]) 300bad03ae4SMasami Hiramatsu return s1[i1] - s2[i2]; 301bad03ae4SMasami Hiramatsu } 302bad03ae4SMasami Hiramatsu return 0; 303bad03ae4SMasami Hiramatsu } 304bad03ae4SMasami Hiramatsu 305cb1a28a0SArnaldo Carvalho de Melo /** 306ea36c46bSJiri Olsa * strxfrchar - Locate and replace character in @s 307ea36c46bSJiri Olsa * @s: The string to be searched/changed. 308ea36c46bSJiri Olsa * @from: Source character to be replaced. 309ea36c46bSJiri Olsa * @to: Destination character. 310ea36c46bSJiri Olsa * 311ea36c46bSJiri Olsa * Return pointer to the changed string. 312ea36c46bSJiri Olsa */ 313ea36c46bSJiri Olsa char *strxfrchar(char *s, char from, char to) 314ea36c46bSJiri Olsa { 315ea36c46bSJiri Olsa char *p = s; 316ea36c46bSJiri Olsa 317ea36c46bSJiri Olsa while ((p = strchr(p, from)) != NULL) 318ea36c46bSJiri Olsa *p++ = to; 319ea36c46bSJiri Olsa 320ea36c46bSJiri Olsa return s; 321ea36c46bSJiri Olsa } 322ea36c46bSJiri Olsa 323ea36c46bSJiri Olsa /** 32408aa9cceSNamhyung Kim * ltrim - Removes leading whitespace from @s. 32508aa9cceSNamhyung Kim * @s: The string to be stripped. 32608aa9cceSNamhyung Kim * 32708aa9cceSNamhyung Kim * Return pointer to the first non-whitespace character in @s. 32808aa9cceSNamhyung Kim */ 32908aa9cceSNamhyung Kim char *ltrim(char *s) 33008aa9cceSNamhyung Kim { 331ecbe5e10SArnaldo Carvalho de Melo while (isspace(*s)) 33208aa9cceSNamhyung Kim s++; 33308aa9cceSNamhyung Kim 33408aa9cceSNamhyung Kim return s; 33508aa9cceSNamhyung Kim } 33608aa9cceSNamhyung Kim 33708aa9cceSNamhyung Kim /** 338cb1a28a0SArnaldo Carvalho de Melo * rtrim - Removes trailing whitespace from @s. 339cb1a28a0SArnaldo Carvalho de Melo * @s: The string to be stripped. 340cb1a28a0SArnaldo Carvalho de Melo * 341cb1a28a0SArnaldo Carvalho de Melo * Note that the first trailing whitespace is replaced with a %NUL-terminator 342cb1a28a0SArnaldo Carvalho de Melo * in the given string @s. Returns @s. 343cb1a28a0SArnaldo Carvalho de Melo */ 344cb1a28a0SArnaldo Carvalho de Melo char *rtrim(char *s) 345cb1a28a0SArnaldo Carvalho de Melo { 346cb1a28a0SArnaldo Carvalho de Melo size_t size = strlen(s); 347cb1a28a0SArnaldo Carvalho de Melo char *end; 348cb1a28a0SArnaldo Carvalho de Melo 349cb1a28a0SArnaldo Carvalho de Melo if (!size) 350cb1a28a0SArnaldo Carvalho de Melo return s; 351cb1a28a0SArnaldo Carvalho de Melo 352cb1a28a0SArnaldo Carvalho de Melo end = s + size - 1; 353cb1a28a0SArnaldo Carvalho de Melo while (end >= s && isspace(*end)) 354cb1a28a0SArnaldo Carvalho de Melo end--; 355cb1a28a0SArnaldo Carvalho de Melo *(end + 1) = '\0'; 356cb1a28a0SArnaldo Carvalho de Melo 357cb1a28a0SArnaldo Carvalho de Melo return s; 358cb1a28a0SArnaldo Carvalho de Melo } 359b232e073SJiri Olsa 36093ec4ce7SArnaldo Carvalho de Melo char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints) 36193ec4ce7SArnaldo Carvalho de Melo { 36293ec4ce7SArnaldo Carvalho de Melo /* 36393ec4ce7SArnaldo Carvalho de Melo * FIXME: replace this with an expression using log10() when we 36493ec4ce7SArnaldo Carvalho de Melo * find a suitable implementation, maybe the one in the dvb drivers... 36593ec4ce7SArnaldo Carvalho de Melo * 36693ec4ce7SArnaldo Carvalho de Melo * "%s == %d || " = log10(MAXINT) * 2 + 8 chars for the operators 36793ec4ce7SArnaldo Carvalho de Melo */ 36893ec4ce7SArnaldo Carvalho de Melo size_t size = nints * 28 + 1; /* \0 */ 36993ec4ce7SArnaldo Carvalho de Melo size_t i, printed = 0; 37093ec4ce7SArnaldo Carvalho de Melo char *expr = malloc(size); 37193ec4ce7SArnaldo Carvalho de Melo 37293ec4ce7SArnaldo Carvalho de Melo if (expr) { 37393ec4ce7SArnaldo Carvalho de Melo const char *or_and = "||", *eq_neq = "=="; 37493ec4ce7SArnaldo Carvalho de Melo char *e = expr; 37593ec4ce7SArnaldo Carvalho de Melo 37693ec4ce7SArnaldo Carvalho de Melo if (!in) { 37793ec4ce7SArnaldo Carvalho de Melo or_and = "&&"; 37893ec4ce7SArnaldo Carvalho de Melo eq_neq = "!="; 37993ec4ce7SArnaldo Carvalho de Melo } 38093ec4ce7SArnaldo Carvalho de Melo 38193ec4ce7SArnaldo Carvalho de Melo for (i = 0; i < nints; ++i) { 38293ec4ce7SArnaldo Carvalho de Melo if (printed == size) 38393ec4ce7SArnaldo Carvalho de Melo goto out_err_overflow; 38493ec4ce7SArnaldo Carvalho de Melo 38593ec4ce7SArnaldo Carvalho de Melo if (i > 0) 386*a067558eSArnaldo Carvalho de Melo printed += scnprintf(e + printed, size - printed, " %s ", or_and); 38793ec4ce7SArnaldo Carvalho de Melo printed += scnprintf(e + printed, size - printed, 38893ec4ce7SArnaldo Carvalho de Melo "%s %s %d", var, eq_neq, ints[i]); 38993ec4ce7SArnaldo Carvalho de Melo } 39093ec4ce7SArnaldo Carvalho de Melo } 39193ec4ce7SArnaldo Carvalho de Melo 39293ec4ce7SArnaldo Carvalho de Melo return expr; 39393ec4ce7SArnaldo Carvalho de Melo 39493ec4ce7SArnaldo Carvalho de Melo out_err_overflow: 39593ec4ce7SArnaldo Carvalho de Melo free(expr); 39693ec4ce7SArnaldo Carvalho de Melo return NULL; 39793ec4ce7SArnaldo Carvalho de Melo } 398