2015-03-19 02:01:23 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
Basic search functionality.
diff --git a/srtsync.c b/srtsync.c index b617be9..ec1be4f 100644 --- a/srtsync.c +++ b/srtsync.c @@ -28,6 +28,14 @@ ts2ms(const char *ts) return ms; } +uint32_t +partial2ms(const char *partial) +{ + char buffer[] = "00:00:00,000"; + strcpy(buffer + sizeof(buffer) - strlen(partial) - 1, partial); + return ts2ms(buffer); +} + void ms2ts(char *buffer, size_t bufsiz, uint32_t ms) { @@ -79,7 +87,7 @@ load_subs(FILE *fp) strcpy(line.text, text); /* Add line to subtitles. */ if (subs->count == subs->bulk) { - subs->bulk += subs->bulk >> 1; + subs->bulk += subs->bulk / 2; subs->lines = realloc(subs->lines, subs->bulk * sizeof(*subs->lines)); } subs->lines[subs->count++] = line; @@ -88,18 +96,27 @@ load_subs(FILE *fp) } void -save_subs(FILE *fp, Subtitles *subs) +print_line(FILE *fp, Subtitles *subs, int index) { + Line *line; char bufon[13], bufoff[13]; + + fprintf(fp, "%d\r\n", index + 1); + line = subs->lines + index; + ms2ts(bufon, 13, line->on); + ms2ts(bufoff, 13, line->off); + fprintf(fp, "%s --> %s\r\n", bufon, bufoff); + fprintf(fp, "%s", line->text); +} + +void +save_subs(FILE *fp, Subtitles *subs) +{ int i; for (i = 0; i < subs->count; i++) { - Line line = subs->lines[i]; - fprintf(fp, "%d\r\n", i + 1); - ms2ts(bufon, 13, line.on); - ms2ts(bufoff, 13, line.off); - fprintf(fp, "%s --> %s\r\n", bufon, bufoff); - fprintf(fp, "%s\r\n", line.text); + print_line(fp, subs, i); + fprintf(fp, "\r\n"); } } @@ -116,11 +133,69 @@ free_subs(Subtitles **subs) } int -main() +closest(Subtitles *subs, uint32_t ms) +{ + int imin, imax; + + imin = 0; + imax = subs->count - 1; + do { + int i = (imin + imax) / 2; + uint32_t sms = subs->lines[i].on; + if (sms < ms) + imin = i + 1; + else if (sms > ms) + imax = i - 1; + else + return i; + } while (imin < imax); + return imin; +} + +int +contains(Line *line, char *words[], int nwords) +{ + char *str = line->text; + while (nwords--) + if (!(str = strstr(str, *words++))) + return 0; + return 1; +} + +int +search(Subtitles *subs, uint32_t ms, char *words[], int nwords) +{ +#define SRT_CHECK(I) if (contains(&subs->lines[I], words, nwords)) return I + int i, s, t; + + i = closest(subs, ms); + SRT_CHECK(i); + s = 1; + while (i-s > 0 && i+s < subs->count) { + SRT_CHECK(i-s); + SRT_CHECK(i+s); + s++; + } + for (t = i-s; t >= 0; t--) + SRT_CHECK(t); + for (t = i+s; t < subs->count; t++) + SRT_CHECK(t); + return -1; +#undef SRT_CHECK +} + +int +main(int argc, char *argv[]) { Subtitles *subs; + int i; + + if (argc < 2) + return 1; subs = load_subs(stdin); - save_subs(stdout, subs); + i = search(subs, partial2ms(argv[1]), argv + 2, argc - 2); + if (i >= 0) + print_line(stdout, subs, i); free_subs(&subs); return 0; }