static int proc_options(int argc, char **argv, struct cmdline_options *opt, int envopt) { int n, argc0 = argc; const char *s; if (argc == 0) return 0; for (argc--, argv++; argc > 0; argc--, argv++) { const char *const arg = argv[0]; if (arg[0] != '-' || !arg[1]) break; s = arg + 1; reswitch: switch (*s) { case 'a': if (envopt) goto noenvopt; opt->do_split = Qtrue; s++; goto reswitch; case 'p': if (envopt) goto noenvopt; opt->do_print = Qtrue; /* through */ case 'n': if (envopt) goto noenvopt; opt->do_loop = Qtrue; s++; goto reswitch; case 'd': ruby_debug = Qtrue; ruby_verbose = Qtrue; s++; goto reswitch; case 'y': if (envopt) goto noenvopt; opt->yydebug = 1; s++; goto reswitch; case 'v': if (opt->verbose) { s++; goto reswitch; } ruby_show_version(); opt->verbose = 1; case 'w': ruby_verbose = Qtrue; s++; goto reswitch; case 'W': { int numlen; int v = 2; /* -W as -W2 */ if (*++s) { v = scan_oct(s, 1, &numlen); if (numlen == 0) v = 1; s += numlen; } switch (v) { case 0: ruby_verbose = Qnil; break; case 1: ruby_verbose = Qfalse; break; default: ruby_verbose = Qtrue; break; } } goto reswitch; case 'c': if (envopt) goto noenvopt; opt->do_check = Qtrue; s++; goto reswitch; case 's': if (envopt) goto noenvopt; forbid_setid("-s"); opt->sflag = 1; s++; goto reswitch; case 'h': if (envopt) goto noenvopt; usage(origarg.argv[0]); rb_exit(EXIT_SUCCESS); break; case 'l': if (envopt) goto noenvopt; opt->do_line = Qtrue; rb_output_rs = rb_rs; s++; goto reswitch; case 'S': if (envopt) goto noenvopt; forbid_setid("-S"); opt->do_search = Qtrue; s++; goto reswitch; case 'e': if (envopt) goto noenvopt; forbid_setid("-e"); if (!*++s) { s = argv[1]; argc--, argv++; } if (!s) { rb_raise(rb_eRuntimeError, "no code specified for -e"); } if (!opt->e_script) { opt->e_script = rb_str_new(0, 0); if (opt->script == 0) opt->script = "-e"; } rb_str_cat2(opt->e_script, s); rb_str_cat2(opt->e_script, "\n"); break; case 'r': forbid_setid("-r"); if (*++s) { add_modules(opt, s); } else if (argv[1]) { add_modules(opt, argv[1]); argc--, argv++; } break; case 'i': if (envopt) goto noenvopt; forbid_setid("-i"); ruby_set_inplace_mode(s + 1); break; case 'x': if (envopt) goto noenvopt; opt->xflag = Qtrue; s++; if (*s && chdir(s) < 0) { rb_fatal("Can't chdir to %s", s); } break; case 'C': case 'X': if (envopt) goto noenvopt; s++; if (!*s) { s = argv[1]; argc--, argv++; } if (!s || !*s) { rb_fatal("Can't chdir"); } if (chdir(s) < 0) { rb_fatal("Can't chdir to %s", s); } break; case 'F': if (envopt) goto noenvopt; if (*++s) { rb_fs = rb_reg_new(s, strlen(s), 0); } break; case 'E': if (!*++s && (!--argc || !(s = *++argv))) { rb_raise(rb_eRuntimeError, "missing argument for -E"); } goto encoding; case 'U': set_internal_encoding_once(opt, "UTF-8", 0); ++s; goto reswitch; case 'K': if (*++s) { const char *enc_name = 0; switch (*s) { case 'E': case 'e': enc_name = "EUC-JP"; break; case 'S': case 's': enc_name = "Windows-31J"; break; case 'U': case 'u': enc_name = "UTF-8"; break; case 'N': case 'n': case 'A': case 'a': enc_name = "ASCII-8BIT"; break; } if (enc_name) { opt->src.enc.name = rb_str_new2(enc_name); if (!opt->ext.enc.name) opt->ext.enc.name = opt->src.enc.name; } s++; } goto reswitch; case 'T': { int numlen; int v = 1; if (*++s) { v = scan_oct(s, 2, &numlen); if (numlen == 0) v = 1; s += numlen; } if (v > opt->safe_level) opt->safe_level = v; } goto reswitch; case 'I': forbid_setid("-I"); if (*++s) ruby_incpush_expand(s); else if (argv[1]) { ruby_incpush_expand(argv[1]); argc--, argv++; } break; case '0': if (envopt) goto noenvopt; { int numlen; int v; char c; v = scan_oct(s, 4, &numlen); s += numlen; if (v > 0377) rb_rs = Qnil; else if (v == 0 && numlen >= 2) { rb_rs = rb_str_new2("\n\n"); } else { c = v & 0xff; rb_rs = rb_str_new(&c, 1); } } goto reswitch; case '-': if (!s[1] || (s[1] == '\r' && !s[2])) { argc--, argv++; goto switch_end; } s++; # define is_option_end(c, allow_hyphen) \ (!(c) || (allow_hyphen && (c) == '-') || (c) == '=') # define check_envopt(name, allow_envopt) \ ((allow_envopt || !envopt) ? (void)0 : \ rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name)) # define need_argument(name, s) \ ((*s++ ? !*s : (!--argc || !(s = *++argv))) ? \ rb_raise(rb_eRuntimeError, "missing argument for --" name) \ : (void)0) # define is_option_with_arg(name, allow_hyphen, allow_envopt) \ (strncmp(name, s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], allow_hyphen) ? \ (check_envopt(name, allow_envopt), s += n, need_argument(name, s), 1) : 0) if (strcmp("copyright", s) == 0) { if (envopt) goto noenvopt_long; opt->copyright = 1; } else if (strcmp("debug", s) == 0) { ruby_debug = Qtrue; ruby_verbose = Qtrue; } else if (is_option_with_arg("enable", Qtrue, Qtrue)) { ruby_each_words(s, enable_option, &opt->disable); } else if (is_option_with_arg("disable", Qtrue, Qtrue)) { ruby_each_words(s, disable_option, &opt->disable); } else if (is_option_with_arg("encoding", Qfalse, Qtrue)) { char *p; encoding: do { # define set_encoding_part(type) \ if (!(p = strchr(s, ':'))) { \ set_##type##_encoding_once(opt, s, 0); \ break; \ } \ else if (p > s) { \ set_##type##_encoding_once(opt, s, p-s); \ } set_encoding_part(external); if (!*(s = ++p)) break; set_encoding_part(internal); if (!*(s = ++p)) break; rb_raise(rb_eRuntimeError, "extra argument for %s: %s", (arg[1] == '-' ? "--encoding" : "-E"), s); # undef set_encoding_part } while (0); } else if (is_option_with_arg("internal-encoding", Qfalse, Qtrue)) { set_internal_encoding_once(opt, s, 0); } else if (is_option_with_arg("external-encoding", Qfalse, Qtrue)) { set_external_encoding_once(opt, s, 0); } else if (strcmp("version", s) == 0) { if (envopt) goto noenvopt_long; opt->version = 1; } else if (strcmp("verbose", s) == 0) { opt->verbose = 1; ruby_verbose = Qtrue; } else if (strcmp("yydebug", s) == 0) { if (envopt) goto noenvopt_long; opt->yydebug = 1; } else if (is_option_with_arg("dump", Qfalse, Qfalse)) { ruby_each_words(s, dump_option, &opt->dump); } else if (strcmp("help", s) == 0) { if (envopt) goto noenvopt_long; usage(origarg.argv[0]); rb_exit(EXIT_SUCCESS); } else { rb_raise(rb_eRuntimeError, "invalid option --%s (-h will show valid options)", s); } break; case '\r': if (!s[1]) break; default: { if (ISPRINT(*s)) { rb_raise(rb_eRuntimeError, "invalid option -%c (-h will show valid options)", (int)(unsigned char)*s); } else { rb_raise(rb_eRuntimeError, "invalid option -\\x%02X (-h will show valid options)", (int)(unsigned char)*s); } } goto switch_end; noenvopt: /* "EIdvwWrKU" only */ rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s); break; noenvopt_long: rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s); break; case 0: break; # undef is_option_end # undef check_envopt # undef need_argument # undef is_option_with_arg } } switch_end: return argc0 - argc; }
/* ** Write a full decode on stdout for the cell at a[ofst]. ** Assume the page contains a header of size szPgHdr bytes. */ static void decodeCell( unsigned char *a, /* Page content (without the page-1 header) */ unsigned pgno, /* Page number */ int iCell, /* Cell index */ int szPgHdr, /* Size of the page header. 0 or 100 */ int ofst /* Cell begins at a[ofst] */ ){ int i, j = 0; int leftChild; i64 k; i64 nPayload; i64 rowid; i64 nHdr; i64 iType; i64 nLocal; unsigned char *x = a + ofst; unsigned char *end; unsigned char cType = a[0]; int nCol = 0; int szCol[2000]; int ofstCol[2000]; int typeCol[2000]; printf("Cell[%d]:\n", iCell); if( cType<=5 ){ leftChild = ((x[0]*256 + x[1])*256 + x[2])*256 + x[3]; printBytes(a, x, 4); printf("left child page:: %d\n", leftChild); x += 4; } if( cType!=5 ){ i = decodeVarint(x, &nPayload); printBytes(a, x, i); nLocal = localPayload(nPayload, cType); if( nLocal==nPayload ){ printf("payload-size: %lld\n", nPayload); }else{ printf("payload-size: %lld (%lld local, %lld overflow)\n", nPayload, nLocal, nPayload-nLocal); } x += i; }else{ nPayload = nLocal = 0; } end = x + nLocal; if( cType==5 || cType==13 ){ i = decodeVarint(x, &rowid); printBytes(a, x, i); printf("rowid: %lld\n", rowid); x += i; } if( nLocal>0 ){ i = decodeVarint(x, &nHdr); printBytes(a, x, i); printf("record-header-size: %d\n", (int)nHdr); j = i; nCol = 0; k = nHdr; while( x+j<end && j<nHdr ){ const char *zTypeName; int sz = 0; char zNm[30]; i = decodeVarint(x+j, &iType); printBytes(a, x+j, i); printf("typecode[%d]: %d - ", nCol, (int)iType); switch( iType ){ case 0: zTypeName = "NULL"; sz = 0; break; case 1: zTypeName = "int8"; sz = 1; break; case 2: zTypeName = "int16"; sz = 2; break; case 3: zTypeName = "int24"; sz = 3; break; case 4: zTypeName = "int32"; sz = 4; break; case 5: zTypeName = "int48"; sz = 6; break; case 6: zTypeName = "int64"; sz = 8; break; case 7: zTypeName = "double"; sz = 8; break; case 8: zTypeName = "zero"; sz = 0; break; case 9: zTypeName = "one"; sz = 0; break; case 10: case 11: zTypeName = "error"; sz = 0; break; default: { sz = (int)(iType-12)/2; sprintf(zNm, (iType&1)==0 ? "blob(%d)" : "text(%d)", sz); zTypeName = zNm; break; } } printf("%s\n", zTypeName); szCol[nCol] = sz; ofstCol[nCol] = (int)k; typeCol[nCol] = (int)iType; k += sz; nCol++; j += i; } for(i=0; i<nCol && ofstCol[i]+szCol[i]<=nLocal; i++){ int s = ofstCol[i]; i64 v; const unsigned char *pData; if( szCol[i]==0 ) continue; printBytes(a, x+s, szCol[i]); printf("data[%d]: ", i); pData = x+s; if( typeCol[i]<=7 ){ v = (signed char)pData[0]; for(k=1; k<szCol[i]; k++){ v = (v<<8) + pData[k]; } if( typeCol[i]==7 ){ double r; memcpy(&r, &v, sizeof(r)); printf("%#g\n", r); }else{ printf("%lld\n", v); } }else{ int ii, jj; char zConst[32]; if( (typeCol[i]&1)==0 ){ zConst[0] = 'x'; zConst[1] = '\''; for(ii=2, jj=0; jj<szCol[i] && ii<24; jj++, ii+=2){ sprintf(zConst+ii, "%02x", pData[jj]); } }else{ zConst[0] = '\''; for(ii=1, jj=0; jj<szCol[i] && ii<24; jj++, ii++){ zConst[ii] = ISPRINT(pData[jj]) ? pData[jj] : '.'; } zConst[ii] = 0; } if( jj<szCol[i] ){ memcpy(zConst+ii, "...'", 5); }else{ memcpy(zConst+ii, "'", 2); } printf("%s\n", zConst); } j = ofstCol[i] + szCol[i]; } } if( j<nLocal ){ printBytes(a, x+j, 0); printf("... %lld bytes of content ...\n", nLocal-j); } if( nLocal<nPayload ){ printBytes(a, x+nLocal, 4); printf("overflow-page: %d\n", decodeInt32(x+nLocal)); } }
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data=conn->data; ldapreqinfo *lr = data->state.proto.generic; int rc, ret; LDAPMessage *result = NULL; LDAPMessage *ent; BerElement *ber = NULL; struct timeval tv = {0,1}; (void)len; (void)buf; (void)sockindex; rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &result); if (rc < 0) { failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); *err = CURLE_RECV_ERROR; return -1; } *err = CURLE_AGAIN; ret = -1; /* timed out */ if (result == NULL) return ret; for (ent = ldap_first_message(li->ld, result); ent; ent = ldap_next_message(li->ld, ent)) { struct berval bv, *bvals, **bvp = &bvals; int binary = 0, msgtype; msgtype = ldap_msgtype(ent); if (msgtype == LDAP_RES_SEARCH_RESULT) { int code; char *info = NULL; rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0); if (rc) { failf(data, "LDAP local: search ldap_parse_result %s", ldap_err2string(rc)); *err = CURLE_LDAP_SEARCH_FAILED; } else if (code && code != LDAP_SIZELIMIT_EXCEEDED) { failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc), info ? info : ""); *err = CURLE_LDAP_SEARCH_FAILED; } else { /* successful */ if (code == LDAP_SIZELIMIT_EXCEEDED) infof(data, "There are more than %d entries\n", lr->nument); data->req.size = data->req.bytecount; *err = CURLE_OK; ret = 0; } lr->msgid = 0; ldap_memfree(info); break; } else if (msgtype != LDAP_RES_SEARCH_ENTRY) { continue; } lr->nument++; rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); data->req.bytecount += bv.bv_len + 5; for (rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp); rc == LDAP_SUCCESS; rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) { int i; if (bv.bv_val == NULL) break; if (bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) binary = 1; else binary = 0; for (i=0; bvals[i].bv_val != NULL; i++) { int binval = 0; Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); data->req.bytecount += bv.bv_len + 2; if (!binary) { /* check for leading or trailing whitespace */ if (ISSPACE(bvals[i].bv_val[0]) || ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) { binval = 1; } else { /* check for unprintable characters */ unsigned int j; for (j=0; j<bvals[i].bv_len; j++) if (!ISPRINT(bvals[i].bv_val[j])) { binval = 1; break; } } } if (binary || binval) { char *val_b64; /* Binary value, encode to base64. */ size_t val_b64_sz = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len, &val_b64); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); data->req.bytecount += 2; if(val_b64_sz > 0) { Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz); free(val_b64); data->req.bytecount += val_b64_sz; } } else { Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1); Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val, bvals[i].bv_len); data->req.bytecount += bvals[i].bv_len + 1; } Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); data->req.bytecount++; } ber_memfree(bvals); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); data->req.bytecount++; } Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); data->req.bytecount++; ber_free(ber, 0); } ldap_msgfree(result); return ret; }
static int internal_function FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, bool no_leading_period, int flags) { register const CHAR *p = pattern, *n = string; register UCHAR c; #ifdef _LIBC # if WIDE_CHAR_VERSION const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); # else const UCHAR *collseq = (const UCHAR *) _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB); # endif #endif while ((c = *p++) != L('\0')) { bool new_no_leading_period = false; c = FOLD (c); switch (c) { case L('?'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res; res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } if (n == string_end) return FNM_NOMATCH; else if (*n == L('/') && (flags & FNM_FILE_NAME)) return FNM_NOMATCH; else if (*n == L('.') && no_leading_period) return FNM_NOMATCH; break; case L('\\'): if (!(flags & FNM_NOESCAPE)) { c = *p++; if (c == L('\0')) /* Trailing \ loses. */ return FNM_NOMATCH; c = FOLD (c); } if (n == string_end || FOLD ((UCHAR) *n) != c) return FNM_NOMATCH; break; case L('*'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res; res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } if (n != string_end && *n == L('.') && no_leading_period) return FNM_NOMATCH; for (c = *p++; c == L('?') || c == L('*'); c = *p++) { if (*p == L('(') && (flags & FNM_EXTMATCH) != 0) { const CHAR *endp = END (p); if (endp != p) { /* This is a pattern. Skip over it. */ p = endp; continue; } } if (c == L('?')) { /* A ? needs to match one character. */ if (n == string_end) /* There isn't another character; no match. */ return FNM_NOMATCH; else if (*n == L('/') && __builtin_expect (flags & FNM_FILE_NAME, 0)) /* A slash does not match a wildcard under FNM_FILE_NAME. */ return FNM_NOMATCH; else /* One character of the string is consumed in matching this ? wildcard, so *??? won't match if there are less than three characters. */ ++n; } } if (c == L('\0')) /* The wildcard(s) is/are the last element of the pattern. If the name is a file name and contains another slash this means it cannot match, unless the FNM_LEADING_DIR flag is set. */ { int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH; if (flags & FNM_FILE_NAME) { if (flags & FNM_LEADING_DIR) result = 0; else { if (MEMCHR (n, L('/'), string_end - n) == NULL) result = 0; } } return result; } else { const CHAR *endp; endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'), string_end - n); if (endp == NULL) endp = string_end; if (c == L('[') || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 && (c == L('@') || c == L('+') || c == L('!')) && *p == L('('))) { int flags2 = ((flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD)); bool no_leading_period2 = no_leading_period; for (--p; n < endp; ++n, no_leading_period2 = false) if (FCT (p, n, string_end, no_leading_period2, flags2) == 0) return 0; } else if (c == L('/') && (flags & FNM_FILE_NAME)) { while (n < string_end && *n != L('/')) ++n; if (n < string_end && *n == L('/') && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) == 0)) return 0; } else { int flags2 = ((flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD)); int no_leading_period2 = no_leading_period; if (c == L('\\') && !(flags & FNM_NOESCAPE)) c = *p; c = FOLD (c); for (--p; n < endp; ++n, no_leading_period2 = false) if (FOLD ((UCHAR) *n) == c && (FCT (p, n, string_end, no_leading_period2, flags2) == 0)) return 0; } } /* If we come here no match is possible with the wildcard. */ return FNM_NOMATCH; case L('['): { /* Nonzero if the sense of the character class is inverted. */ register bool not; CHAR cold; UCHAR fn; if (posixly_correct == 0) posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; if (n == string_end) return FNM_NOMATCH; if (*n == L('.') && no_leading_period) return FNM_NOMATCH; if (*n == L('/') && (flags & FNM_FILE_NAME)) /* `/' cannot be matched. */ return FNM_NOMATCH; not = (*p == L('!') || (posixly_correct < 0 && *p == L('^'))); if (not) ++p; fn = FOLD ((UCHAR) *n); c = *p++; for (;;) { if (!(flags & FNM_NOESCAPE) && c == L('\\')) { if (*p == L('\0')) return FNM_NOMATCH; c = FOLD ((UCHAR) *p); ++p; if (c == fn) goto matched; } else if (c == L('[') && *p == L(':')) { /* Leave room for the null. */ CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; size_t c1 = 0; #if defined _LIBC || WIDE_CHAR_SUPPORT wctype_t wt; #endif const CHAR *startp = p; for (;;) { if (c1 == CHAR_CLASS_MAX_LENGTH) /* The name is too long and therefore the pattern is ill-formed. */ return FNM_NOMATCH; c = *++p; if (c == L(':') && p[1] == L(']')) { p += 2; break; } if (c < L('a') || c >= L('z')) { /* This cannot possibly be a character class name. Match it as a normal range. */ p = startp; c = L('['); goto normal_bracket; } str[c1++] = c; } str[c1] = L('\0'); #if defined _LIBC || WIDE_CHAR_SUPPORT wt = IS_CHAR_CLASS (str); if (wt == 0) /* Invalid character class name. */ return FNM_NOMATCH; # if defined _LIBC && ! WIDE_CHAR_VERSION /* The following code is glibc specific but does there a good job in speeding up the code since we can avoid the btowc() call. */ if (_ISCTYPE ((UCHAR) *n, wt)) goto matched; # else if (ISWCTYPE (BTOWC ((UCHAR) *n), wt)) goto matched; # endif #else if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n)) || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n)) || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n)) || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n)) || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n)) || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n)) || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n)) || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n)) || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n)) || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n)) || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n)) || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n))) goto matched; #endif c = *p++; } #ifdef _LIBC else if (c == L('[') && *p == L('=')) { UCHAR str[1]; uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); const CHAR *startp = p; c = *++p; if (c == L('\0')) { p = startp; c = L('['); goto normal_bracket; } str[0] = c; c = *++p; if (c != L('=') || p[1] != L(']')) { p = startp; c = L('['); goto normal_bracket; } p += 2; if (nrules == 0) { if ((UCHAR) *n == str[0]) goto matched; } else { const int32_t *table; # if WIDE_CHAR_VERSION const int32_t *weights; const int32_t *extra; # else const unsigned char *weights; const unsigned char *extra; # endif const int32_t *indirect; int32_t idx; const UCHAR *cp = (const UCHAR *) str; /* This #include defines a local function! */ # if WIDE_CHAR_VERSION # include <locale/weightwc.h> # else # include <locale/weight.h> # endif # if WIDE_CHAR_VERSION table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); weights = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); extra = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); # else table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); # endif idx = findidx (&cp); if (idx != 0) { /* We found a table entry. Now see whether the character we are currently at has the same equivalance class value. */ int len = weights[idx]; int32_t idx2; const UCHAR *np = (const UCHAR *) n; idx2 = findidx (&np); if (idx2 != 0 && len == weights[idx2]) { int cnt = 0; while (cnt < len && (weights[idx + 1 + cnt] == weights[idx2 + 1 + cnt])) ++cnt; if (cnt == len) goto matched; } } } c = *p++; } #endif else if (c == L('\0')) /* [ (unterminated) loses. */ return FNM_NOMATCH; else { bool is_range = false; #ifdef _LIBC bool is_seqval = false; if (c == L('[') && *p == L('.')) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); const CHAR *startp = p; size_t c1 = 0; while (1) { c = *++p; if (c == L('.') && p[1] == L(']')) { p += 2; break; } if (c == '\0') return FNM_NOMATCH; ++c1; } /* We have to handling the symbols differently in ranges since then the collation sequence is important. */ is_range = *p == L('-') && p[1] != L('\0'); if (nrules == 0) { /* There are no names defined in the collation data. Therefore we only accept the trivial names consisting of the character itself. */ if (c1 != 1) return FNM_NOMATCH; if (!is_range && *n == startp[1]) goto matched; cold = startp[1]; c = *p++; } else { int32_t table_size; const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION char str[c1]; size_t strcnt; # else # define str (startp + 1) # endif const unsigned char *extra; int32_t idx; int32_t elem; int32_t second; int32_t hash; # ifdef WIDE_CHAR_VERSION /* We have to convert the name to a single-byte string. This is possible since the names consist of ASCII characters and the internal representation is UCS4. */ for (strcnt = 0; strcnt < c1; ++strcnt) str[strcnt] = startp[1 + strcnt]; # endif table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); /* Locate the character in the hashing table. */ hash = elem_hash (str, c1); idx = 0; elem = hash % table_size; second = hash % (table_size - 2); while (symb_table[2 * elem] != 0) { /* First compare the hashing value. */ if (symb_table[2 * elem] == hash && c1 == extra[symb_table[2 * elem + 1]] && memcmp (str, &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { /* Yep, this is the entry. */ idx = symb_table[2 * elem + 1]; idx += 1 + extra[idx]; break; } /* Next entry. */ elem += second; } if (symb_table[2 * elem] != 0) { /* Compare the byte sequence but only if this is not part of a range. */ # ifdef WIDE_CHAR_VERSION int32_t *wextra; idx += 1 + extra[idx]; /* Adjust for the alignment. */ idx = (idx + 3) & ~3; wextra = (int32_t *) &extra[idx + 4]; # endif if (! is_range) { # ifdef WIDE_CHAR_VERSION for (c1 = 0; (int32_t) c1 < wextra[idx]; ++c1) if (n[c1] != wextra[1 + c1]) break; if ((int32_t) c1 == wextra[idx]) goto matched; # else for (c1 = 0; c1 < extra[idx]; ++c1) if (n[c1] != extra[1 + c1]) break; if (c1 == extra[idx]) goto matched; # endif } /* Get the collation sequence value. */ is_seqval = true; # ifdef WIDE_CHAR_VERSION cold = wextra[1 + wextra[idx]]; # else /* Adjust for the alignment. */ idx += 1 + extra[idx]; idx = (idx + 3) & ~4; cold = *((int32_t *) &extra[idx]); # endif c = *p++; } else if (c1 == 1) { /* No valid character. Match it as a single byte. */ if (!is_range && *n == str[0]) goto matched; cold = str[0]; c = *p++; } else return FNM_NOMATCH; } } else # undef str #endif { c = FOLD (c); normal_bracket: /* We have to handling the symbols differently in ranges since then the collation sequence is important. */ is_range = (*p == L('-') && p[1] != L('\0') && p[1] != L(']')); if (!is_range && c == fn) goto matched; cold = c; c = *p++; } if (c == L('-') && *p != L(']')) { #if _LIBC /* We have to find the collation sequence value for C. Collation sequence is nothing we can regularly access. The sequence value is defined by the order in which the definitions of the collation values for the various characters appear in the source file. A strange concept, nowhere documented. */ uint32_t fcollseq; uint32_t lcollseq; UCHAR cend = *p++; # ifdef WIDE_CHAR_VERSION /* Search in the `names' array for the characters. */ fcollseq = __collseq_table_lookup (collseq, fn); if (fcollseq == ~((uint32_t) 0)) /* XXX We don't know anything about the character we are supposed to match. This means we are failing. */ goto range_not_matched; if (is_seqval) lcollseq = cold; else lcollseq = __collseq_table_lookup (collseq, cold); # else fcollseq = collseq[fn]; lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; # endif is_seqval = false; if (cend == L('[') && *p == L('.')) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); const CHAR *startp = p; size_t c1 = 0; while (1) { c = *++p; if (c == L('.') && p[1] == L(']')) { p += 2; break; } if (c == '\0') return FNM_NOMATCH; ++c1; } if (nrules == 0) { /* There are no names defined in the collation data. Therefore we only accept the trivial names consisting of the character itself. */ if (c1 != 1) return FNM_NOMATCH; cend = startp[1]; } else { int32_t table_size; const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION char str[c1]; size_t strcnt; # else # define str (startp + 1) # endif const unsigned char *extra; int32_t idx; int32_t elem; int32_t second; int32_t hash; # ifdef WIDE_CHAR_VERSION /* We have to convert the name to a single-byte string. This is possible since the names consist of ASCII characters and the internal representation is UCS4. */ for (strcnt = 0; strcnt < c1; ++strcnt) str[strcnt] = startp[1 + strcnt]; # endif table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); /* Locate the character in the hashing table. */ hash = elem_hash (str, c1); idx = 0; elem = hash % table_size; second = hash % (table_size - 2); while (symb_table[2 * elem] != 0) { /* First compare the hashing value. */ if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) && memcmp (str, &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { /* Yep, this is the entry. */ idx = symb_table[2 * elem + 1]; idx += 1 + extra[idx]; break; } /* Next entry. */ elem += second; } if (symb_table[2 * elem] != 0) { /* Compare the byte sequence but only if this is not part of a range. */ # ifdef WIDE_CHAR_VERSION int32_t *wextra; idx += 1 + extra[idx]; /* Adjust for the alignment. */ idx = (idx + 3) & ~4; wextra = (int32_t *) &extra[idx + 4]; # endif /* Get the collation sequence value. */ is_seqval = true; # ifdef WIDE_CHAR_VERSION cend = wextra[1 + wextra[idx]]; # else /* Adjust for the alignment. */ idx += 1 + extra[idx]; idx = (idx + 3) & ~4; cend = *((int32_t *) &extra[idx]); # endif } else if (symb_table[2 * elem] != 0 && c1 == 1) { cend = str[0]; c = *p++; } else return FNM_NOMATCH; } # undef str } else { if (!(flags & FNM_NOESCAPE) && cend == L('\\')) cend = *p++; if (cend == L('\0')) return FNM_NOMATCH; cend = FOLD (cend); } /* XXX It is not entirely clear to me how to handle characters which are not mentioned in the collation specification. */ if ( # ifdef WIDE_CHAR_VERSION lcollseq == 0xffffffff || # endif lcollseq <= fcollseq) { /* We have to look at the upper bound. */ uint32_t hcollseq; if (is_seqval) hcollseq = cend; else { # ifdef WIDE_CHAR_VERSION hcollseq = __collseq_table_lookup (collseq, cend); if (hcollseq == ~((uint32_t) 0)) { /* Hum, no information about the upper bound. The matching succeeds if the lower bound is matched exactly. */ if (lcollseq != fcollseq) goto range_not_matched; goto matched; } # else hcollseq = collseq[cend]; # endif } if (lcollseq <= hcollseq && fcollseq <= hcollseq) goto matched; } # ifdef WIDE_CHAR_VERSION range_not_matched: # endif #else /* We use a boring value comparison of the character values. This is better than comparing using `strcoll' since the latter would have surprising and sometimes fatal consequences. */ UCHAR cend = *p++; if (!(flags & FNM_NOESCAPE) && cend == L('\\')) cend = *p++; if (cend == L('\0')) return FNM_NOMATCH; /* It is a range. */ if (cold <= fn && fn <= cend) goto matched; #endif c = *p++; } } if (c == L(']')) break; } if (!not) return FNM_NOMATCH; break; matched: /* Skip the rest of the [...] that already matched. */ do { ignore_next: c = *p++; if (c == L('\0')) /* [... (unterminated) loses. */ return FNM_NOMATCH; if (!(flags & FNM_NOESCAPE) && c == L('\\')) { if (*p == L('\0')) return FNM_NOMATCH; /* XXX 1003.2d11 is unclear if this is right. */ ++p; } else if (c == L('[') && *p == L(':')) { int c1 = 0; const CHAR *startp = p; while (1) { c = *++p; if (++c1 == CHAR_CLASS_MAX_LENGTH) return FNM_NOMATCH; if (*p == L(':') && p[1] == L(']')) break; if (c < L('a') || c >= L('z')) { p = startp; goto ignore_next; } } p += 2; c = *p++; } else if (c == L('[') && *p == L('=')) { c = *++p; if (c == L('\0')) return FNM_NOMATCH; c = *++p; if (c != L('=') || p[1] != L(']')) return FNM_NOMATCH; p += 2; c = *p++; } else if (c == L('[') && *p == L('.')) { ++p; while (1) { c = *++p; if (c == '\0') return FNM_NOMATCH; if (*p == L('.') && p[1] == L(']')) break; } p += 2; c = *p++; } } while (c != L(']')); if (not) return FNM_NOMATCH; } break; case L('+'): case L('@'): case L('!'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res; res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } goto normal_match; case L('/'): if (NO_LEADING_PERIOD (flags)) { if (n == string_end || c != (UCHAR) *n) return FNM_NOMATCH; new_no_leading_period = true; break; } /* FALLTHROUGH */ default: normal_match: if (n == string_end || c != FOLD ((UCHAR) *n)) return FNM_NOMATCH; } no_leading_period = new_no_leading_period; ++n; } if (n == string_end) return 0; if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L('/')) /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ return 0; return FNM_NOMATCH; }
/* * v_key_name -- * Return the string that will display the key. This routine * is the backup for the KEY_NAME() macro. * * PUBLIC: char *v_key_name __P((SCR *, ARG_CHAR_T)); */ char * v_key_name( SCR *sp, ARG_CHAR_T ach) { static const char hexdigit[] = "0123456789abcdef"; static const char octdigit[] = "01234567"; int ch; size_t len; char *chp; /* * Cache the last checked character. It won't be a problem * since nvi will rescan the mapping when settings changed. */ if (ach && sp->lastc == ach) return (sp->cname); sp->lastc = ach; #ifdef USE_WIDECHAR len = wctomb(sp->cname, ach); if (len > MB_CUR_MAX) #endif sp->cname[(len = 1)-1] = (u_char)ach; ch = (u_char)sp->cname[0]; sp->cname[len] = '\0'; /* See if the character was explicitly declared printable or not. */ if ((chp = O_STR(sp, O_PRINT)) != NULL) if (strstr(chp, sp->cname) != NULL) goto done; if ((chp = O_STR(sp, O_NOPRINT)) != NULL) if (strstr(chp, sp->cname) != NULL) goto nopr; /* * Historical (ARPA standard) mappings. Printable characters are left * alone. Control characters less than 0x20 are represented as '^' * followed by the character offset from the '@' character in the ASCII * character set. Del (0x7f) is represented as '^' followed by '?'. * * XXX * The following code depends on the current locale being identical to * the ASCII map from 0x40 to 0x5f (since 0x1f + 0x40 == 0x5f). I'm * told that this is a reasonable assumption... * * XXX * The code prints non-printable wide characters in 4 or 5 digits * Unicode escape sequences, so only supports plane 0 to 15. */ if (ISPRINT(ach)) goto done; nopr: if (iscntrl(ch) && (ch < 0x20 || ch == 0x7f)) { sp->cname[0] = '^'; sp->cname[1] = ch == 0x7f ? '?' : '@' + ch; len = 2; goto done; } #ifdef USE_WIDECHAR if (INTISWIDE(ach)) { int uc = -1; if (!strcmp(codeset(), "UTF-8")) uc = decode_utf8(sp->cname); #ifdef USE_ICONV else { char buf[sizeof(sp->cname)] = ""; size_t left = sizeof(sp->cname); char *in = sp->cname; char *out = buf; iconv(sp->conv.id[IC_IE_TO_UTF16], (iconv_src_t)&in, &len, &out, &left); iconv(sp->conv.id[IC_IE_TO_UTF16], NULL, NULL, NULL, NULL); uc = decode_utf16(buf, 1); } #endif if (uc >= 0) { len = snprintf(sp->cname, sizeof(sp->cname), uc < 0x10000 ? "\\u%04x" : "\\U%05X", uc); goto done; } } #endif if (O_ISSET(sp, O_OCTAL)) { sp->cname[0] = '\\'; sp->cname[1] = octdigit[(ch & 0300) >> 6]; sp->cname[2] = octdigit[(ch & 070) >> 3]; sp->cname[3] = octdigit[ ch & 07 ]; } else {
void ascii_print (FILE *e, const char *s, rc_uint_type length) { while (1) { char ch; if (length == 0) return; if ((bfd_signed_vma) length > 0) --length; ch = *s; if (ch == 0 && (bfd_signed_vma) length < 0) return; ++s; if ((ch & 0x7f) == ch) { if (ch == '\\') fputs ("\\\\", e); else if (ch == '"') fputs ("\"\"", e); else if (ISPRINT (ch)) putc (ch, e); else { switch (ch) { case ESCAPE_A: fputs ("\\a", e); break; case ESCAPE_B: fputs ("\\b", e); break; case ESCAPE_F: fputs ("\\f", e); break; case ESCAPE_N: fputs ("\\n", e); break; case ESCAPE_R: fputs ("\\r", e); break; case ESCAPE_T: fputs ("\\t", e); break; case ESCAPE_V: fputs ("\\v", e); break; default: fprintf (e, "\\%03o", (unsigned int) ch); break; } } } else fprintf (e, "\\%03o", (unsigned int) ch & 0xff); } }
static int bfd_pef_parse_traceback_table (bfd *abfd, asection *section, unsigned char *buf, size_t len, size_t pos, asymbol *sym, FILE *file) { struct traceback_table table; size_t offset; const char *s; asymbol tmpsymbol; if (sym == NULL) sym = & tmpsymbol; sym->name = NULL; sym->value = 0; sym->the_bfd = abfd; sym->section = section; sym->flags = 0; sym->udata.i = 0; /* memcpy is fine since all fields are unsigned char. */ if ((pos + 8) > len) return -1; memcpy (&table, buf + pos, 8); /* Calling code relies on returned symbols having a name and correct offset. */ if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS)) return -1; if (! (table.flags2 & TB_NAME_PRESENT)) return -1; if (! table.flags1 & TB_HAS_TBOFF) return -1; offset = 8; if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams)) offset += 4; if (table.flags1 & TB_HAS_TBOFF) { struct traceback_table_tboff off; if ((pos + offset + 4) > len) return -1; off.tb_offset = bfd_getb32 (buf + pos + offset); offset += 4; /* Need to subtract 4 because the offset includes the 0x0L preceding the table. */ if (file != NULL) fprintf (file, " [offset = 0x%lx]", off.tb_offset); if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset))) return -1; sym->value = pos - off.tb_offset - 4; } if (table.flags2 & TB_INT_HNDL) offset += 4; if (table.flags1 & TB_HAS_CTL) { struct traceback_table_anchors anchors; if ((pos + offset + 4) > len) return -1; anchors.ctl_info = bfd_getb32 (buf + pos + offset); offset += 4; if (anchors.ctl_info > 1024) return -1; offset += anchors.ctl_info * 4; } if (table.flags2 & TB_NAME_PRESENT) { struct traceback_table_routine name; char *namebuf; if ((pos + offset + 2) > len) return -1; name.name_len = bfd_getb16 (buf + pos + offset); offset += 2; if (name.name_len > 4096) return -1; if ((pos + offset + name.name_len) > len) return -1; namebuf = bfd_alloc (abfd, name.name_len + 1); if (namebuf == NULL) return -1; memcpy (namebuf, buf + pos + offset, name.name_len); namebuf[name.name_len] = '\0'; /* Strip leading period inserted by compiler. */ if (namebuf[0] == '.') memmove (namebuf, namebuf + 1, name.name_len + 1); sym->name = namebuf; for (s = sym->name; (*s != '\0'); s++) if (! ISPRINT (*s)) return -1; offset += name.name_len; } if (table.flags2 & TB_USES_ALLOCA) offset += 4; if (table.flags4 & TB_HAS_VEC_INFO) offset += 4; if (file != NULL) fprintf (file, " [length = 0x%lx]", (long) offset); return offset; }
static int loop(const unsigned char *pattern, const unsigned char *string) { loop_state state = CURLFNM_LOOP_DEFAULT; unsigned char *p = (unsigned char *)pattern; unsigned char *s = (unsigned char *)string; unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 }; int rc = 0; for(;;) { switch(state) { case CURLFNM_LOOP_DEFAULT: if(*p == '*') { while(*(p+1) == '*') /* eliminate multiple stars */ p++; if(*s == '\0' && *(p+1) == '\0') return CURL_FNMATCH_MATCH; rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */ if(rc == CURL_FNMATCH_MATCH) return CURL_FNMATCH_MATCH; if(*s) /* let the star eat up one character */ s++; else return CURL_FNMATCH_NOMATCH; } else if(*p == '?') { if(ISPRINT(*s)) { s++; p++; } else if(*s == '\0') return CURL_FNMATCH_NOMATCH; else return CURL_FNMATCH_FAIL; /* cannot deal with other character */ } else if(*p == '\0') { if(*s == '\0') return CURL_FNMATCH_MATCH; else return CURL_FNMATCH_NOMATCH; } else if(*p == '\\') { state = CURLFNM_LOOP_BACKSLASH; p++; } else if(*p == '[') { unsigned char *pp = p+1; /* cannot handle with pointer to register */ if(setcharset(&pp, charset)) { int found = FALSE; if(charset[(unsigned int)*s]) found = TRUE; else if(charset[CURLFNM_ALNUM]) found = ISALNUM(*s); else if(charset[CURLFNM_ALPHA]) found = ISALPHA(*s); else if(charset[CURLFNM_DIGIT]) found = ISDIGIT(*s); else if(charset[CURLFNM_XDIGIT]) found = ISXDIGIT(*s); else if(charset[CURLFNM_PRINT]) found = ISPRINT(*s); else if(charset[CURLFNM_SPACE]) found = ISSPACE(*s); else if(charset[CURLFNM_UPPER]) found = ISUPPER(*s); else if(charset[CURLFNM_LOWER]) found = ISLOWER(*s); else if(charset[CURLFNM_BLANK]) found = ISBLANK(*s); else if(charset[CURLFNM_GRAPH]) found = ISGRAPH(*s); if(charset[CURLFNM_NEGATE]) found = !found; if(found) { p = pp+1; s++; memset(charset, 0, CURLFNM_CHSET_SIZE); } else return CURL_FNMATCH_NOMATCH; } else return CURL_FNMATCH_FAIL; } else { if(*p++ != *s++) return CURL_FNMATCH_NOMATCH; } break; case CURLFNM_LOOP_BACKSLASH: if(ISPRINT(*p)) { if(*p++ == *s++) state = CURLFNM_LOOP_DEFAULT; else return CURL_FNMATCH_NOMATCH; } else return CURL_FNMATCH_FAIL; break; } } }
/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */ static int setcharset(unsigned char **p, unsigned char *charset) { setcharset_state state = CURLFNM_SCHS_DEFAULT; unsigned char rangestart = 0; unsigned char lastchar = 0; bool something_found = FALSE; unsigned char c; for(;;) { c = **p; switch(state) { case CURLFNM_SCHS_DEFAULT: if(ISALNUM(c)) { /* ASCII value */ rangestart = c; charset[c] = 1; (*p)++; state = CURLFNM_SCHS_MAYRANGE; something_found = TRUE; } else if(c == ']') { if(something_found) return SETCHARSET_OK; else something_found = TRUE; state = CURLFNM_SCHS_RIGHTBR; charset[c] = 1; (*p)++; } else if(c == '[') { char c2 = *((*p)+1); if(c2 == ':') { /* there has to be a keyword */ (*p) += 2; if(parsekeyword(p, charset)) { state = CURLFNM_SCHS_DEFAULT; } else return SETCHARSET_FAIL; } else { charset[c] = 1; (*p)++; } something_found = TRUE; } else if(c == '?' || c == '*') { something_found = TRUE; charset[c] = 1; (*p)++; } else if(c == '^' || c == '!') { if(!something_found) { if(charset[CURLFNM_NEGATE]) { charset[c] = 1; something_found = TRUE; } else charset[CURLFNM_NEGATE] = 1; /* negate charset */ } else charset[c] = 1; (*p)++; } else if(c == '\\') { c = *(++(*p)); if(ISPRINT((c))) { something_found = TRUE; state = CURLFNM_SCHS_MAYRANGE; charset[c] = 1; rangestart = c; (*p)++; } else return SETCHARSET_FAIL; } else if(c == '\0') { return SETCHARSET_FAIL; } else { charset[c] = 1; (*p)++; something_found = TRUE; } break; case CURLFNM_SCHS_MAYRANGE: if(c == '-') { charset[c] = 1; (*p)++; lastchar = '-'; state = CURLFNM_SCHS_MAYRANGE2; } else if(c == '[') { state = CURLFNM_SCHS_DEFAULT; } else if(ISALNUM(c)) { charset[c] = 1; (*p)++; } else if(c == '\\') { c = *(++(*p)); if(ISPRINT(c)) { charset[c] = 1; (*p)++; } else return SETCHARSET_FAIL; } else if(c == ']') { return SETCHARSET_OK; } else return SETCHARSET_FAIL; break; case CURLFNM_SCHS_MAYRANGE2: if(c == '\\') { c = *(++(*p)); if(!ISPRINT(c)) return SETCHARSET_FAIL; } if(c == ']') { return SETCHARSET_OK; } else if(c == '\\') { c = *(++(*p)); if(ISPRINT(c)) { charset[c] = 1; state = CURLFNM_SCHS_DEFAULT; (*p)++; } else return SETCHARSET_FAIL; } if(c >= rangestart) { if((ISLOWER(c) && ISLOWER(rangestart)) || (ISDIGIT(c) && ISDIGIT(rangestart)) || (ISUPPER(c) && ISUPPER(rangestart))) { charset[lastchar] = 0; rangestart++; while(rangestart++ <= c) charset[rangestart-1] = 1; (*p)++; state = CURLFNM_SCHS_DEFAULT; } else return SETCHARSET_FAIL; } break; case CURLFNM_SCHS_RIGHTBR: if(c == '[') { state = CURLFNM_SCHS_RIGHTBRLEFTBR; charset[c] = 1; (*p)++; } else if(c == ']') { return SETCHARSET_OK; } else if(c == '\0') { return SETCHARSET_FAIL; } else if(ISPRINT(c)) { charset[c] = 1; (*p)++; state = CURLFNM_SCHS_DEFAULT; } else /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a * nonsense warning 'statement not reached' at end of the fnc when * compiling on Solaris */ goto fail; break; case CURLFNM_SCHS_RIGHTBRLEFTBR: if(c == ']') { return SETCHARSET_OK; } else { state = CURLFNM_SCHS_DEFAULT; charset[c] = 1; (*p)++; } break; } } fail: return SETCHARSET_FAIL; }