From f98b260025255891e5d2b20df2ee89dcc50bb368 Mon Sep 17 00:00:00 2001 From: ketmar Date: Tue, 30 Jul 2013 09:06:28 +0000 Subject: [PATCH] tagscan now tries to preserve short names on updates FossilOrigin-Name: 25dcb308952b1e79ff0ec5889423910224b5470d9f0f5b8b38e780657121449d --- src/tagscan.c | 235 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 128 insertions(+), 107 deletions(-) diff --git a/src/tagscan.c b/src/tagscan.c index 9d8f680..692de7f 100644 --- a/src/tagscan.c +++ b/src/tagscan.c @@ -841,128 +841,139 @@ static void fileinfo_postprocess (void) { for (fileinfo_t *fi = filelist; fi != NULL; fi = fi->hh.next) { //fileinfo_t *oldfi; string_t *snv; - const char *onamep = strrchr(fi->realname->str, '/')+1; // this CAN'T fail! - const char *oext = strrchr(onamep, '.'); - char *trs, *tmp = NULL; - fi->idx = cur_fileinfo_idx++; - if (oext == onamep) { fprintf(stderr, "strangely named file: '%s'\n", fi->realname->str); } - if (strcmp(fi->title_t->value->str, UNDEF_TITLE_T) != 0) { - // generate from title - //fprintf(stderr, "t: [%s]\n", fi->title_t->value->str); - tmp = malloc(strlen(fi->title_t->value->str)+(oext != NULL ? strlen(oext) : 0)+32); - if (fi->tracknum == 0) { - int trno = 0; - if (leIsDigit(onamep[0])) { - trno = onamep[0]-'0'; - if (leIsDigit(onamep[1])) { - trno = trno*10+onamep[1]-'0'; - if (leIsDigit(onamep[2])) { - trno = 0; + if (fi->shortname == NULL) { + // generate short name + const char *onamep = strrchr(fi->realname->str, '/')+1; // this CAN'T fail! + const char *oext = strrchr(onamep, '.'); + char *trs, *tmp = NULL; + fi->idx = cur_fileinfo_idx++; + if (oext == onamep) { fprintf(stderr, "strangely named file: '%s'\n", fi->realname->str); } + if (strcmp(fi->title_t->value->str, UNDEF_TITLE_T) != 0) { + // generate from title + //fprintf(stderr, "t: [%s]\n", fi->title_t->value->str); + tmp = malloc(strlen(fi->title_t->value->str)+(oext != NULL ? strlen(oext) : 0)+32); + if (fi->tracknum == 0) { + int trno = 0; + if (leIsDigit(onamep[0])) { + trno = onamep[0]-'0'; + if (leIsDigit(onamep[1])) { + trno = trno*10+onamep[1]-'0'; + if (leIsDigit(onamep[2])) { + trno = 0; + } } } - } - if (trno == 0) { - sprintf(tmp, "%s%s", fi->title_t->value->str, (oext != NULL ? oext : "")); + if (trno == 0) { + sprintf(tmp, "%s%s", fi->title_t->value->str, (oext != NULL ? oext : "")); + } else { + sprintf(tmp, "%02d_%s%s", trno, fi->title_t->value->str, (oext != NULL ? oext : "")); + } } else { - sprintf(tmp, "%02d_%s%s", trno, fi->title_t->value->str, (oext != NULL ? oext : "")); + sprintf(tmp, "%02u_%s%s", fi->tracknum, fi->title_t->value->str, (oext != NULL ? oext : "")); } + //fprintf(stderr, "generated: [%s] : [%s]\n", onamep, tmp); + // in koi } else { - sprintf(tmp, "%02u_%s%s", fi->tracknum, fi->title_t->value->str, (oext != NULL ? oext : "")); - } - //fprintf(stderr, "generated: [%s] : [%s]\n", onamep, tmp); - // in koi - } else { - // transliterate utf-8 or koi - //fprintf(stderr, "dt: [%s]\n", fi->title_t->value->str); - if (is_possible_utf8(onamep)) { - if (is_valid_utf8(onamep)) { - // convert to koi-8 - tmp = str_tokoi(onamep); - if (tmp == NULL) { fprintf(stderr, "FATAL: fileinfo_postprocess() failed to convert encoding!\n"); abort(); } + // transliterate utf-8 or koi + //fprintf(stderr, "dt: [%s]\n", fi->title_t->value->str); + if (is_possible_utf8(onamep)) { + if (is_valid_utf8(onamep)) { + // convert to koi-8 + tmp = str_tokoi(onamep); + if (tmp == NULL) { fprintf(stderr, "FATAL: fileinfo_postprocess() failed to convert encoding!\n"); abort(); } + } } + if (tmp == NULL) tmp = strdup(onamep); } - if (tmp == NULL) tmp = strdup(onamep); - } - // normalize - if (oext != NULL) strrchr(tmp, '.')[0] = 0; - if (!tmp[0]) { fprintf(stderr, "VERY strangely named file: '%s'\n", fi->realname->str); } - trs = str_transliterate(tmp, 1); - trimstr(trs); - if (oext != NULL) { - //fprintf(stderr, "tmp=%p; trs=%p; oext=%p\n", tmp, trs, oext); - tmp = realloc(tmp, strlen(trs)+strlen(oext)+4); - sprintf(tmp, "%s%s", trs, oext); - for (char *s = tmp+strlen(trs); *s; ++s) *s = le2lower(*s); - free(trs); - trs = tmp; - } - /* - // fuck all nonalnums, convert to lowercase - for (unsigned char *s = (unsigned char *)trs; *s; ++s) { - if (*s == 127 || (*s < 128 || !leIsAlNum(*s))) *s = '_'; - *s = le2lower(*s); - } - */ - // trim and normalize name - //trimstr(trs); - // add extension back - //if (oext != NULL) strcat(trs, oext); - // add track number if any - if (fi->tracknum > 0) { - int tno = 0; - if (leIsDigit(*trs)) { - // starts with digit, parse number - for (const char *t = trs; *t && leIsDigit(*t); ++t) { - tno = tno*10+t[0]-'0'; - if (tno > 255 || t-trs > 2) break; // alas, this is definitely not a track number + // normalize + if (oext != NULL) strrchr(tmp, '.')[0] = 0; + if (!tmp[0]) { fprintf(stderr, "VERY strangely named file: '%s'\n", fi->realname->str); } + trs = str_transliterate(tmp, 1); + trimstr(trs); + if (oext != NULL) { + //fprintf(stderr, "tmp=%p; trs=%p; oext=%p\n", tmp, trs, oext); + tmp = realloc(tmp, strlen(trs)+strlen(oext)+4); + sprintf(tmp, "%s%s", trs, oext); + for (char *s = tmp+strlen(trs); *s; ++s) *s = le2lower(*s); + free(trs); + trs = tmp; + } + /* + // fuck all nonalnums, convert to lowercase + for (unsigned char *s = (unsigned char *)trs; *s; ++s) { + if (*s == 127 || (*s < 128 || !leIsAlNum(*s))) *s = '_'; + *s = le2lower(*s); + } + */ + // trim and normalize name + //trimstr(trs); + // add extension back + //if (oext != NULL) strcat(trs, oext); + // add track number if any + if (fi->tracknum > 0) { + int tno = 0; + if (leIsDigit(*trs)) { + // starts with digit, parse number + for (const char *t = trs; *t && leIsDigit(*t); ++t) { + tno = tno*10+t[0]-'0'; + if (tno > 255 || t-trs > 2) break; // alas, this is definitely not a track number + } + } + if (tno != fi->tracknum) { + // there is no track number, let's add it + char *nn = malloc(strlen(trs)+8); + sprintf(nn, "%02u_%s", fi->tracknum, trs); + free(trs); + trs = nn; } } - if (tno != fi->tracknum) { - // there is no track number, let's add it - char *nn = malloc(strlen(trs)+8); - sprintf(nn, "%02u_%s", fi->tracknum, trs); + // + if (trs[0] == '.') { + char *n = malloc(strlen(trs)+4); + sprintf(n, "_%s", trs); free(trs); - trs = nn; + trs = n; } - } - // - if (trs[0] == '.') { - char *n = malloc(strlen(trs)+4); - sprintf(n, "_%s", trs); - free(trs); - trs = n; - } - // - if ((snv = cstring_find(trs)) != NULL) { - // this name can be is taken, check it better and generate new one - fileinfo_t *xf; - // first check if this name is really taken - HASH_FIND_STR_EX(hh_sname, snhash, trs, xf); - if (xf != NULL) { - // yes, the name is really taken, let's generate new one - char *newname = malloc(strlen(trs)+(oext != NULL ? strlen(oext) : 0)+16); - char *ext = strrchr(trs, '.'); // all dots except the last one are annihilated here - int cnt; - if (ext != NULL) *ext = 0; // remove extension - for (cnt = 1; cnt < 1000000; ++cnt) { - sprintf(newname, "%s_%d%s", trs, cnt, (oext != NULL ? oext : "")); - HASH_FIND_STR_EX(hh_sname, snhash, newname, xf); - if (xf == NULL) break; // found free name + // + if ((snv = cstring_find(trs)) != NULL) { + // this name can be is taken, check it better and generate new one + fileinfo_t *xf; + // first check if this name is really taken + HASH_FIND_STR_EX(hh_sname, snhash, trs, xf); + if (xf != NULL) { + // yes, the name is really taken, let's generate new one + char *newname = malloc(strlen(trs)+(oext != NULL ? strlen(oext) : 0)+16); + char *ext = strrchr(trs, '.'); // all dots except the last one are annihilated here + int cnt; + if (ext != NULL) *ext = 0; // remove extension + for (cnt = 1; cnt < 1000000; ++cnt) { + sprintf(newname, "%s_%d%s", trs, cnt, (oext != NULL ? oext : "")); + HASH_FIND_STR_EX(hh_sname, snhash, newname, xf); + if (xf == NULL) break; // found free name + } + if (cnt >= 1000000) { fprintf(stderr, "FATAL: too many files with the same name in fileinfo_postprocess()!\n"); abort(); } + //fprintf(stderr, "renamed: [%s%s] -> [%s]\n", trs, (oext != NULL ? oext : ""), newname); + free(trs); + trs = newname; + snv = cstring_add(trs); } - if (cnt >= 1000000) { fprintf(stderr, "FATAL: too many files with the same name in fileinfo_postprocess()!\n"); abort(); } - //fprintf(stderr, "renamed: [%s%s] -> [%s]\n", trs, (oext != NULL ? oext : ""), newname); - free(trs); - trs = newname; + // if the name is not taken, snv is correct here + } else { + // this name is surely free, use it snv = cstring_add(trs); } - // if the name is not taken, snv is correct here + // set short name + fi->shortname = snv; + fi->snamestr = snv->str; } else { - // this name is surely free, use it - snv = cstring_add(trs); + // we already have short name for this file, wow! + // heh, do nothing except sanity check + fileinfo_t *xf; + // + snv = fi->shortname; + HASH_FIND_STR_EX(hh_sname, snhash, snv->str, xf); + if (xf != NULL) { fprintf(stderr, "FATAL: duplicate preserved short name!\n"); abort(); } } - // set short name - fi->shortname = snv; - fi->snamestr = snv->str; HASH_ADD_KEYPTR(hh_sname, snhash, fi->snamestr, strlen(fi->snamestr), fi); //fprintf(stderr, "[%s] -> [%s]\n", onamep, fi->shortname->str); } @@ -1068,7 +1079,6 @@ static int fill_tags (const char *filename) { unsigned int yy = taglib_tag_year(tag); unsigned int tno = taglib_tag_track(tag); // - // if (!dotest) goto doutf8; if (notutf(artist) || notutf(album) || @@ -1368,6 +1378,8 @@ error: static void ts_build_hashes (void) { clock_t stt; int was_report = 0; + fileinfo_t *snhash = NULL, *xf; // 'shortname' hash (sanity check) + string_t *snv; mtagvalue_t *add_tag (fileinfo_t *fi, uint32_t tagidx, int tflidx) { static const char *defval[TFL_MAX] = { @@ -1444,6 +1456,14 @@ do_other: fi = fileinfo_find(fname); if (fi != NULL) { fprintf(stderr, "FATAL: internal error 201!\n"); abort(); } fi = fileinfo_add(fname); + // + snv = cstring_add(get_str(tfi->shortname)); + fi->snamestr = snv->str; + HASH_FIND_STR_EX(hh_sname, snhash, snv->str, xf); + if (xf != NULL) { fprintf(stderr, "FATAL: tagdb file corrupted (duplicate shortname found!\n"); abort(); } + fi->shortname = snv; + HASH_ADD_KEYPTR(hh_sname, snhash, fi->snamestr, strlen(fi->snamestr), fi); + // fi->di.dev = tfi->devid; fi->di.node = tfi->inode; fi->devid = tfi->devid; @@ -1472,6 +1492,7 @@ do_other: } } } + HASH_CLEAR(hh_sname, snhash); // don't need it anymore if (was_report) fprintf(stdout, "\r[%u/%u] files processed\n", file_count, file_count); tagdb_unload(); printf("%d files, %d strings, %d tags (%d normal, %d transliterated).\n", HASH_COUNT(filelist), HASH_COUNT(strings), HASH_COUNT(taglist), HASH_CNT(hh_o, tagolist), HASH_CNT(hh_t, tagtlist)); -- 2.11.4.GIT