comparison libmpdemux/realrtsp/asmrp.c @ 9922:6cb7a295ab0e

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