static int l_strcmp (const TString *ls, const TString *rs) { const char *l = getstr(ls); size_t ll = ls->tsv.len; const char *r = getstr(rs); size_t lr = rs->tsv.len; for (;;) { int temp = strcoll(l, r); if (temp != 0) return temp; else { /* strings are equal up to a `\0' */ size_t len = strlen(l); /* index of first `\0' in both strings */ if (len == lr) /* r is finished? */ return (len == ll) ? 0 : 1; else if (len == ll) /* l is finished? */ return -1; /* l is smaller than r (because r is not finished) */ /* both strings longer than `len'; go on comparing (after the `\0') */ len++; l += len; ll -= len; r += len; lr -= len; } } return -1; // Suppress warning }
/* ** Compare two strings 'ls' x 'rs', returning an integer smaller-equal- ** -larger than zero if 'ls' is smaller-equal-larger than 'rs'. ** The code is a little tricky because it allows '\0' in the strings ** and it uses 'strcoll' (to respect locales) for each segments ** of the strings. */ static int l_strcmp (const TString *ls, const TString *rs) { const char *l = getstr(ls); size_t ll = tsslen(ls); const char *r = getstr(rs); size_t lr = tsslen(rs); for (;;) { /* for each segment */ int temp = strcoll(l, r); if (temp != 0) /* not equal? */ return temp; /* done */ else { /* strings are equal up to a '\0' */ size_t len = strlen(l); /* index of first '\0' in both strings */ if (len == lr) /* 'rs' is finished? */ return (len == ll) ? 0 : 1; /* check 'ls' */ else if (len == ll) /* 'ls' is finished? */ return -1; /* 'ls' is smaller than 'rs' ('rs' is not finished) */ /* both strings longer than 'len'; go on comparing after the '\0' */ len++; l += len; ll -= len; r += len; lr -= len; } } }
/* * dcomp is the sort function called from qsort(). When comparing * two device entries we sort by alphabetical order of the device's * driver name, then minor number, then block vs. character, then * the name of the device entry itself. */ static int dcomp(const void *p1, const void *p2) { struct devices_ent *dep1 = *((struct devices_ent **)p1); struct devices_ent *dep2 = *((struct devices_ent **)p2); if (dep1->drp->index == dep2->drp->index) { if (dep1->minor == dep2->minor) { if (dep1->israw == dep2->israw) { return (strcoll(dep1->devicename, dep2->devicename)); } else { return (dep1->israw - dep2->israw); } } else { return (dep1->minor - dep2->minor); } } else { return (dep1->drp->index - dep2->drp->index); } }
/* * Compare two characters converting collate information * into ASCII-compatible range, it allows to handle * "[a-z]"-type ranges with national characters. */ static int collate_range_cmp(int c1, int c2) { static char s1[2], s2[2]; int ret; #ifndef ASCII_COMPATIBLE_COLLATE int as1, as2, al1, al2; #endif c1 &= UCHAR_MAX; c2 &= UCHAR_MAX; if (c1 == c2) return (0); #ifndef ASCII_COMPATIBLE_COLLATE as1 = isascii(c1); as2 = isascii(c2); al1 = isalpha(c1); al2 = isalpha(c2); if (as1 || as2 || al1 || al2) { if ((as1 && as2) || (!al1 && !al2)) return (c1 - c2); if (al1 && !al2) { if (isupper(c1)) return ('A' - c2); else return ('a' - c2); } else if (al2 && !al1) { if (isupper(c2)) return (c1 - 'A'); else return (c1 - 'a'); } } #endif s1[0] = c1; s2[0] = c2; if ((ret = strcoll(s1, s2)) != 0) return (ret); return (c1 - c2); }
/* Compare S1 (with length S1LEN) and S2 (with length S2LEN) according to the LC_COLLATE locale. S1 and S2 do not overlap, and are not adjacent. Temporarily modify the bytes after S1 and S2, but restore their original contents before returning. */ int memcoll (char *s1, size_t s1len, char *s2, size_t s2len) { int diff; char n1 = s1[s1len]; char n2 = s2[s2len]; s1[s1len++] = '\0'; s2[s2len++] = '\0'; while (! (diff = strcoll (s1, s2))) { /* strcoll found no difference, but perhaps it was fooled by NUL characters in the data. Work around this problem by advancing past the NUL chars. */ size_t size1 = strlen (s1) + 1; size_t size2 = strlen (s2) + 1; s1 += size1; s2 += size2; s1len -= size1; s2len -= size2; if (s1len == 0) { if (s2len != 0) diff = -1; break; } else if (s2len == 0) { diff = 1; break; } } s1[s1len - 1] = n1; s2[s2len - 1] = n2; return diff; }
int compareStringObjectsWithFlags(robj *a, robj *b, int flags) { redisAssertWithInfo(NULL,a,a->type == REDIS_STRING && b->type == REDIS_STRING); char bufa[128], bufb[128], *astr, *bstr; size_t alen, blen, minlen; if (a == b) return 0; // 指向字符串值,并在有需要时,将整数转换为字符串 a if (sdsEncodedObject(a)) { astr = a->ptr; alen = sdslen(astr); } else { alen = ll2string(bufa,sizeof(bufa),(long) a->ptr); astr = bufa; } // 同样处理字符串 b if (sdsEncodedObject(b)) { bstr = b->ptr; blen = sdslen(bstr); } else { blen = ll2string(bufb,sizeof(bufb),(long) b->ptr); bstr = bufb; } // 对比 if (flags & REDIS_COMPARE_COLL) { return strcoll(astr,bstr); } else { int cmp; minlen = (alen < blen) ? alen : blen; cmp = memcmp(astr,bstr,minlen); if (cmp == 0) return alen-blen; return cmp; } }
int do_test (void) { if (setlocale (LC_COLLATE, "en_GB.UTF-8") == NULL) { puts ("setlocale failed, cannot test for overflow"); return 0; } char *p = malloc (SIZE); if (p == NULL) { puts ("could not allocate memory"); return 1; } memset (p, 'x', SIZE - 1); p[SIZE - 1] = 0; printf ("%d\n", strcoll (p, p)); return 0; }
nsresult nsCollationUnix::CompareString(int32_t strength, const nsAString& string1, const nsAString& string2, int32_t* result) { nsresult res = NS_OK; nsAutoString stringNormalized1, stringNormalized2; if (strength != kCollationCaseSensitive) { res = mCollation->NormalizeString(string1, stringNormalized1); if (NS_FAILED(res)) { return res; } res = mCollation->NormalizeString(string2, stringNormalized2); if (NS_FAILED(res)) { return res; } } else { stringNormalized1 = string1; stringNormalized2 = string2; } // convert unicode to charset char *str1, *str2; res = mCollation->UnicodeToChar(stringNormalized1, &str1); if (NS_SUCCEEDED(res) && str1) { res = mCollation->UnicodeToChar(stringNormalized2, &str2); if (NS_SUCCEEDED(res) && str2) { DoSetLocale(); *result = strcoll(str1, str2); DoRestoreLocale(); PR_Free(str2); } PR_Free(str1); } return res; }
/* sortCompare() is used by qsort in sortCommand(). Given that qsort_r with * the additional parameter is not standard but a BSD-specific we have to * pass sorting parameters via the global 'server' structure */ int sortCompare(const void *s1, const void *s2) { const redisSortObject *so1 = s1, *so2 = s2; int cmp; if (!server.sort_alpha) { /* Numeric sorting. Here it's trivial as we precomputed scores */ if (so1->u.score > so2->u.score) { cmp = 1; } else if (so1->u.score < so2->u.score) { cmp = -1; } else { /* Objects have the same score, but we don't want the comparison * to be undefined, so we compare objects lexicographycally. * This way the result of SORT is deterministic. */ cmp = compareStringObjects(so1->obj,so2->obj); } } else { /* Alphanumeric sorting */ if (server.sort_bypattern) { if (!so1->u.cmpobj || !so2->u.cmpobj) { /* At least one compare object is NULL */ if (so1->u.cmpobj == so2->u.cmpobj) cmp = 0; else if (so1->u.cmpobj == NULL) cmp = -1; else cmp = 1; } else { /* We have both the objects, use strcoll */ cmp = strcoll(so1->u.cmpobj->ptr,so2->u.cmpobj->ptr); } } else { /* Compare elements directly. */ cmp = compareStringObjects(so1->obj,so2->obj); } } return server.sort_desc ? -cmp : cmp; }
int compare_keys(char *buffer_left, char *buffer_right) { int keycmp = 0; int i; char field_left[MAX_FIELD_LEN + 1]; char field_right[MAX_FIELD_LEN + 1]; // printf("inside compare_keys([%s], [%s])\n", buffer_left, buffer_right); if (buffer_left == NULL && buffer_right == NULL) { return LEFT_RIGHT_EQUAL; } /* these special cases may seem counter-intuitive, but saying that a NULL line is greater than a non-NULL line results in the non-NULL line getting printed and a new line read in. */ if (buffer_left == NULL) return LEFT_GREATER; if (buffer_right == NULL) return RIGHT_GREATER; for (i = 0; i < nkeys; i++) { get_line_field(field_left, buffer_left, MAX_FIELD_LEN, keyfields[i], delim); get_line_field(field_right, buffer_right, MAX_FIELD_LEN, keyfields[i], delim); /* printf("Comparing (%s) to (%s) inside compare_keys\n", field_left, field_right); */ if ((keycmp = strcoll(field_left, field_right)) != 0) break; } /* ensure predictable return values */ if (keycmp == 0) return 0; if (keycmp < 0) return -1; if (keycmp > 0) return 1; }
// This takes a name and does a lookup into the ccsid table (from ccsid.h) // to find the corresponding ccsid. It also checks if the string ends in s390 // and returns that information to the caller. // The lookup into the table is done via a binary search since we know that the // table was nicely sorted for us. static int getccsid(const char *s,int * is390) { char tmpstr[_AE_MAX_CODESET_NAME_LENGTH]; int start; int limit; int index; int result; int thelen; // Clean up the name.... if (s == NULL) return -1; if ((thelen = stripNameCopy(s,tmpstr,_AE_MAX_CODESET_NAME_LENGTH-1)) == -1) return -1; // Check for the S390 string in the name *is390 = 0; if ( (strstr((char *)tmpstr, "S390")) != NULL ) *is390 = 1; // Now lookup the name via a binary search start = 0; limit = _AE_NUM_OF_CODESETS; index = limit/2; while ( ((result=strcoll(tmpstr, CCSID_MAPPING[index].NAME)) != 0) && (start < limit-1) ) { if (result < 0) limit = index; else start = index; index = (start+limit)/2; } if (result != 0 && start >= limit-1) return -1; return CCSID_MAPPING[index].CCSID; }
/* * A replacement for * scandir(const char *dir, struct dirent ***namelist, filter, alphasort); * because scandir & alphasort don't exist on Solaris 9. * Return the dirent->d_name that was sorted the highest according to strcoll, * or NULL on error or if no entries matched the filter. * The caller is responsible for freeing the returned string */ char * scan(const char * path) { DIR *dir = NULL; struct dirent * entry = NULL; char * candidate = NULL; if ((dir = opendir(path)) == NULL) { return NULL; } while ((entry = readdir(dir)) != NULL) { if (filter(entry)) { if (candidate == NULL) { candidate = strdup(entry->d_name); } else if (strcoll(candidate, entry->d_name) < 0) { free(candidate); candidate = strdup(entry->d_name); } } } closedir(dir); return candidate; }
//根据flags比较两个字符串对象a和b,返回0表示相等,非零表示不相等 int compareStringObjectsWithFlags(robj *a, robj *b, int flags) { serverAssertWithInfo(NULL,a,a->type == OBJ_STRING && b->type == OBJ_STRING); char bufa[128], bufb[128], *astr, *bstr; size_t alen, blen, minlen; if (a == b) return 0; //如果是同一对象直接返回 //如果是指向字符串值的两种OBJ_ENCODING_EMBSTR或OBJ_ENCODING_RAW的两类对象 if (sdsEncodedObject(a)) { astr = a->ptr; alen = sdslen(astr); //获取字符串的长度 } else { //如果是整数类型的OBJ_ENCODING_INT编码 alen = ll2string(bufa,sizeof(bufa),(long) a->ptr); //转换为字符串 astr = bufa; } //如果是指向字符串值的两种OBJ_ENCODING_EMBSTR或OBJ_ENCODING_RAW的两类对象 if (sdsEncodedObject(b)) { bstr = b->ptr; blen = sdslen(bstr); //获取字符串的长度 } else { //如果是整数类型的OBJ_ENCODING_INT编码 blen = ll2string(bufb,sizeof(bufb),(long) b->ptr); //转换为字符串 bstr = bufb; } //以本地指定的字符次序进行比较 if (flags & REDIS_COMPARE_COLL) { //strcoll()会依环境变量LC_COLLATE所指定的文字排列次序来比较两字符串 return strcoll(astr,bstr); //比较a和b的字符串对象,相等返回0 } else { //以二进制方式进行比较 int cmp; minlen = (alen < blen) ? alen : blen; cmp = memcmp(astr,bstr,minlen); //相等返回0,否则返回第一个字符串和第二个字符串的长度差 if (cmp == 0) return alen-blen; return cmp; } }
int alphasort_ci(const struct dirent **a, const struct dirent **b) { /* * A case insensitive version of alphasort. */ int i; char a_name[512]; char b_name[512]; strncpy(a_name, (*a)->d_name, sizeof(a_name)); strncpy(b_name, (*b)->d_name, sizeof(b_name)); for (i = 0; i < strlen(a_name); i++) { if (a_name[i] >= 'A' && a_name[i] <= 'Z') a_name[i] = a_name[i] - ('A' - 'a'); } for (i = 0; i < strlen(b_name); i++) { if (b_name[i] >= 'A' && b_name[i] <= 'Z') b_name[i] = b_name[i] - ('A' - 'a'); } return strcoll(a_name, b_name); }
static int compare_names (char const *name1, char const *name2) { if (locale_specific_sorting) { int r; errno = 0; if (ignore_file_name_case) r = strcasecoll (name1, name2); else r = strcoll (name1, name2); if (errno) { error (0, errno, _("cannot compare file names `%s' and `%s'"), name1, name2); longjmp (failed_locale_specific_sorting, 1); } return r; } return (ignore_file_name_case ? strcasecmp (name1, name2) : file_name_cmp (name1, name2)); }
int CompareText(const char* str1, const char* str2) { if (!IsEmpty(str1)) if (!IsEmpty(str2)) { char buf1[2], buf2[2]; buf1[1] = buf2[1] = '\0'; int result; do { buf1[0] = tolower(*str1); buf2[0] = tolower(*str2++); result = strcoll(buf1, buf2); } while (*str1++ && (result == 0)); return result; } else return 1; else if (!IsEmpty(str2)) return -1; else return 0; }
static int _LNK_CONV CmpStr(const void *p1, const void *p2) { #else static int CmpStr(const void *p1, const void *p2) { #endif // defined(__IBMCPP__) return strcoll(*(const char **)p1, *(const char **)p2); } /** * Create Sorted list of possible word extensions */ ExComplete::ExComplete(EBuffer *B): ExView() { Buffer = B; Orig = Buffer->CP; WordBegin = NULL; WordFixed = WordPos = WordsLast = 0; Words = new char *[MAXCOMPLETEWORDS + 2]; if (Words != NULL) RefreshComplete(); } ExComplete::~ExComplete() { // fprintf(stderr, "W %p %p %p %d\n", Words, WordContinue, WordBegin, WordsLast); if (WordBegin != NULL) delete[] WordBegin; if (Words != NULL) { for (int i = 0; i < WordsLast; i++) delete[] Words[i]; delete[] Words; } } void ExComplete::Activate(int gotfocus) { ExView::Activate(gotfocus); }
void StringStrcoll(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = strcoll(Param[0]->Val->Pointer, Param[1]->Val->Pointer); }
/* Compare S1 (with length S1LEN) and S2 (with length S2LEN) according to the LC_COLLATE locale. S1 and S2 do not overlap, and are not adjacent. Perhaps temporarily modify the bytes after S1 and S2, but restore their original contents before returning. Set errno to an error number if there is an error, and to zero otherwise. */ int memcoll (char *s1, size_t s1len, char *s2, size_t s2len) { int diff; #if HAVE_STRCOLL /* strcoll is slow on many platforms, so check for the common case where the arguments are bytewise equal. Otherwise, walk through the buffers using strcoll on each substring. */ if (s1len == s2len && memcmp (s1, s2, s1len) == 0) { errno = 0; diff = 0; } else { char n1 = s1[s1len]; char n2 = s2[s2len]; s1[s1len++] = '\0'; s2[s2len++] = '\0'; while (! (errno = 0, (diff = strcoll (s1, s2)) || errno)) { /* strcoll found no difference, but perhaps it was fooled by NUL characters in the data. Work around this problem by advancing past the NUL chars. */ size_t size1 = strlen (s1) + 1; size_t size2 = strlen (s2) + 1; s1 += size1; s2 += size2; s1len -= size1; s2len -= size2; if (s1len == 0) { if (s2len != 0) diff = -1; break; } else if (s2len == 0) { diff = 1; break; } } s1[s1len - 1] = n1; s2[s2len - 1] = n2; } #else diff = memcmp (s1, s2, s1len < s2len ? s1len : s2len); if (! diff) diff = s1len < s2len ? -1 : s1len != s2len; errno = 0; #endif return diff; }
static struct bstr strip_ext(struct bstr str) { int dotpos = bstrrchr(str, '.'); if (dotpos < 0) return str; return (struct bstr){str.start, dotpos}; } static struct bstr get_ext(struct bstr s) { int dotpos = bstrrchr(s, '.'); if (dotpos < 0) return (struct bstr){NULL, 0}; return bstr_splice(s, dotpos + 1, s.len); } bool mp_might_be_subtitle_file(const char *filename) { return test_ext(get_ext(bstr0(filename))) == STREAM_SUB; } static int compare_sub_filename(const void *a, const void *b) { const struct subfn *s1 = a; const struct subfn *s2 = b; return strcoll(s1->fname, s2->fname); } static int compare_sub_priority(const void *a, const void *b) { const struct subfn *s1 = a; const struct subfn *s2 = b; if (s1->priority > s2->priority) return -1; if (s1->priority < s2->priority) return 1; return strcoll(s1->fname, s2->fname); } static struct bstr guess_lang_from_filename(struct bstr name) { if (name.len < 2) return (struct bstr){NULL, 0}; int n = 0; int i = name.len - 1; if (name.start[i] == ')' || name.start[i] == ']') i--; while (i >= 0 && mp_isalpha(name.start[i])) { n++; if (n > 3) return (struct bstr){NULL, 0}; i--; } if (n < 2) return (struct bstr){NULL, 0}; return (struct bstr){name.start + i + 1, n}; } static void append_dir_subtitles(struct mpv_global *global, struct subfn **slist, int *nsub, struct bstr path, const char *fname, int limit_fuzziness) { void *tmpmem = talloc_new(NULL); struct MPOpts *opts = global->opts; struct mp_log *log = mp_log_new(tmpmem, global->log, "find_files"); if (mp_is_url(bstr0(fname))) goto out; struct bstr f_fname = bstr0(mp_basename(fname)); struct bstr f_fname_noext = bstrdup(tmpmem, strip_ext(f_fname)); bstr_lower(f_fname_noext); struct bstr f_fname_trim = bstr_strip(f_fname_noext); // 0 = nothing // 1 = any subtitle file // 2 = any sub file containing movie name // 3 = sub file containing movie name and the lang extension char *path0 = bstrdup0(tmpmem, path); DIR *d = opendir(path0); if (!d) goto out; mp_verbose(log, "Loading external files in %.*s\n", BSTR_P(path)); struct dirent *de; while ((de = readdir(d))) { struct bstr dename = bstr0(de->d_name); void *tmpmem2 = talloc_new(tmpmem); // retrieve various parts of the filename struct bstr tmp_fname_noext = bstrdup(tmpmem2, strip_ext(dename)); bstr_lower(tmp_fname_noext); struct bstr tmp_fname_ext = get_ext(dename); struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext); // check what it is (most likely) int type = test_ext(tmp_fname_ext); char **langs = NULL; int fuzz = -1; switch (type) { case STREAM_SUB: langs = opts->sub_lang; fuzz = opts->sub_auto; break; case STREAM_AUDIO: langs = opts->audio_lang; fuzz = opts->audiofile_auto; break; } if (fuzz < 0) goto next_sub; // we have a (likely) subtitle file int prio = 0; char *found_lang = NULL; if (langs) { if (bstr_startswith(tmp_fname_trim, f_fname_trim)) { struct bstr lang = guess_lang_from_filename(tmp_fname_trim); if (lang.len) { for (int n = 0; langs[n]; n++) { if (bstr_startswith0(lang, langs[n])) { prio = 4; // matches the movie name + lang extension found_lang = langs[n]; break; } } } } } if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0) prio = 3; // matches the movie name if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && fuzz >= 1) prio = 2; // contains the movie name if (!prio) { // doesn't contain the movie name // don't try in the mplayer subtitle directory if (!limit_fuzziness && fuzz >= 2) { prio = 1; } } mp_dbg(log, "Potential external file: \"%s\" Priority: %d\n", de->d_name, prio); if (prio) { prio += prio; char *subpath = mp_path_join(*slist, path, dename); if (mp_path_exists(subpath)) { MP_GROW_ARRAY(*slist, *nsub); struct subfn *sub = *slist + (*nsub)++; // annoying and redundant if (strncmp(subpath, "./", 2) == 0) subpath += 2; sub->type = type; sub->priority = prio; sub->fname = subpath; sub->lang = found_lang; } else talloc_free(subpath); } next_sub: talloc_free(tmpmem2); } closedir(d); out: talloc_free(tmpmem); } static bool case_endswith(const char *s, const char *end) { size_t len = strlen(s); size_t elen = strlen(end); return len >= elen && strcasecmp(s + len - elen, end) == 0; } // Drop .sub file if .idx file exists. // Assumes slist is sorted by compare_sub_filename. static void filter_subidx(struct subfn **slist, int *nsub) { const char *prev = NULL; for (int n = 0; n < *nsub; n++) { const char *fname = (*slist)[n].fname; if (case_endswith(fname, ".idx")) { prev = fname; } else if (case_endswith(fname, ".sub")) { if (prev && strncmp(prev, fname, strlen(fname) - 4) == 0) (*slist)[n].priority = -1; } } for (int n = *nsub - 1; n >= 0; n--) { if ((*slist)[n].priority < 0) MP_TARRAY_REMOVE_AT(*slist, *nsub, n); } } // Return a list of subtitles and audio files found, sorted by priority. // Last element is terminated with a fname==NULL entry. struct subfn *find_external_files(struct mpv_global *global, const char *fname) { struct MPOpts *opts = global->opts; struct subfn *slist = talloc_array_ptrtype(NULL, slist, 1); int n = 0; // Load subtitles from current media directory append_dir_subtitles(global, &slist, &n, mp_dirname(fname), fname, 0); if (opts->sub_auto >= 0) { // Load subtitles in dirs specified by sub-paths option if (opts->sub_paths) { for (int i = 0; opts->sub_paths[i]; i++) { char *path = mp_path_join(slist, mp_dirname(fname), bstr0(opts->sub_paths[i])); append_dir_subtitles(global, &slist, &n, bstr0(path), fname, 0); } } // Load subtitles in ~/.mpv/sub limiting sub fuzziness char *mp_subdir = mp_find_config_file(NULL, global, "sub/"); if (mp_subdir) append_dir_subtitles(global, &slist, &n, bstr0(mp_subdir), fname, 1); talloc_free(mp_subdir); } // Sort by name for filter_subidx() qsort(slist, n, sizeof(*slist), compare_sub_filename); filter_subidx(&slist, &n); // Sort subs by priority and append them qsort(slist, n, sizeof(*slist), compare_sub_priority); struct subfn z = {0}; MP_TARRAY_APPEND(NULL, slist, n, z); return slist; }
/* Used by qsort to sort filelist */ static int compar(const void *p, const void *q) { return strcoll(*((char **) p), *((char **) q)); }
/* Parse and evaluate comparison expressions */ struct val * eval2(void) { struct val *l, *r; enum token op; int v = 0, li, ri; l = eval3(); while ((op = token) == EQ || op == NE || op == LT || op == GT || op == LE || op == GE) { nexttoken(0); r = eval3(); if (is_integer(l, &li) && is_integer(r, &ri)) { switch (op) { case GT: v = (li > ri); break; case GE: v = (li >= ri); break; case LT: v = (li < ri); break; case LE: v = (li <= ri); break; case EQ: v = (li == ri); break; case NE: v = (li != ri); break; default: break; } } else { to_string(l); to_string(r); switch (op) { case GT: v = (strcoll(l->u.s, r->u.s) > 0); break; case GE: v = (strcoll(l->u.s, r->u.s) >= 0); break; case LT: v = (strcoll(l->u.s, r->u.s) < 0); break; case LE: v = (strcoll(l->u.s, r->u.s) <= 0); break; case EQ: v = (strcoll(l->u.s, r->u.s) == 0); break; case NE: v = (strcoll(l->u.s, r->u.s) != 0); break; default: break; } } free_value(l); free_value(r); l = make_int(v); } return l; }
static int ncmp(const void *_ri1, const void *_ri2) { const struct rangeinfo *ri1 = _ri1, *ri2 = _ri2; return( strcoll(_(ri1->range->name),_(ri2->range->name))); }
int alphasort(const void *_a, const void *_b){ return strcoll((*(const struct dirent **)_a)->d_name, (*(const struct dirent **)_b)->d_name); }
int alphasort (const struct dirent **a, const struct dirent **b) { return strcoll ((*a)->d_name, (*b)->d_name); }
void nullpointer(int value) { int res = 0; FILE *fp; // cppcheck-suppress nullPointer clearerr(0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer feof(0); // cppcheck-suppress nullPointer fgetc(0); // cppcheck-suppress nullPointer fclose(0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer ferror(0); // cppcheck-suppress nullPointer ftell(0); // cppcheck-suppress nullPointer puts(0); // cppcheck-suppress nullPointer fp=fopen(0,0); fclose(fp); fp = 0; // No FP fflush(0); // No FP // cppcheck-suppress redundantAssignment fp = freopen(0,"abc",stdin); fclose(fp); fp = 0; // cppcheck-suppress nullPointer fputc(0,0); // cppcheck-suppress nullPointer fputs(0,0); // cppcheck-suppress nullPointer fgetpos(0,0); // cppcheck-suppress nullPointer frexp(1.0,0); // cppcheck-suppress nullPointer fsetpos(0,0); // cppcheck-suppress nullPointer itoa(123,0,10); putchar(0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strchr(0,0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strlen(0); // cppcheck-suppress nullPointer strcpy(0,0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strspn(0,0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strcspn(0,0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strcoll(0,0); // cppcheck-suppress nullPointer strcat(0,0); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strcmp(0,0); // cppcheck-suppress nullPointer strncpy(0,0,1); // cppcheck-suppress nullPointer strncat(0,0,1); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strncmp(0,0,1); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress nullPointer strstr(0,0); // cppcheck-suppress nullPointer strtoul(0,0,0); // cppcheck-suppress nullPointer strtoull(0,0,0); // cppcheck-suppress nullPointer strtol(0,0,0); // #6100 False positive nullPointer - calling mbstowcs(NULL,) res += mbstowcs(0,"",0); // cppcheck-suppress unreadVariable res += wcstombs(0,L"",0); strtok(NULL,"xyz"); strxfrm(0,"foo",0); // TODO: error message strxfrm(0,"foo",42); snprintf(NULL, 0, "someformatstring"); // legal // cppcheck-suppress nullPointer snprintf(NULL, 42, "someformatstring"); // not legal }
int __collate_range_cmp(int c1, int c2) { static char s1[2], s2[2]; s1[0] = c1; s2[0] = c2; return (strcoll(s1, s2)); }
/* * find_compare -- * tell fts_open() how to order the traversal of the hierarchy. * This variant gives lexicographical order, i.e., alphabetical * order within each directory. */ static int find_compare(const FTSENT * const *s1, const FTSENT * const *s2) { return (strcoll((*s1)->fts_name, (*s2)->fts_name)); }
int main(void) { puts("string"); char *c = "a123456789abbbaccca"; char *p; p = index(c, '1'); printf("%s\n", p); p = index(c, 'y'); if (p == NULL) { printf("no found \n"); } p = index(c, 'a'); printf("%s\n", p); printf("\n\nloop...\n\n"); p = c; while ((p = index(p, 'a')) != NULL) { printf("%s\n", p); p++; } puts("memchr"); p = memchr(c, '9', 8); // 8 个字节前面有没有 '9' printf("memchr %s\n", p); puts("memcmp"); char *x = "abcdef"; char *y = "aBcdEf"; int z = memcmp((void *) x, (void *) y, 3); printf("memcmp(x,y) : %d\n", z); z = memcmp(x, y, 3); printf("memcmp(x,y) : %d\n", z); z = strcasecmp(x, y); printf("strcasecmp(x,y) : %d\n", z); z = strcmp(x, y); printf("strcmp(x,y) : %d\n", z); z = strcoll(x, y); printf("strcoll(x,y) : %d\n", z); //根据环境变量LC_COLLATE指定的文字排列顺序来对比 char ww[40] = "www.goolge.com"; char yy[] = "->android"; char *result = strcat(ww,yy); printf("result : %s\n", result); char *c1 = "a123456789abbbaccca"; char *p1; p1 = strchr(c1,'b'); printf("strchr result : %s\n", p1); return EXIT_SUCCESS; }
static struct bstr strip_ext(struct bstr str) { int dotpos = bstrrchr(str, '.'); if (dotpos < 0) return str; return (struct bstr){str.start, dotpos}; } static struct bstr get_ext(struct bstr s) { int dotpos = bstrrchr(s, '.'); if (dotpos < 0) return (struct bstr){NULL, 0}; return bstr_splice(s, dotpos + 1, s.len); } struct subfn { int priority; char *fname; }; static int compare_sub_priority(const void *a, const void *b) { const struct subfn *s1 = a; const struct subfn *s2 = b; if (s1->priority > s2->priority) return -1; if (s1->priority < s2->priority) return 1; return strcoll(s1->fname, s2->fname); } static struct bstr guess_lang_from_filename(struct bstr name) { if (name.len < 2) return (struct bstr){NULL, 0}; int n = 0; int i = name.len - 1; if (name.start[i] == ')' || name.start[i] == ']') i--; while (i >= 0 && isalpha(name.start[i])) { n++; if (n > 3) return (struct bstr){NULL, 0}; i--; } if (n < 2) return (struct bstr){NULL, 0}; return (struct bstr){name.start + i + 1, n}; } struct sub_list { struct subfn subs[MAX_SUBTITLE_FILES]; int sid; void *ctx; }; /** * @brief Append all the subtitles in the given path matching fname * @param opts MPlayer options * @param slist pointer to the subtitles list tallocated * @param nsub pointer to the number of subtitles * @param path Look for subtitles in this directory * @param fname Subtitle filename (pattern) * @param limit_fuzziness Ignore flag when sub_fuziness == 2 */ static void append_dir_subtitles(struct MPOpts *opts, struct subfn **slist, int *nsub, struct bstr path, const char *fname, int limit_fuzziness) { char *sub_exts[] = {"utf", "utf8", "utf-8", "sub", "srt", "smi", "rt", "txt", "ssa", "aqt", "jss", "js", "ass", NULL}; void *tmpmem = talloc_new(NULL); FILE *f; assert(strlen(fname) < 1e6); struct bstr f_fname = bstr0(mp_basename(fname)); struct bstr f_fname_noext = bstrdup(tmpmem, strip_ext(f_fname)); bstr_lower(f_fname_noext); struct bstr f_fname_trim = bstr_strip(f_fname_noext); // 0 = nothing // 1 = any subtitle file // 2 = any sub file containing movie name // 3 = sub file containing movie name and the lang extension char *path0 = bstrdup0(tmpmem, path); DIR *d = opendir(path0); if (!d) goto out; mp_msg(MSGT_SUBREADER, MSGL_V, "Load subtitles in %.*s\n", BSTR_P(path)); struct dirent *de; while ((de = readdir(d))) { struct bstr dename = bstr0(de->d_name); void *tmpmem2 = talloc_new(tmpmem); // retrieve various parts of the filename struct bstr tmp_fname_noext = bstrdup(tmpmem2, strip_ext(dename)); bstr_lower(tmp_fname_noext); struct bstr tmp_fname_ext = get_ext(dename); struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext); // If it's a .sub, check if there is a .idx with the same name. If // there is one, it's certainly a vobsub so we skip it. if (bstrcasecmp(tmp_fname_ext, bstr0("sub")) == 0) { char *idxname = talloc_asprintf(tmpmem2, "%.*s.idx", (int)tmp_fname_noext.len, de->d_name); char *idx = mp_path_join(tmpmem2, path, bstr0(idxname)); f = fopen(idx, "rt"); if (f) { fclose(f); goto next_sub; } } // does it end with a subtitle extension? #ifdef CONFIG_ICONV #ifdef CONFIG_ENCA int i = (sub_cp && strncasecmp(sub_cp, "enca", 4) != 0) ? 3 : 0; #else int i = sub_cp ? 3 : 0; #endif #else int i = 0; #endif while (1) { if (!sub_exts[i]) goto next_sub; if (bstrcasecmp(bstr0(sub_exts[i]), tmp_fname_ext) == 0) break; i++; } // we have a (likely) subtitle file int prio = 0; if (opts->sub_lang) { if (bstr_startswith(tmp_fname_trim, f_fname_trim)) { struct bstr lang = guess_lang_from_filename(tmp_fname_trim); if (lang.len) { for (int n = 0; opts->sub_lang[n]; n++) { if (bstr_startswith(lang, bstr0(opts->sub_lang[n]))) { prio = 4; // matches the movie name + lang extension break; } } } } } if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0) prio = 3; // matches the movie name if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && sub_match_fuzziness >= 1) prio = 2; // contains the movie name if (!prio) { // doesn't contain the movie name // don't try in the mplayer subtitle directory if (!limit_fuzziness && sub_match_fuzziness >= 2) { prio = 1; } } mp_msg(MSGT_SUBREADER, MSGL_DBG2, "Potential sub file: " "\"%s\" Priority: %d\n", de->d_name, prio); if (prio) { prio += prio; #ifdef CONFIG_ICONV if (i < 3) // prefer UTF-8 coded prio++; #endif char *subpath = mp_path_join(*slist, path, dename); if ((f = fopen(subpath, "rt"))) { MP_GROW_ARRAY(*slist, *nsub); struct subfn *sub = *slist + (*nsub)++; fclose(f); sub->priority = prio; sub->fname = subpath; } else talloc_free(subpath); } next_sub: talloc_free(tmpmem2); } closedir(d); out: talloc_free(tmpmem); } char **find_text_subtitles(struct MPOpts *opts, const char *fname) { char **subnames = NULL; struct subfn *slist = talloc_array_ptrtype(NULL, slist, 1); int n = 0; // Load subtitles from current media directory append_dir_subtitles(opts, &slist, &n, mp_dirname(fname), fname, 0); // Load subtitles in dirs specified by sub-paths option if (opts->sub_paths) { for (int i = 0; opts->sub_paths[i]; i++) { char *path = mp_path_join(slist, mp_dirname(fname), bstr0(opts->sub_paths[i])); append_dir_subtitles(opts, &slist, &n, bstr0(path), fname, 0); } } // Load subtitles in ~/.mplayer/sub limiting sub fuzziness char *mp_subdir = get_path("sub/"); if (mp_subdir) append_dir_subtitles(opts, &slist, &n, bstr0(mp_subdir), fname, 1); free(mp_subdir); // Sort subs by priority and append them qsort(slist, n, sizeof(*slist), compare_sub_priority); subnames = talloc_array_ptrtype(NULL, subnames, n); for (int i = 0; i < n; i++) subnames[i] = talloc_strdup(subnames, slist[i].fname); talloc_free(slist); return subnames; } char **find_vob_subtitles(struct MPOpts *opts, const char *fname) { char **vobs = talloc_array_ptrtype(NULL, vobs, 1); int n = 0; // Potential vobsub in the media directory struct bstr bname = bstr0(mp_basename(fname)); int pdot = bstrrchr(bname, '.'); if (pdot >= 0) bname.len = pdot; vobs[n++] = mp_path_join(vobs, mp_dirname(fname), bname); // Potential vobsubs in directories specified by sub-paths option if (opts->sub_paths) { for (int i = 0; opts->sub_paths[i]; i++) { char *path = mp_path_join(NULL, mp_dirname(fname), bstr0(opts->sub_paths[i])); MP_GROW_ARRAY(vobs, n); vobs[n++] = mp_path_join(vobs, bstr0(path), bname); talloc_free(path); } } // Potential vobsub in ~/.mplayer/sub char *mp_subdir = get_path("sub/"); if (mp_subdir) { MP_GROW_ARRAY(vobs, n); vobs[n++] = mp_path_join(vobs, bstr0(mp_subdir), bname); } free(mp_subdir); MP_RESIZE_ARRAY(NULL, vobs, n); return vobs; }