int ascii_strncasecmp (char const *a, char const *b, size_t n) { unsigned char const *p1 = (unsigned char const *)a; unsigned char const *p2 = (unsigned char const *)b; unsigned char c1, c2; if (p1 == p2 || !n ) return 0; do { c1 = ascii_tolower (*p1); c2 = ascii_tolower (*p2); if ( !--n || c1 == '\0') break; ++p1; ++p2; } while (c1 == c2); return c1 - c2; }
int ascii_strcasecmp (const char *a, const char *b) { const unsigned char *p1 = (const unsigned char *)a; const unsigned char *p2 = (const unsigned char *)b; unsigned char c1, c2; if (p1 == p2) return 0; do { c1 = ascii_tolower (*p1); c2 = ascii_tolower (*p2); if (c1 == '\0') break; ++p1; ++p2; } while (c1 == c2); return c1 - c2; }
static int ascii_strncasecmp(const char *s1, const char *s2, size_t n){ const unsigned char *us1 = (const unsigned char *)s1; const unsigned char *us2 = (const unsigned char *)s2; while( *us1 && *us2 && n && ascii_tolower(*us1)==ascii_tolower(*us2) ){ us1++, us2++, n--; } return n ? ascii_tolower(*us1)-ascii_tolower(*us2) : 0; }
int stricmp_ascii(const char * s1,const char * s2) throw() { for(;;) { char c1 = ascii_tolower(*s1), c2 = ascii_tolower(*s2); if (c1<c2) return -1; else if (c1>c2) return 1; else if (c1 == 0) return 0; s1++; s2++; } }
int stricmp_ascii_partial( const char * str, const char * substr) throw() { size_t walk = 0; for(;;) { char c1 = str[walk]; char c2 = substr[walk]; c1 = ascii_tolower(c1); c2 = ascii_tolower(c2); if (c2 == 0) return 0; // substr terminated = ret0 regardless of str content if (c1<c2) return -1; // ret -1 early else if (c1>c2) return 1; // ret 1 early // else c1 == c2 and c2 != 0 so c1 != 0 either ++walk; // go on } }
int stricmp_ascii_ex(const char * const s1,t_size const len1,const char * const s2,t_size const len2) throw() { t_size walk1 = 0, walk2 = 0; for(;;) { char c1 = (walk1 < len1) ? s1[walk1] : 0; char c2 = (walk2 < len2) ? s2[walk2] : 0; c1 = ascii_tolower(c1); c2 = ascii_tolower(c2); if (c1<c2) return -1; else if (c1>c2) return 1; else if (c1 == 0) return 0; walk1++; walk2++; } }
static void setup_map(void) { static gboolean done; guint i; if (done) return; for (i = 0; i < G_N_ELEMENTS(map); i++) { guchar c; if (i > 0 && utf8_byte_is_allowed(i)) { if (is_ascii_upper(i)) { c = ascii_tolower(i); } else if ( is_ascii_punct(i) || is_ascii_cntrl(i) || is_ascii_space(i) ) { c = ' '; } else { c = i; } } else { c = 0; } map[i] = c; } done = TRUE; }
bool EnumMapper::parse(std::string s, int &val, bool ignore_case) const { auto i = name2val.find(ignore_case ? ascii_tolower(s) : s); // Throws if (i == name2val.end()) return false; val = i->second; return true; }
bool EnumMapper::parse(string s, int &val, bool ignore_case) const { std::map<std::string, int>::const_iterator const i = name2val.find(ignore_case ? ascii_tolower(s) : s); if(i == name2val.end()) return false; val = i->second; return true; }
int ascii_strncasecmp (const char *a, const char *b, int n) { int i, j; if (a == b) return 0; if (a == NULL && b) return -1; if (b == NULL && a) return 1; for (j = 0; (*a || *b) && j < n; a++, b++, j++) { if ((i = ascii_tolower (*a) - ascii_tolower (*b))) return i; } return 0; }
int ascii_strcasecmp (const char *a, const char *b) { int i; if (a == b) return 0; if (a == NULL && b) return -1; if (b == NULL && a) return 1; for (; *a || *b; a++, b++) { if ((i = ascii_tolower (*a) - ascii_tolower (*b))) return i; } return 0; }
/** * This method compares the data in one buffer with another * @update gess 01/04/99 * @param aStr1 is the first buffer to be compared * @param aStr2 is the 2nd buffer to be compared * @param aCount is the number of chars to compare * @param aIgnoreCase tells us whether to use a case-sensitive comparison * @return -1,0,1 depending on <,==,> */ static #ifdef __SUNPRO_CC inline #endif /* __SUNPRO_CC */ PRInt32 Compare2To1(const PRUnichar* aStr1,const char* aStr2,PRUint32 aCount,bool aIgnoreCase){ const PRUnichar* s1 = aStr1; const char *s2 = aStr2; if (aStr1 && aStr2) { if (aCount != 0) { do { PRUnichar c1 = *s1++; PRUnichar c2 = PRUnichar((unsigned char)*s2++); if (c1 != c2) { #ifdef NS_DEBUG // we won't warn on c1>=128 (the 2-byte value) because often // it is just fine to compare an constant, ascii value (i.e. "body") // against some non-ascii value (i.e. a unicode string that // was downloaded from a web page) if (aIgnoreCase && c2>=128) NS_WARNING("got a non-ASCII string, but we can't do an accurate case conversion!"); #endif // can't do case conversion on characters out of our range if (aIgnoreCase && c1<128 && c2<128) { c1 = ascii_tolower(char(c1)); c2 = ascii_tolower(char(c2)); if (c1 == c2) continue; } if (c1 < c2) return -1; return 1; } } while (--aCount); } } return 0; }
static int cache_glob_lookup_file_name (const char *file_name, const char *mime_types[], int n_mime_types) { int n; MimeWeight mimes[10]; int n_mimes = 10; int i; int len; char *lower_case; assert (file_name != NULL && n_mime_types > 0); /* First, check the literals */ lower_case = ascii_tolower (file_name); n = cache_glob_lookup_literal (lower_case, mime_types, n_mime_types, FALSE); if (n > 0) { free (lower_case); return n; } n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types, TRUE); if (n > 0) { free (lower_case); return n; } len = strlen (file_name); n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes); if (n < 2) n += cache_glob_lookup_suffix (file_name, len, TRUE, mimes + n, n_mimes - n); free (lower_case); /* Last, try fnmatch */ if (n < 2) n += cache_glob_lookup_fnmatch (file_name, mimes + n, n_mimes - n); n = filter_out_dupes (mimes, n); qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); if (n_mime_types < n) n = n_mime_types; for (i = 0; i < n; i++) mime_types[i] = mimes[i].mime; return n; }
BufferedImage::Ref load_image(InputStream& in, std::string source_name, std::string format_name, Logger* logger, FileFormat::ProgressTracker* tracker, FileFormat::Registry::ConstRefArg r) { FileFormat::Registry::ConstRef registry = r; if (!registry) registry = FileFormat::Registry::get_default_registry(); RewindableStream rewindable(in); // Primary auto-detection if (format_name.empty()) { for (int i = 0; i < registry->get_num_formats(); ++i) { FileFormat::ConstRef f = registry->get_format(i); bool s = f->check_signature(rewindable); rewindable.rewind(); if (!s) continue; format_name = f->get_name(); break; } } rewindable.release(); // Secondary auto-detection if (format_name.empty()) { std::string suffix = ascii_tolower(file::suffix_of(source_name)); if (!suffix.empty()) { for (int i = 0; i < registry->get_num_formats(); ++i) { FileFormat::ConstRef f = registry->get_format(i); if (!f->check_suffix(suffix)) continue; format_name = f->get_name(); break; } } } if (format_name.empty()) { throw UnresolvableFormatException("Image format could not be detected from the initial " "data nor from the file name: \""+source_name+"\""); } for (int i = 0; i < registry->get_num_formats(); ++i) { FileFormat::ConstRef f = registry->get_format(i); if (format_name != f->get_name()) continue; BufferedImage::Ref j = f->load(rewindable, logger, tracker); return j; } throw UnknownFormatException("Unrecognized format specifier: \""+format_name+"\""); }
static void check_trie_with_file(const trie_t *db, const char *file) { file_map_t map; const char *p, *end; char line[BUFSIZ]; if (!file_map_open(&map, file, false)) { return; } p = map.map; end = map.end; while (end > p && end[-1] != '\n') { --end; } if (end != map.end) { warn("file %s miss a final \\n, ignoring last line", file); } while (p < end && p != NULL) { const char *eol = (char *)memchr(p, '\n', end - p); if (eol == NULL) { eol = end; } if (eol - p > BUFSIZ) { p = eol - BUFSIZ; } int i = 0; if (*p != '#' && p != eol) { #if 1 for (const char *s = eol - 1 ; s >= p ; --s) { line[i++] = ascii_tolower(*s); } #else memcpy(line, p, eol - p); i = eol - p; #endif line[i] = '\0'; if (!trie_lookup(db, line)) { warn("'%s' not found in the trie", line); } strcat(line, "coucou"); if (trie_lookup(db, line)) { warn("'%s' found in trie", line); } if (!trie_prefix(db, line)) { warn("'%s' has no prefix in trie", line); } } p = eol + 1; } file_map_close(&map); }
EnumMapper::EnumMapper(const EnumAssoc* m, bool ignore_case) { if (!m) return; while (m->name) { std::string name = m->name; if (!val2name.insert(std::pair<int, std::string>(m->value, name)).second) throw std::runtime_error("Multiple names for value "+format_value(m->value)); if (!name2val.insert(std::pair<std::string, int>(ignore_case ? ascii_tolower(name) : name, m->value)).second) throw std::runtime_error("Multiple values for name '"+name+"'"); ++m; } }
char * enum_map_name(const char *name, size_t namelen) { static char buf[SIZEOF_STR]; int bufpos; for (bufpos = 0; bufpos <= namelen; bufpos++) { buf[bufpos] = ascii_tolower(name[bufpos]); if (buf[bufpos] == '_') buf[bufpos] = '-'; } buf[bufpos] = 0; return buf; }
static trie_t *create_trie_from_file(const char *file) { trie_t *db; file_map_t map; const char *p, *end; char line[BUFSIZ]; if (!file_map_open(&map, file, false)) { return NULL; } p = map.map; end = map.end; while (end > p && end[-1] != '\n') { --end; } if (end != map.end) { warn("file %s miss a final \\n, ignoring last line", file); } db = trie_new(); while (p < end && p != NULL) { const char *eol = (char *)memchr(p, '\n', end - p); if (eol == NULL) { eol = end; } if (eol - p > BUFSIZ) { p = eol - BUFSIZ; } int i = 0; if (*p != '#' && p != eol) { #if 1 for (const char *s = eol - 1 ; s >= p ; --s) { line[i++] = ascii_tolower(*s); } #else memcpy(line, p, eol - p); i = eol - p; #endif line[i] = '\0'; trie_insert(db, line); } p = eol + 1; } file_map_close(&map); trie_compile(db, false); return db; }
/** * Compute character mask "hash", using one bit per letter of the alphabet, * plus one for any digit. */ static guint32 mask_hash(const char *s) { guchar c; guint32 mask = 0; while ((c = (guchar) *s++)) { if (is_ascii_space(c)) continue; else if (is_ascii_digit(c)) mask |= MASK_DIGIT; else { int idx = ascii_tolower(c) - 97; if (idx >= 0 && idx < 26) mask |= MASK_LETTER(idx); } } return mask; }
url_scheme_t url_check_scheme (const char *s) { char sbuf[STRING]; char *t; int i; if (!s || !(t = strchr (s, ':'))) return U_UNKNOWN; if ((size_t)(t - s) >= sizeof (sbuf) - 1) return U_UNKNOWN; strfcpy (sbuf, s, t - s + 1); for (t = sbuf; *t; t++) *t = ascii_tolower (*t); if ((i = mutt_getvaluebyname (sbuf, UrlMap)) == -1) return U_UNKNOWN; else return (url_scheme_t) i; }
void save_image(Image::ConstRefArg image, OutputStream& out, std::string target_name, std::string format_name, Logger* logger, FileFormat::ProgressTracker* tracker, FileFormat::Registry::ConstRefArg r) { FileFormat::Registry::ConstRef registry = r; if (!registry) registry = FileFormat::Registry::get_default_registry(); if (format_name.empty()) { // Determine format by suffix std::string suffix = ascii_tolower(file::suffix_of(target_name)); if (!suffix.empty()) { for (int i = 0; i < registry->get_num_formats(); ++i) { FileFormat::ConstRef f = registry->get_format(i); if (!f->check_suffix(suffix)) continue; format_name = f->get_name(); break; } } } if (format_name.empty()) { throw UnresolvableFormatException("Image format could not be " "detected from the file name" ": \"" + target_name + "\""); } for (int i = 0; i < registry->get_num_formats(); ++i) { FileFormat::ConstRef f = registry->get_format(i); if (format_name != f->get_name()) continue; f->save(image, out, logger, tracker); out.flush(); return; } throw UnknownFormatException("Unrecognized format " "specifier: \""+format_name+"\""); }
static const char *pgp_entry_fmt (char *dest, size_t destlen, size_t col, char op, const char *src, const char *prefix, const char *ifstring, const char *elsestring, unsigned long data, format_flag flags) { char fmt[16]; pgp_entry_t *entry; pgp_uid_t *uid; pgp_key_t key, pkey; int kflags = 0; int optional = (flags & M_FORMAT_OPTIONAL); entry = (pgp_entry_t *) data; uid = entry->uid; key = uid->parent; pkey = pgp_principal_key (key); if (isupper ((unsigned char) op)) key = pkey; kflags = key->flags | (pkey->flags & KEYFLAG_RESTRICTIONS) | uid->flags; switch (ascii_tolower (op)) { case '[': { const char *cp; char buf2[SHORT_STRING], *p; int do_locales; struct tm *tm; size_t len; p = dest; cp = src; if (*cp == '!') { do_locales = 0; cp++; } else do_locales = 1; len = destlen - 1; while (len > 0 && *cp != ']') { if (*cp == '%') { cp++; if (len >= 2) { *p++ = '%'; *p++ = *cp; len -= 2; } else break; /* not enough space */ cp++; } else { *p++ = *cp++; len--; } } *p = 0; if (do_locales && Locale) setlocale (LC_TIME, Locale); tm = localtime (&key->gen_time); strftime (buf2, sizeof (buf2), dest, tm); if (do_locales) setlocale (LC_TIME, "C"); snprintf (fmt, sizeof (fmt), "%%%ss", prefix); snprintf (dest, destlen, fmt, buf2); if (len > 0) src = cp + 1; } break; case 'n': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%sd", prefix); snprintf (dest, destlen, fmt, entry->num); } break; case 'k': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%ss", prefix); snprintf (dest, destlen, fmt, _pgp_keyid (key)); } break; case 'u': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%ss", prefix); snprintf (dest, destlen, fmt, NONULL (uid->addr)); } break; case 'a': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%ss", prefix); snprintf (dest, destlen, fmt, key->algorithm); } break; case 'l': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%sd", prefix); snprintf (dest, destlen, fmt, key->keylen); } break; case 'f': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%sc", prefix); snprintf (dest, destlen, fmt, pgp_flags (kflags)); } else if (!(kflags & (KEYFLAG_RESTRICTIONS))) optional = 0; break; case 'c': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%ss", prefix); snprintf (dest, destlen, fmt, pgp_key_abilities (kflags)); } else if (!(kflags & (KEYFLAG_ABILITIES))) optional = 0; break; case 't': if (!optional) { snprintf (fmt, sizeof (fmt), "%%%sc", prefix); snprintf (dest, destlen, fmt, trust_flags[uid->trust & 0x03]); } else if (!(uid->trust & 0x03)) /* undefined trust */ optional = 0; break; default: *dest = '\0'; } if (optional) mutt_FormatString (dest, destlen, col, ifstring, mutt_attach_fmt, data, 0); else if (flags & M_FORMAT_OPTIONAL) mutt_FormatString (dest, destlen, col, elsestring, mutt_attach_fmt, data, 0); return (src); }
keyserver_spec_t parse_keyserver_uri (const char *string,int require_scheme, const char *configname,unsigned int configlineno) { int assume_hkp=0; struct keyserver_spec *keyserver; const char *idx; int count; char *uri,*options; assert(string!=NULL); keyserver=xmalloc_clear(sizeof(struct keyserver_spec)); uri=xstrdup(string); options=strchr(uri,' '); if(options) { char *tok; *options='\0'; options++; while((tok=optsep(&options))) add_canonical_option(tok,&keyserver->options); } /* Get the scheme */ for(idx=uri,count=0;*idx && *idx!=':';idx++) { count++; /* Do we see the start of an RFC-2732 ipv6 address here? If so, there clearly isn't a scheme so get out early. */ if(*idx=='[') { /* Was the '[' the first thing in the string? If not, we have a mangled scheme with a [ in it so fail. */ if(count==1) break; else goto fail; } } if(count==0) goto fail; if(*idx=='\0' || *idx=='[') { if(require_scheme) return NULL; /* Assume HKP if there is no scheme */ assume_hkp=1; keyserver->scheme=xstrdup("hkp"); keyserver->uri=xmalloc(strlen(keyserver->scheme)+3+strlen(uri)+1); strcpy(keyserver->uri,keyserver->scheme); strcat(keyserver->uri,"://"); strcat(keyserver->uri,uri); } else { int i; keyserver->uri=xstrdup(uri); keyserver->scheme=xmalloc(count+1); /* Force to lowercase */ for(i=0;i<count;i++) keyserver->scheme[i]=ascii_tolower(uri[i]); keyserver->scheme[i]='\0'; /* Skip past the scheme and colon */ uri+=count+1; } if(ascii_strcasecmp(keyserver->scheme,"x-broken-hkp")==0) { deprecated_warning(configname,configlineno,"x-broken-hkp", "--keyserver-options ","broken-http-proxy"); xfree(keyserver->scheme); keyserver->scheme=xstrdup("hkp"); append_to_strlist(&opt.keyserver_options.other,"broken-http-proxy"); } else if(ascii_strcasecmp(keyserver->scheme,"x-hkp")==0) { /* Canonicalize this to "hkp" so it works with both the internal and external keyserver interface. */ xfree(keyserver->scheme); keyserver->scheme=xstrdup("hkp"); } if (uri[0]=='/' && uri[1]=='/' && uri[2] == '/') { /* Three slashes means network path with a default host name. This is a hack because it does not crok all possible combiantions. We should better repalce all code bythe parser from http.c. */ keyserver->path = xstrdup (uri+2); } else if(assume_hkp || (uri[0]=='/' && uri[1]=='/')) { /* Two slashes means network path. */ /* Skip over the "//", if any */ if(!assume_hkp) uri+=2; /* Do we have userinfo auth data present? */ for(idx=uri,count=0;*idx && *idx!='@' && *idx!='/';idx++) count++; /* We found a @ before the slash, so that means everything before the @ is auth data. */ if(*idx=='@') { if(count==0) goto fail; keyserver->auth=xmalloc(count+1); strncpy(keyserver->auth,uri,count); keyserver->auth[count]='\0'; uri+=count+1; } /* Is it an RFC-2732 ipv6 [literal address] ? */ if(*uri=='[') { for(idx=uri+1,count=1;*idx && ((isascii (*idx) && isxdigit(*idx)) || *idx==':' || *idx=='.');idx++) count++; /* Is the ipv6 literal address terminated? */ if(*idx==']') count++; else goto fail; } else for(idx=uri,count=0;*idx && *idx!=':' && *idx!='/';idx++) count++; if(count==0) goto fail; keyserver->host=xmalloc(count+1); strncpy(keyserver->host,uri,count); keyserver->host[count]='\0'; /* Skip past the host */ uri+=count; if(*uri==':') { /* It would seem to be reasonable to limit the range of the ports to values between 1-65535, but RFC 1738 and 1808 imply there is no limit. Of course, the real world has limits. */ for(idx=uri+1,count=0;*idx && *idx!='/';idx++) { count++; /* Ports are digits only */ if(!digitp(idx)) goto fail; } keyserver->port=xmalloc(count+1); strncpy(keyserver->port,uri+1,count); keyserver->port[count]='\0'; /* Skip past the colon and port number */ uri+=1+count; } /* Everything else is the path */ if(*uri) keyserver->path=xstrdup(uri); else keyserver->path=xstrdup("/"); if(keyserver->path[1]) keyserver->flags.direct_uri=1; } else if(uri[0]!='/') { /* No slash means opaque. Just record the opaque blob and get out. */ keyserver->opaque=xstrdup(uri); } else { /* One slash means absolute path. We don't need to support that yet. */ goto fail; } return keyserver; fail: free_keyserver_spec(keyserver); return NULL; }
int _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, const char *file_name, const char *mime_types[], int n_mime_types) { XdgGlobList *list; int i, n; MimeWeight mimes[10]; int n_mimes = 10; int len; char *lower_case; /* First, check the literals */ assert (file_name != NULL && n_mime_types > 0); n = 0; lower_case = ascii_tolower (file_name); for (list = glob_hash->literal_list; list; list = list->next) { if (strcmp ((const char *)list->data, file_name) == 0) { mime_types[0] = list->mime_type; free (lower_case); return 1; } } for (list = glob_hash->literal_list; list; list = list->next) { if (!list->case_sensitive && strcmp ((const char *)list->data, lower_case) == 0) { mime_types[0] = list->mime_type; free (lower_case); return 1; } } len = strlen (file_name); n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE, mimes, n_mimes); if (n < 2) n += _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE, mimes + n, n_mimes - n); if (n < 2) { for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next) { if (fnmatch ((const char *)list->data, file_name, 0) == 0) { mimes[n].mime = list->mime_type; mimes[n].weight = list->weight; n++; } } } free (lower_case); n = filter_out_dupes (mimes, n); qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); if (n_mime_types < n) n = n_mime_types; for (i = 0; i < n; i++) mime_types[i] = mimes[i].mime; return n; }
/** * Get next token, as delimited by one of the characters given in ``delim'' or * by the end of the string, whichever comes first. Same as strtok_next(), * only we can specify whether we wish to ignore leading and/or trailing spaces * for this lookup. * * When ``looked'' is non-NULL, we're looking whether the token matches the * string, and we do not bother constructing the token as soon as we have * determined that the current token cannot match. Therefore, the returned * token string is meaningless and forced to "", the empty string. * * @param s the string tokenizing object * @param delim the string containing one-character delimiters, e.g. ",;" * @param no_lead whether leading spaces in token should be stripped * @param no_end whether trailing spaces in token should be stripped * @param length if non-NULL, gets filled with the returned token length * @param looked the token which we're looking for, NULL if none * @param caseless whether token matching is to be done case-insensitively * @param found if non-NULL, gets filled with whether we found ``looked'' * * @return pointer to the next token, which must be duplicated if it needs to * be perused, or NULL if there are no more tokens. The token lifetime lasts * until the next call to one of the strtok_* functions on the same object. */ static const char * strtok_next_internal(strtok_t *s, const char *delim, bool no_lead, bool no_end, size_t *length, const char *looked, bool caseless, bool *found) { size_t tlen; int c; int d_min, d_max; const char *l = NULL; bool seen_non_blank = FALSE; int deferred_blank = 0; char *tstart; strtok_check(s); g_assert(delim != NULL); if (NULL == s->p) return NULL; /* Finished parsing */ /* * Pre-compile delimiter string to see what are the min and max character * codes on which we delimit tokens. When handling a low amount of * delimiters which are close enough in the 8-bit code space, this lowers * significantly the amount of character comparisons we have to do. */ d_min = 256; d_max = 0; { const char *q = delim; int d; while ((d = peek_u8(q++))) { if (d < d_min) d_min = d; if (d > d_max) d_max = d; } } /* * Now parse the string until we reach one of the delimiters or its end. */ s->t = s->token; tlen = 0; while ((c = peek_u8(s->p++))) { /* Have we reached one of the delimiters? */ if (c >= d_min && c <= d_max) { const char *q = delim; int d; while ((d = peek_u8(q++))) { if (d == c) goto end_token; } } /* Check whether token can match the ``looked'' up string */ if (looked != NULL) { if (!seen_non_blank && !is_ascii_blank(c)) seen_non_blank = TRUE; if (!no_lead || seen_non_blank) { int x; if (l == NULL) l = looked; if (no_end) { if (is_ascii_blank(c)) { deferred_blank++; continue; } else { for (/**/; deferred_blank > 0; deferred_blank--) { /* All blanks deemed equal here */ if (!is_ascii_blank(*l++)) goto skip_until_delim; } } } x = peek_u8(l++); if (caseless) { if (ascii_tolower(c) != ascii_tolower(x)) goto skip_until_delim; } else if (c != x) { goto skip_until_delim; } } continue; /* No need to collect token when looking... */ } /* Character was not a delimiter, add to token */ if (tlen >= s->len) extend_token(s); g_assert(tlen < s->len); s->t = poke_u8(s->t, c); tlen++; } s->p = NULL; /* Signals: reached end of string */ end_token: if (tlen >= s->len) extend_token(s); g_assert(tlen < s->len); g_assert(s->len > 0); /* * Strip trailing white spaces if required. */ if (no_end) { while (s->t > s->token) { if (!is_ascii_blank(*(s->t - 1))) break; s->t--; } } *s->t = '\0'; /* End token string */ /* Check whether token can match the ``looked'' up string */ if (looked != NULL) { if (l == NULL) l = looked; if (*l != '\0') goto not_found; *s->token = '\0'; /* Always return empty string */ } /* * Leading white spaces are skipped if required. */ tstart = no_lead ? skip_ascii_blanks(s->token) : s->token; /* Fill to-be-returned information */ if (found) *found = TRUE; if (length) *length = s->t - tstart; return tstart; skip_until_delim: /* * Looked-up string did not match the token we were constructing. * Move to the next delimiter or the end of the string, skipping * the token construction. */ while ((c = peek_u8(s->p++))) { if (c >= d_min && c <= d_max) { const char *q = delim; int d; while ((d = peek_u8(q++))) { if (d == c) goto not_found; /* Found delimiter, not the string */ } } } /* FALL THROUGH */ not_found: /* * We did not find the looked-up string and reached either the next * delimiter or the end of the parsed string. */ if (0 == s->len) extend_token(s); *s->token = '\0'; /* Always return empty string */ if (length) *length = 0; if (found) *found = FALSE; return s->token; }