movie.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "dict.h"
  5. /* Possible tags */
  6. enum {
  7. BEG, /* beginning of entry */
  8. AB, /* abstract */
  9. AN, /* database serial number */
  10. AS, /* author (one at a time) */
  11. AU, /* all authors */
  12. AW, /* award_awardee */
  13. BW, /* bw or c */
  14. CA, /* cast: character_actor */
  15. CN, /* cinematography */
  16. CO, /* country */
  17. CR, /* miscellaneous job_name */
  18. DE, /* topic keyword */
  19. DR, /* director */
  20. ED, /* editor */
  21. MP, /* MPAA rating (R, PG, etc.) */
  22. NT, /* note */
  23. PR, /* producer and for ...*/
  24. PS, /* producer (repeats info in PR) */
  25. RA, /* rating (letter) */
  26. RD, /* release date */
  27. RT, /* running time */
  28. RV, /* review citation */
  29. ST, /* production or release company (repeats info in PR) */
  30. TI, /* title[; original foreign title] */
  31. TX, /* paragraph of descriptive text */
  32. VD, /* video information (format_time_company; or "Not Avail.") */
  33. NTAG /* number of tags */
  34. };
  35. /* Assoc tables must be sorted on first field */
  36. static char *tagtab[] = {
  37. [BEG] "$$",
  38. [AB] "AB",
  39. [AN] "AN",
  40. [AS] "AS",
  41. [AU] "AU",
  42. [AW] "AW",
  43. [BW] "BW",
  44. [CA] "CA",
  45. [CN] "CN",
  46. [CO] "CO",
  47. [CR] "CR",
  48. [DE] "DE",
  49. [DR] "DR",
  50. [ED] "ED",
  51. [MP] "MP",
  52. [NT] "NT",
  53. [PR] "PR",
  54. [PS] "PS",
  55. [RA] "RA",
  56. [RD] "RD",
  57. [RT] "RT",
  58. [RV] "RV",
  59. [ST] "ST",
  60. [TI] "TI",
  61. [TX] "TX",
  62. [VD] "VD",
  63. };
  64. static char *mget(int, char *, char *, char **);
  65. static void moutall(int, char *, char *);
  66. static void moutall2(int, char *, char *);
  67. void
  68. movieprintentry(Entry ent, int cmd)
  69. {
  70. char *p, *e, *ps, *pe, *pn;
  71. int n;
  72. ps = ent.start;
  73. pe = ent.end;
  74. if(cmd == 'r') {
  75. Bwrite(bout, ps, pe-ps);
  76. return;
  77. }
  78. p = mget(TI, ps, pe, &e);
  79. if(p) {
  80. outpiece(p, e);
  81. outnl(0);
  82. }
  83. if(cmd == 'h')
  84. return;
  85. outnl(2);
  86. n = 0;
  87. p = mget(RD, ps, pe, &e);
  88. if(p) {
  89. outchars("Released: ");
  90. outpiece(p, e);
  91. n++;
  92. }
  93. p = mget(CO, ps, pe, &e);
  94. if(p) {
  95. if(n)
  96. outchars(", ");
  97. outpiece(p, e);
  98. n++;
  99. }
  100. p = mget(RT, ps, pe, &e);
  101. if(p) {
  102. if(n)
  103. outchars(", ");
  104. outchars("Running time: ");
  105. outpiece(p, e);
  106. n++;
  107. }
  108. p = mget(MP, ps, pe, &e);
  109. if(p) {
  110. if(n)
  111. outchars(", ");
  112. outpiece(p, e);
  113. n++;
  114. }
  115. p = mget(BW, ps, pe, &e);
  116. if(p) {
  117. if(n)
  118. outchars(", ");
  119. if(*p == 'c' || *p == 'C')
  120. outchars("Color");
  121. else
  122. outchars("B&W");
  123. n++;
  124. }
  125. if(n) {
  126. outchar('.');
  127. outnl(1);
  128. }
  129. p = mget(VD, ps, pe, &e);
  130. if(p) {
  131. outchars("Video: ");
  132. outpiece(p, e);
  133. outnl(1);
  134. }
  135. p = mget(AU, ps, pe, &e);
  136. if(p) {
  137. outchars("By: ");
  138. moutall2(AU, ps, pe);
  139. outnl(1);
  140. }
  141. p = mget(DR, ps, pe, &e);
  142. if(p) {
  143. outchars("Director: ");
  144. outpiece(p, e);
  145. outnl(1);
  146. }
  147. p = mget(PR, ps, pe, &e);
  148. if(p) {
  149. outchars("Producer: ");
  150. outpiece(p, e);
  151. outnl(1);
  152. }
  153. p = mget(CN, ps, pe, &e);
  154. if(p) {
  155. outchars("Cinematograpy: ");
  156. outpiece(p, e);
  157. outnl(1);
  158. }
  159. p = mget(CR, ps, pe, &e);
  160. if(p) {
  161. outchars("Other Credits: ");
  162. moutall2(CR, ps, pe);
  163. }
  164. outnl(2);
  165. p = mget(CA, ps, pe, &e);
  166. if(p) {
  167. outchars("Cast: ");
  168. moutall2(CA, ps, pe);
  169. }
  170. outnl(2);
  171. p = mget(AW, ps, pe, &e);
  172. if(p) {
  173. outchars("Awards: ");
  174. moutall2(AW, ps, pe);
  175. outnl(2);
  176. }
  177. p = mget(NT, ps, pe, &e);
  178. if(p) {
  179. outpiece(p, e);
  180. outnl(2);
  181. }
  182. p = mget(AB, ps, pe, &e);
  183. if(p) {
  184. outpiece(p, e);
  185. outnl(2);
  186. }
  187. pn = ps;
  188. n = 0;
  189. while((p = mget(TX, pn, pe, &pn)) != 0) {
  190. if(n++)
  191. outnl(1);
  192. outpiece(p, pn);
  193. }
  194. outnl(0);
  195. }
  196. long
  197. movienextoff(long fromoff)
  198. {
  199. long a;
  200. char *p;
  201. a = Bseek(bdict, fromoff, 0);
  202. if(a < 0)
  203. return -1;
  204. for(;;) {
  205. p = Brdline(bdict, '\n');
  206. if(!p)
  207. break;
  208. if(p[0] == '$' && p[1] == '$')
  209. return (Boffset(bdict)-Blinelen(bdict));
  210. }
  211. return -1;
  212. }
  213. void
  214. movieprintkey(void)
  215. {
  216. Bprint(bout, "No key\n");
  217. }
  218. /*
  219. * write a comma-separated list of all tag values between b and e
  220. */
  221. static void
  222. moutall(int tag, char *b, char *e)
  223. {
  224. char *p, *pn;
  225. int n;
  226. n = 0;
  227. pn = b;
  228. while((p = mget(tag, pn, e, &pn)) != 0) {
  229. if(n++)
  230. outchars(", ");
  231. outpiece(p, pn);
  232. }
  233. }
  234. /*
  235. * like moutall, but values are expected to have form:
  236. * field1_field2
  237. * and we are to output 'field2 (field1)' for each
  238. * (sometimes field1 has underscores, so search from end)
  239. */
  240. static void
  241. moutall2(int tag, char *b, char *e)
  242. {
  243. char *p, *pn, *us, *q;
  244. int n;
  245. n = 0;
  246. pn = b;
  247. while((p = mget(tag, pn, e, &pn)) != 0) {
  248. if(n++)
  249. outchars(", ");
  250. us = 0;
  251. for(q = pn-1; q >= p; q--)
  252. if(*q == '_') {
  253. us = q;
  254. break;
  255. }
  256. if(us) {
  257. /*
  258. * Hack to fix cast list Himself/Herself
  259. */
  260. if(strncmp(us+1, "Himself", 7) == 0 ||
  261. strncmp(us+1, "Herself", 7) == 0) {
  262. outpiece(p, us);
  263. outchars(" (");
  264. outpiece(us+1, pn);
  265. outchar(')');
  266. } else {
  267. outpiece(us+1, pn);
  268. outchars(" (");
  269. outpiece(p, us);
  270. outchar(')');
  271. }
  272. } else {
  273. outpiece(p, pn);
  274. }
  275. }
  276. }
  277. /*
  278. * Starting from b, find next line beginning with tagtab[tag].
  279. * Don't go past e, but assume *e==0.
  280. * Return pointer to beginning of value (after tag), and set
  281. * eptr to point at newline that ends the value
  282. */
  283. static char *
  284. mget(int tag, char *b, char *e, char **eptr)
  285. {
  286. char *p, *t, *ans;
  287. if(tag < 0 || tag >= NTAG)
  288. return 0;
  289. t = tagtab[tag];
  290. ans = 0;
  291. for(p = b;;) {
  292. p = strchr(p, '\n');
  293. if(!p || ++p >= e) {
  294. if(ans)
  295. *eptr = e-1;
  296. break;
  297. }
  298. if(!ans) {
  299. if(p[0] == t[0] && p[1] == t[1])
  300. ans = p+3;
  301. } else {
  302. if(p[0] != ' ') {
  303. *eptr = p-1;
  304. break;
  305. }
  306. }
  307. }
  308. return ans;
  309. }