Mercurial > mplayer.hg
annotate libmpdemux/realrtsp/asmrp.c @ 19252:9757c44cae9a
no need to reming the copyright with msg_(), the notice in the source is enough
author | nicodvb |
---|---|
date | Sun, 30 Jul 2006 08:15:59 +0000 |
parents | f580a7755ac5 |
children |
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> | |
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 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
13203
diff
changeset
|
98 static asmrp_t *asmrp_new (void) { |
9922 | 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 | |
13203
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
553 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
|
554 #ifdef LOG |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
555 printf ("empty assignment\n"); |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
556 #endif |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
557 return; |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
558 } |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
559 |
9922 | 560 if (p->sym != ASMRP_SYM_ID) { |
561 printf ("error: identifier expected\n"); | |
562 abort (); | |
563 } | |
564 asmrp_get_sym (p); | |
565 | |
566 if (p->sym != ASMRP_SYM_EQUALS) { | |
567 printf ("error: = expected\n"); | |
568 abort (); | |
569 } | |
570 asmrp_get_sym (p); | |
571 | |
572 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) | |
573 && (p->sym != ASMRP_SYM_ID)) { | |
574 printf ("error: number or string expected\n"); | |
575 abort (); | |
576 } | |
577 asmrp_get_sym (p); | |
578 | |
579 #ifdef LOG | |
580 printf ("assignment done\n"); | |
581 #endif | |
582 } | |
583 | |
584 static int asmrp_rule (asmrp_t *p) { | |
585 | |
586 int ret; | |
587 | |
588 #ifdef LOG | |
589 printf ("rule\n"); | |
590 #endif | |
591 | |
592 ret = 1; | |
593 | |
594 if (p->sym == ASMRP_SYM_HASH) { | |
595 | |
596 asmrp_get_sym (p); | |
597 ret = asmrp_condition (p); | |
598 | |
599 while (p->sym == ASMRP_SYM_COMMA) { | |
600 | |
601 asmrp_get_sym (p); | |
602 | |
603 asmrp_assignment (p); | |
604 } | |
605 | |
606 } else if (p->sym != ASMRP_SYM_SEMICOLON) { | |
607 | |
608 asmrp_assignment (p); | |
609 | |
610 while (p->sym == ASMRP_SYM_COMMA) { | |
611 | |
612 asmrp_get_sym (p); | |
613 asmrp_assignment (p); | |
614 } | |
615 } | |
616 | |
617 #ifdef LOG | |
618 printf ("rule done = %d\n", ret); | |
619 #endif | |
620 | |
621 if (p->sym != ASMRP_SYM_SEMICOLON) { | |
622 printf ("semicolon expected.\n"); | |
623 abort (); | |
624 } | |
625 | |
626 asmrp_get_sym (p); | |
627 | |
628 return ret; | |
629 } | |
630 | |
631 static int asmrp_eval (asmrp_t *p, int *matches) { | |
632 | |
633 int rule_num, num_matches; | |
634 | |
635 #ifdef LOG | |
636 printf ("eval\n"); | |
637 #endif | |
638 | |
639 asmrp_get_sym (p); | |
640 | |
641 rule_num = 0; num_matches = 0; | |
642 while (p->sym != ASMRP_SYM_EOF) { | |
643 | |
644 if (asmrp_rule (p)) { | |
645 #ifdef LOG | |
646 printf ("rule #%d is true\n", rule_num); | |
647 #endif | |
648 matches[num_matches] = rule_num; | |
649 num_matches++; | |
650 } | |
651 | |
652 rule_num++; | |
653 } | |
654 | |
655 matches[num_matches] = -1; | |
656 return num_matches; | |
657 } | |
658 | |
659 int asmrp_match (const char *rules, int bandwidth, int *matches) { | |
660 | |
661 asmrp_t *p; | |
662 int num_matches; | |
663 | |
664 p = asmrp_new (); | |
665 | |
666 asmrp_init (p, rules); | |
667 | |
668 asmrp_set_id (p, "Bandwidth", bandwidth); | |
669 asmrp_set_id (p, "OldPNMPlayer", 0); | |
670 | |
671 num_matches = asmrp_eval (p, matches); | |
672 | |
673 asmrp_dispose (p); | |
674 | |
675 return num_matches; | |
676 } | |
677 |