Mercurial > mplayer.hg
annotate stream/realrtsp/asmrp.c @ 20750:582c0088ed65
now the OSD shows the value returned by demuxer_get_current_time() rather than sh_video->pts
author | nicodvb |
---|---|
date | Tue, 07 Nov 2006 22:57:42 +0000 |
parents | 118af5ff4b1d |
children | 4511c04bc4a0 |
rev | line source |
---|---|
9922 | 1 /* |
2 * This file was ported to MPlayer from xine CVS asmrp.c,v 1.2 2002/12/17 16:49:48 | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (C) 2002 the xine project | |
7 * | |
8 * This file is part of xine, a free video player. | |
9 * | |
10 * xine is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * xine is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
23 * | |
24 * | |
25 * a parser for real's asm rules | |
26 * | |
27 * grammar for these rules: | |
28 * | |
29 | |
30 rule_book = { rule } | |
31 rule = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';' | |
32 assignment = id '=' const | |
33 const = ( number | string ) | |
34 condition = comp_expr { ( '&&' | '||' ) comp_expr } | |
35 comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand } | |
36 operand = ( '$' id | num | '(' condition ')' ) | |
37 | |
38 */ | |
39 | |
40 #include <stdlib.h> | |
41 #include <stdio.h> | |
42 #include <string.h> | |
20701 | 43 #include "mp_msg.h" |
9922 | 44 |
45 /* | |
46 #define LOG | |
47 */ | |
48 | |
49 #define ASMRP_SYM_NONE 0 | |
50 #define ASMRP_SYM_EOF 1 | |
51 | |
52 #define ASMRP_SYM_NUM 2 | |
53 #define ASMRP_SYM_ID 3 | |
54 #define ASMRP_SYM_STRING 4 | |
55 | |
56 #define ASMRP_SYM_HASH 10 | |
57 #define ASMRP_SYM_SEMICOLON 11 | |
58 #define ASMRP_SYM_COMMA 12 | |
59 #define ASMRP_SYM_EQUALS 13 | |
60 #define ASMRP_SYM_AND 14 | |
61 #define ASMRP_SYM_OR 15 | |
62 #define ASMRP_SYM_LESS 16 | |
63 #define ASMRP_SYM_LEQ 17 | |
64 #define ASMRP_SYM_GEQ 18 | |
65 #define ASMRP_SYM_GREATER 19 | |
66 #define ASMRP_SYM_DOLLAR 20 | |
67 #define ASMRP_SYM_LPAREN 21 | |
68 #define ASMRP_SYM_RPAREN 22 | |
69 | |
70 #define ASMRP_MAX_ID 1024 | |
71 | |
72 #define ASMRP_MAX_SYMTAB 10 | |
73 | |
74 typedef struct { | |
75 char *id; | |
76 int v; | |
77 } asmrp_sym_t; | |
78 | |
79 typedef struct { | |
80 | |
81 /* public part */ | |
82 | |
83 int sym; | |
84 int num; | |
85 | |
86 char str[ASMRP_MAX_ID]; | |
87 | |
88 /* private part */ | |
89 | |
90 char *buf; | |
91 int pos; | |
92 char ch; | |
93 | |
94 asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB]; | |
95 int sym_tab_num; | |
96 | |
97 } asmrp_t; | |
98 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
13203
diff
changeset
|
99 static asmrp_t *asmrp_new (void) { |
9922 | 100 |
101 asmrp_t *p; | |
102 | |
103 p = malloc (sizeof (asmrp_t)); | |
104 | |
105 p->sym_tab_num = 0; | |
106 p->sym = ASMRP_SYM_NONE; | |
107 | |
108 return p; | |
109 } | |
110 | |
111 static void asmrp_dispose (asmrp_t *p) { | |
112 | |
113 int i; | |
114 | |
115 for (i=0; i<p->sym_tab_num; i++) | |
116 free (p->sym_tab[i].id); | |
117 | |
118 free (p); | |
119 } | |
120 | |
121 static void asmrp_getch (asmrp_t *p) { | |
122 p->ch = p->buf[p->pos]; | |
123 p->pos++; | |
124 | |
125 #ifdef LOG | |
126 printf ("%c\n", p->ch); | |
127 #endif | |
128 | |
129 } | |
130 | |
131 static void asmrp_init (asmrp_t *p, const char *str) { | |
132 | |
133 p->buf = strdup (str); | |
134 p->pos = 0; | |
135 | |
136 asmrp_getch (p); | |
137 } | |
138 | |
139 static void asmrp_number (asmrp_t *p) { | |
140 | |
141 int num; | |
142 | |
143 num = 0; | |
144 while ( (p->ch>='0') && (p->ch<='9') ) { | |
145 | |
146 num = num*10 + (p->ch - '0'); | |
147 | |
148 asmrp_getch (p); | |
149 } | |
150 | |
151 p->sym = ASMRP_SYM_NUM; | |
152 p->num = num; | |
153 } | |
154 | |
155 static void asmrp_string (asmrp_t *p) { | |
156 | |
157 int l; | |
158 | |
159 l = 0; | |
160 | |
161 while ( (p->ch!='"') && (p->ch>=32) ) { | |
162 | |
163 p->str[l] = p->ch; | |
164 | |
165 l++; | |
166 asmrp_getch (p); | |
167 } | |
168 p->str[l]=0; | |
169 | |
170 if (p->ch=='"') | |
171 asmrp_getch (p); | |
172 | |
173 p->sym = ASMRP_SYM_STRING; | |
174 } | |
175 | |
176 static void asmrp_identifier (asmrp_t *p) { | |
177 | |
178 int l; | |
179 | |
180 l = 0; | |
181 | |
182 while ( ((p->ch>='A') && (p->ch<='z')) | |
183 || ((p->ch>='0') && (p->ch<='9'))) { | |
184 | |
185 p->str[l] = p->ch; | |
186 | |
187 l++; | |
188 asmrp_getch (p); | |
189 } | |
190 p->str[l]=0; | |
191 | |
192 p->sym = ASMRP_SYM_ID; | |
193 } | |
194 | |
195 #ifdef LOG | |
196 static void asmrp_print_sym (asmrp_t *p) { | |
197 | |
198 printf ("symbol: "); | |
199 | |
200 switch (p->sym) { | |
201 | |
202 case ASMRP_SYM_NONE: | |
203 printf ("NONE\n"); | |
204 break; | |
205 | |
206 case ASMRP_SYM_EOF: | |
207 printf ("EOF\n"); | |
208 break; | |
209 | |
210 case ASMRP_SYM_NUM: | |
211 printf ("NUM %d\n", p->num); | |
212 break; | |
213 | |
214 case ASMRP_SYM_ID: | |
215 printf ("ID '%s'\n", p->str); | |
216 break; | |
217 | |
218 case ASMRP_SYM_STRING: | |
219 printf ("STRING \"%s\"\n", p->str); | |
220 break; | |
221 | |
222 case ASMRP_SYM_HASH: | |
223 printf ("#\n"); | |
224 break; | |
225 | |
226 case ASMRP_SYM_SEMICOLON: | |
227 printf (";\n"); | |
228 break; | |
229 case ASMRP_SYM_COMMA: | |
230 printf (",\n"); | |
231 break; | |
232 case ASMRP_SYM_EQUALS: | |
233 printf ("==\n"); | |
234 break; | |
235 case ASMRP_SYM_AND: | |
236 printf ("&&\n"); | |
237 break; | |
238 case ASMRP_SYM_OR: | |
239 printf ("||\n"); | |
240 break; | |
241 case ASMRP_SYM_LESS: | |
242 printf ("<\n"); | |
243 break; | |
244 case ASMRP_SYM_LEQ: | |
245 printf ("<=\n"); | |
246 break; | |
247 case ASMRP_SYM_GEQ: | |
248 printf (">=\n"); | |
249 break; | |
250 case ASMRP_SYM_GREATER: | |
251 printf (">\n"); | |
252 break; | |
253 case ASMRP_SYM_DOLLAR: | |
254 printf ("$\n"); | |
255 break; | |
256 case ASMRP_SYM_LPAREN: | |
257 printf ("(\n"); | |
258 break; | |
259 case ASMRP_SYM_RPAREN: | |
260 printf (")\n"); | |
261 break; | |
262 | |
263 default: | |
264 printf ("unknown symbol %d\n", p->sym); | |
265 } | |
266 } | |
267 #endif | |
268 | |
269 static void asmrp_get_sym (asmrp_t *p) { | |
270 | |
271 while (p->ch <= 32) { | |
272 if (p->ch == 0) { | |
273 p->sym = ASMRP_SYM_EOF; | |
274 return; | |
275 } | |
276 | |
277 asmrp_getch (p); | |
278 } | |
279 | |
280 if (p->ch == '\\') | |
281 asmrp_getch (p); | |
282 | |
283 switch (p->ch) { | |
284 | |
285 case '#': | |
286 p->sym = ASMRP_SYM_HASH; | |
287 asmrp_getch (p); | |
288 break; | |
289 case ';': | |
290 p->sym = ASMRP_SYM_SEMICOLON; | |
291 asmrp_getch (p); | |
292 break; | |
293 case ',': | |
294 p->sym = ASMRP_SYM_COMMA; | |
295 asmrp_getch (p); | |
296 break; | |
297 case '=': | |
298 p->sym = ASMRP_SYM_EQUALS; | |
299 asmrp_getch (p); | |
300 if (p->ch=='=') | |
301 asmrp_getch (p); | |
302 break; | |
303 case '&': | |
304 p->sym = ASMRP_SYM_AND; | |
305 asmrp_getch (p); | |
306 if (p->ch=='&') | |
307 asmrp_getch (p); | |
308 break; | |
309 case '|': | |
310 p->sym = ASMRP_SYM_OR; | |
311 asmrp_getch (p); | |
312 if (p->ch=='|') | |
313 asmrp_getch (p); | |
314 break; | |
315 case '<': | |
316 p->sym = ASMRP_SYM_LESS; | |
317 asmrp_getch (p); | |
318 if (p->ch=='=') { | |
319 p->sym = ASMRP_SYM_LEQ; | |
320 asmrp_getch (p); | |
321 } | |
322 break; | |
323 case '>': | |
324 p->sym = ASMRP_SYM_GREATER; | |
325 asmrp_getch (p); | |
326 if (p->ch=='=') { | |
327 p->sym = ASMRP_SYM_GEQ; | |
328 asmrp_getch (p); | |
329 } | |
330 break; | |
331 case '$': | |
332 p->sym = ASMRP_SYM_DOLLAR; | |
333 asmrp_getch (p); | |
334 break; | |
335 case '(': | |
336 p->sym = ASMRP_SYM_LPAREN; | |
337 asmrp_getch (p); | |
338 break; | |
339 case ')': | |
340 p->sym = ASMRP_SYM_RPAREN; | |
341 asmrp_getch (p); | |
342 break; | |
343 | |
344 case '"': | |
345 asmrp_getch (p); | |
346 asmrp_string (p); | |
347 break; | |
348 | |
349 case '0': case '1': case '2': case '3': case '4': | |
350 case '5': case '6': case '7': case '8': case '9': | |
351 asmrp_number (p); | |
352 break; | |
353 | |
354 default: | |
355 asmrp_identifier (p); | |
356 } | |
357 | |
358 #ifdef LOG | |
359 asmrp_print_sym (p); | |
360 #endif | |
361 | |
362 } | |
363 | |
364 static int asmrp_find_id (asmrp_t *p, char *s) { | |
365 | |
366 int i; | |
367 | |
368 for (i=0; i<p->sym_tab_num; i++) { | |
369 if (!strcmp (s, p->sym_tab[i].id)) | |
370 return i; | |
371 } | |
372 | |
373 return -1; | |
374 } | |
375 | |
376 static int asmrp_set_id (asmrp_t *p, char *s, int v) { | |
377 | |
378 int i; | |
379 | |
380 i = asmrp_find_id (p, s); | |
381 | |
382 if (i<0) { | |
383 i = p->sym_tab_num; | |
384 p->sym_tab_num++; | |
385 p->sym_tab[i].id = strdup (s); | |
386 | |
387 #ifdef LOG | |
388 printf ("new symbol '%s'\n", s); | |
389 #endif | |
390 | |
391 } | |
392 | |
393 p->sym_tab[i].v = v; | |
394 | |
395 #ifdef LOG | |
396 printf ("symbol '%s' assigned %d\n", s, v); | |
397 #endif | |
398 | |
399 return i; | |
400 } | |
401 | |
402 static int asmrp_condition (asmrp_t *p) ; | |
403 | |
404 static int asmrp_operand (asmrp_t *p) { | |
405 | |
406 int i, ret; | |
407 | |
408 #ifdef LOG | |
409 printf ("operand\n"); | |
410 #endif | |
411 | |
412 ret = 0; | |
413 | |
414 switch (p->sym) { | |
415 | |
416 case ASMRP_SYM_DOLLAR: | |
417 | |
418 asmrp_get_sym (p); | |
419 | |
420 if (p->sym != ASMRP_SYM_ID) { | |
20699 | 421 mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected.\n"); |
20697 | 422 break; |
9922 | 423 } |
424 | |
425 i = asmrp_find_id (p, p->str); | |
426 if (i<0) { | |
20699 | 427 mp_msg(MSGT_STREAM, MSGL_ERR, "error: unknown identifier %s\n", p->str); |
9922 | 428 } |
429 ret = p->sym_tab[i].v; | |
430 | |
431 asmrp_get_sym (p); | |
432 break; | |
433 | |
434 case ASMRP_SYM_NUM: | |
435 ret = p->num; | |
436 | |
437 asmrp_get_sym (p); | |
438 break; | |
439 | |
440 case ASMRP_SYM_LPAREN: | |
441 asmrp_get_sym (p); | |
442 | |
443 ret = asmrp_condition (p); | |
444 | |
445 if (p->sym != ASMRP_SYM_RPAREN) { | |
20699 | 446 mp_msg(MSGT_STREAM, MSGL_ERR, "error: ) expected.\n"); |
20697 | 447 break; |
9922 | 448 } |
449 | |
450 asmrp_get_sym (p); | |
451 break; | |
452 | |
453 default: | |
20699 | 454 mp_msg(MSGT_STREAM, MSGL_ERR, "syntax error, $ number or ( expected\n"); |
9922 | 455 } |
456 | |
457 #ifdef LOG | |
458 printf ("operand done, =%d\n", ret); | |
459 #endif | |
460 | |
461 return ret; | |
462 } | |
463 | |
20697 | 464 |
9922 | 465 static int asmrp_comp_expression (asmrp_t *p) { |
466 | |
467 int a; | |
468 | |
469 #ifdef LOG | |
470 printf ("comp_expression\n"); | |
471 #endif | |
472 | |
473 a = asmrp_operand (p); | |
474 | |
475 while ( (p->sym == ASMRP_SYM_LESS) | |
476 || (p->sym == ASMRP_SYM_LEQ) | |
477 || (p->sym == ASMRP_SYM_EQUALS) | |
478 || (p->sym == ASMRP_SYM_GEQ) | |
479 || (p->sym == ASMRP_SYM_GREATER) ) { | |
480 int op = p->sym; | |
481 int b; | |
482 | |
483 asmrp_get_sym (p); | |
484 | |
485 b = asmrp_operand (p); | |
486 | |
487 switch (op) { | |
488 case ASMRP_SYM_LESS: | |
489 a = a<b; | |
490 break; | |
491 case ASMRP_SYM_LEQ: | |
492 a = a<=b; | |
493 break; | |
494 case ASMRP_SYM_EQUALS: | |
495 a = a==b; | |
496 break; | |
497 case ASMRP_SYM_GEQ: | |
498 a = a>=b; | |
499 break; | |
500 case ASMRP_SYM_GREATER: | |
501 a = a>b; | |
502 break; | |
503 } | |
504 | |
505 } | |
506 | |
507 #ifdef LOG | |
508 printf ("comp_expression done = %d\n", a); | |
509 #endif | |
510 return a; | |
511 } | |
512 | |
513 static int asmrp_condition (asmrp_t *p) { | |
514 | |
515 int a; | |
516 | |
517 #ifdef LOG | |
518 printf ("condition\n"); | |
519 #endif | |
520 | |
521 a = asmrp_comp_expression (p); | |
522 | |
523 while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) { | |
524 int op, b; | |
525 | |
526 op = p->sym; | |
527 | |
528 asmrp_get_sym (p); | |
529 | |
530 b = asmrp_comp_expression (p); | |
531 | |
532 switch (op) { | |
533 case ASMRP_SYM_AND: | |
534 a = a & b; | |
535 break; | |
536 case ASMRP_SYM_OR: | |
537 a = a | b; | |
538 break; | |
539 } | |
540 } | |
541 | |
542 #ifdef LOG | |
543 printf ("condition done = %d\n", a); | |
544 #endif | |
545 return a; | |
546 } | |
547 | |
548 static void asmrp_assignment (asmrp_t *p) { | |
549 | |
550 #ifdef LOG | |
551 printf ("assignment\n"); | |
552 #endif | |
553 | |
13203
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
554 if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) { |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
555 #ifdef LOG |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
556 printf ("empty assignment\n"); |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
557 #endif |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
558 return; |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
559 } |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
560 |
9922 | 561 if (p->sym != ASMRP_SYM_ID) { |
20699 | 562 mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected\n"); |
20697 | 563 return; |
9922 | 564 } |
565 asmrp_get_sym (p); | |
566 | |
567 if (p->sym != ASMRP_SYM_EQUALS) { | |
20699 | 568 mp_msg(MSGT_STREAM, MSGL_ERR, "error: = expected\n"); |
20697 | 569 return; |
9922 | 570 } |
571 asmrp_get_sym (p); | |
572 | |
573 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) | |
574 && (p->sym != ASMRP_SYM_ID)) { | |
20699 | 575 mp_msg(MSGT_STREAM, MSGL_ERR, "error: number or string expected\n"); |
20697 | 576 return; |
9922 | 577 } |
578 asmrp_get_sym (p); | |
579 | |
580 #ifdef LOG | |
581 printf ("assignment done\n"); | |
582 #endif | |
583 } | |
584 | |
585 static int asmrp_rule (asmrp_t *p) { | |
586 | |
587 int ret; | |
588 | |
589 #ifdef LOG | |
590 printf ("rule\n"); | |
591 #endif | |
592 | |
593 ret = 1; | |
594 | |
595 if (p->sym == ASMRP_SYM_HASH) { | |
596 | |
597 asmrp_get_sym (p); | |
598 ret = asmrp_condition (p); | |
599 | |
600 while (p->sym == ASMRP_SYM_COMMA) { | |
601 | |
602 asmrp_get_sym (p); | |
603 | |
604 asmrp_assignment (p); | |
605 } | |
606 | |
607 } else if (p->sym != ASMRP_SYM_SEMICOLON) { | |
608 | |
609 asmrp_assignment (p); | |
610 | |
611 while (p->sym == ASMRP_SYM_COMMA) { | |
612 | |
613 asmrp_get_sym (p); | |
614 asmrp_assignment (p); | |
615 } | |
616 } | |
617 | |
618 #ifdef LOG | |
619 printf ("rule done = %d\n", ret); | |
620 #endif | |
621 | |
622 if (p->sym != ASMRP_SYM_SEMICOLON) { | |
20699 | 623 mp_msg(MSGT_STREAM, MSGL_ERR, "semicolon expected.\n"); |
20697 | 624 return ret; |
9922 | 625 } |
626 | |
627 asmrp_get_sym (p); | |
628 | |
629 return ret; | |
630 } | |
631 | |
632 static int asmrp_eval (asmrp_t *p, int *matches) { | |
633 | |
634 int rule_num, num_matches; | |
635 | |
636 #ifdef LOG | |
637 printf ("eval\n"); | |
638 #endif | |
639 | |
640 asmrp_get_sym (p); | |
641 | |
642 rule_num = 0; num_matches = 0; | |
643 while (p->sym != ASMRP_SYM_EOF) { | |
644 | |
645 if (asmrp_rule (p)) { | |
646 #ifdef LOG | |
647 printf ("rule #%d is true\n", rule_num); | |
648 #endif | |
649 matches[num_matches] = rule_num; | |
650 num_matches++; | |
651 } | |
652 | |
653 rule_num++; | |
654 } | |
655 | |
656 matches[num_matches] = -1; | |
657 return num_matches; | |
658 } | |
659 | |
660 int asmrp_match (const char *rules, int bandwidth, int *matches) { | |
661 | |
662 asmrp_t *p; | |
663 int num_matches; | |
664 | |
665 p = asmrp_new (); | |
666 | |
667 asmrp_init (p, rules); | |
668 | |
669 asmrp_set_id (p, "Bandwidth", bandwidth); | |
670 asmrp_set_id (p, "OldPNMPlayer", 0); | |
671 | |
672 num_matches = asmrp_eval (p, matches); | |
673 | |
674 asmrp_dispose (p); | |
675 | |
676 return num_matches; | |
677 } | |
678 |