contrib: theora: do not run autoreconf
[vlc/gmpfix.git] / modules / access / rtsp / real_asmrp.c
blob057e230e7823400e3b022b1621aa8384a4e4671f
1 /*
2 * Copyright (C) 2002-2004 the xine project
4 * This file is part of xine, a free video player.
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 * $Id$
22 * a parser for real's asm rules
24 * grammar for these rules:
27 rule_book = { rule }
28 rule = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';'
29 assignment = id '=' const
30 const = ( number | string )
31 condition = comp_expr { ( '&&' | '||' ) comp_expr }
32 comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand }
33 operand = ( '$' id | num | '(' condition ')' )
37 #include "real.h"
39 #define ASMRP_SYM_NONE 0
40 #define ASMRP_SYM_EOF 1
42 #define ASMRP_SYM_NUM 2
43 #define ASMRP_SYM_ID 3
44 #define ASMRP_SYM_STRING 4
46 #define ASMRP_SYM_HASH 10
47 #define ASMRP_SYM_SEMICOLON 11
48 #define ASMRP_SYM_COMMA 12
49 #define ASMRP_SYM_EQUALS 13
50 #define ASMRP_SYM_AND 14
51 #define ASMRP_SYM_OR 15
52 #define ASMRP_SYM_LESS 16
53 #define ASMRP_SYM_LEQ 17
54 #define ASMRP_SYM_GEQ 18
55 #define ASMRP_SYM_GREATER 19
56 #define ASMRP_SYM_DOLLAR 20
57 #define ASMRP_SYM_LPAREN 21
58 #define ASMRP_SYM_RPAREN 22
60 #define ASMRP_MAX_ID 1024
62 #define ASMRP_MAX_SYMTAB 10
64 typedef struct {
65 char *id;
66 int v;
67 } asmrp_sym_t;
69 typedef struct {
71 /* public part */
73 int sym;
74 int num;
76 char str[ASMRP_MAX_ID];
78 /* private part */
80 char *buf;
81 int pos;
82 char ch;
84 asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB];
85 int sym_tab_num;
87 } asmrp_t;
89 static asmrp_t *asmrp_new (void ) {
91 asmrp_t *p;
93 p = malloc (sizeof (asmrp_t));
95 p->sym_tab_num = 0;
96 p->sym = ASMRP_SYM_NONE;
97 p->buf = NULL;
99 return p;
102 static void asmrp_dispose (asmrp_t *p) {
104 int i;
106 for (i=0; i<p->sym_tab_num; i++)
107 free (p->sym_tab[i].id);
109 free( p->buf );
110 free( p );
113 static void asmrp_getch (asmrp_t *p) {
114 p->ch = p->buf[p->pos];
115 p->pos++;
117 lprintf ("%c\n", p->ch);
121 static void asmrp_init (asmrp_t *p, const char *str) {
123 p->buf = strdup (str);
124 p->pos = 0;
126 asmrp_getch (p);
129 static void asmrp_number (asmrp_t *p) {
131 int num;
133 num = 0;
134 while ( (p->ch>='0') && (p->ch<='9') ) {
136 num = num*10 + (p->ch - '0');
138 asmrp_getch (p);
141 p->sym = ASMRP_SYM_NUM;
142 p->num = num;
145 static void asmrp_string (asmrp_t *p) {
147 int l;
149 l = 0;
151 while ( (p->ch!='"') && (p->ch>=32) ) {
153 p->str[l] = p->ch;
155 l++;
156 asmrp_getch (p);
158 p->str[l]=0;
160 if (p->ch=='"')
161 asmrp_getch (p);
163 p->sym = ASMRP_SYM_STRING;
166 static void asmrp_identifier (asmrp_t *p) {
168 int l;
170 l = 0;
172 while ( ((p->ch>='A') && (p->ch<='z'))
173 || ((p->ch>='0') && (p->ch<='9'))) {
175 p->str[l] = p->ch;
177 l++;
178 asmrp_getch (p);
180 p->str[l]=0;
182 p->sym = ASMRP_SYM_ID;
185 #ifdef LOG
186 static void asmrp_print_sym (asmrp_t *p) {
188 printf ("symbol: ");
190 switch (p->sym) {
192 case ASMRP_SYM_NONE:
193 printf ("NONE\n");
194 break;
196 case ASMRP_SYM_EOF:
197 printf ("EOF\n");
198 break;
200 case ASMRP_SYM_NUM:
201 printf ("NUM %d\n", p->num);
202 break;
204 case ASMRP_SYM_ID:
205 printf ("ID '%s'\n", p->str);
206 break;
208 case ASMRP_SYM_STRING:
209 printf ("STRING \"%s\"\n", p->str);
210 break;
212 case ASMRP_SYM_HASH:
213 printf ("#\n");
214 break;
216 case ASMRP_SYM_SEMICOLON:
217 printf (";\n");
218 break;
219 case ASMRP_SYM_COMMA:
220 printf (",\n");
221 break;
222 case ASMRP_SYM_EQUALS:
223 printf ("==\n");
224 break;
225 case ASMRP_SYM_AND:
226 printf ("&&\n");
227 break;
228 case ASMRP_SYM_OR:
229 printf ("||\n");
230 break;
231 case ASMRP_SYM_LESS:
232 printf ("<\n");
233 break;
234 case ASMRP_SYM_LEQ:
235 printf ("<=\n");
236 break;
237 case ASMRP_SYM_GEQ:
238 printf (">=\n");
239 break;
240 case ASMRP_SYM_GREATER:
241 printf (">\n");
242 break;
243 case ASMRP_SYM_DOLLAR:
244 printf ("$\n");
245 break;
246 case ASMRP_SYM_LPAREN:
247 printf ("(\n");
248 break;
249 case ASMRP_SYM_RPAREN:
250 printf (")\n");
251 break;
253 default:
254 printf ("unknown symbol %d\n", p->sym);
257 #endif
259 static void asmrp_get_sym (asmrp_t *p) {
261 while (p->ch <= 32) {
262 if (p->ch == 0) {
263 p->sym = ASMRP_SYM_EOF;
264 return;
267 asmrp_getch (p);
270 if (p->ch == '\\')
271 asmrp_getch (p);
273 switch (p->ch) {
275 case '#':
276 p->sym = ASMRP_SYM_HASH;
277 asmrp_getch (p);
278 break;
279 case ';':
280 p->sym = ASMRP_SYM_SEMICOLON;
281 asmrp_getch (p);
282 break;
283 case ',':
284 p->sym = ASMRP_SYM_COMMA;
285 asmrp_getch (p);
286 break;
287 case '=':
288 p->sym = ASMRP_SYM_EQUALS;
289 asmrp_getch (p);
290 if (p->ch=='=')
291 asmrp_getch (p);
292 break;
293 case '&':
294 p->sym = ASMRP_SYM_AND;
295 asmrp_getch (p);
296 if (p->ch=='&')
297 asmrp_getch (p);
298 break;
299 case '|':
300 p->sym = ASMRP_SYM_OR;
301 asmrp_getch (p);
302 if (p->ch=='|')
303 asmrp_getch (p);
304 break;
305 case '<':
306 p->sym = ASMRP_SYM_LESS;
307 asmrp_getch (p);
308 if (p->ch=='=') {
309 p->sym = ASMRP_SYM_LEQ;
310 asmrp_getch (p);
312 break;
313 case '>':
314 p->sym = ASMRP_SYM_GREATER;
315 asmrp_getch (p);
316 if (p->ch=='=') {
317 p->sym = ASMRP_SYM_GEQ;
318 asmrp_getch (p);
320 break;
321 case '$':
322 p->sym = ASMRP_SYM_DOLLAR;
323 asmrp_getch (p);
324 break;
325 case '(':
326 p->sym = ASMRP_SYM_LPAREN;
327 asmrp_getch (p);
328 break;
329 case ')':
330 p->sym = ASMRP_SYM_RPAREN;
331 asmrp_getch (p);
332 break;
334 case '"':
335 asmrp_getch (p);
336 asmrp_string (p);
337 break;
339 case '0': case '1': case '2': case '3': case '4':
340 case '5': case '6': case '7': case '8': case '9':
341 asmrp_number (p);
342 break;
344 default:
345 asmrp_identifier (p);
348 #ifdef LOG
349 asmrp_print_sym (p);
350 #endif
354 static int asmrp_find_id (asmrp_t *p, const char *s) {
356 int i;
358 for (i=0; i<p->sym_tab_num; i++) {
359 if (!strcmp (s, p->sym_tab[i].id))
360 return i;
363 return -1;
366 static int asmrp_set_id (asmrp_t *p, const char *s, int v) {
368 int i;
370 i = asmrp_find_id (p, s);
372 if (i<0) {
373 i = p->sym_tab_num;
374 p->sym_tab_num++;
375 p->sym_tab[i].id = strdup (s);
377 lprintf ("new symbol '%s'\n", s);
381 p->sym_tab[i].v = v;
383 lprintf ("symbol '%s' assigned %d\n", s, v);
385 return i;
388 static int asmrp_condition (asmrp_t *p) ;
390 static int asmrp_operand (asmrp_t *p) {
392 int i, ret;
394 lprintf ("operand\n");
396 ret = 0;
398 switch (p->sym) {
400 case ASMRP_SYM_DOLLAR:
402 asmrp_get_sym (p);
404 if (p->sym != ASMRP_SYM_ID) {
405 printf ("error: identifier expected.\n");
406 break;
409 i = asmrp_find_id (p, p->str);
410 if (i<0) {
411 lprintf ("error: unknown identifier %s\n", p->str);
413 ret = p->sym_tab[i].v;
415 asmrp_get_sym (p);
416 break;
418 case ASMRP_SYM_NUM:
419 ret = p->num;
421 asmrp_get_sym (p);
422 break;
424 case ASMRP_SYM_LPAREN:
425 asmrp_get_sym (p);
427 ret = asmrp_condition (p);
429 if (p->sym != ASMRP_SYM_RPAREN) {
430 printf ("error: ) expected.\n");
431 break;
434 asmrp_get_sym (p);
435 break;
437 default:
438 lprintf ("syntax error, $ number or ( expected\n");
439 break;
442 lprintf ("operand done, =%d\n", ret);
444 return ret;
447 static int asmrp_comp_expression (asmrp_t *p) {
449 int a;
451 lprintf ("comp_expression\n");
453 a = asmrp_operand (p);
455 while ( (p->sym == ASMRP_SYM_LESS)
456 || (p->sym == ASMRP_SYM_LEQ)
457 || (p->sym == ASMRP_SYM_EQUALS)
458 || (p->sym == ASMRP_SYM_GEQ)
459 || (p->sym == ASMRP_SYM_GREATER) ) {
460 int op = p->sym;
461 int b;
463 asmrp_get_sym (p);
465 b = asmrp_operand (p);
467 switch (op) {
468 case ASMRP_SYM_LESS:
469 a = a<b;
470 break;
471 case ASMRP_SYM_LEQ:
472 a = a<=b;
473 break;
474 case ASMRP_SYM_EQUALS:
475 a = a==b;
476 break;
477 case ASMRP_SYM_GEQ:
478 a = a>=b;
479 break;
480 case ASMRP_SYM_GREATER:
481 a = a>b;
482 break;
487 lprintf ("comp_expression done = %d\n", a);
489 return a;
492 static int asmrp_condition (asmrp_t *p) {
494 int a;
496 lprintf ("condition\n");
498 a = asmrp_comp_expression (p);
500 while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) {
501 int op, b;
503 op = p->sym;
505 asmrp_get_sym (p);
507 b = asmrp_comp_expression (p);
509 switch (op) {
510 case ASMRP_SYM_AND:
511 a = a & b;
512 break;
513 case ASMRP_SYM_OR:
514 a = a | b;
515 break;
519 lprintf ("condition done = %d\n", a);
521 return a;
524 static void asmrp_assignment (asmrp_t *p) {
526 lprintf ("assignment\n");
528 if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) {
529 lprintf ("empty assignment\n");
530 return;
533 if (p->sym != ASMRP_SYM_ID) {
534 printf ("error: identifier expected\n");
535 return;
537 asmrp_get_sym (p);
539 if (p->sym != ASMRP_SYM_EQUALS) {
540 printf ("error: = expected\n");
541 return;
543 asmrp_get_sym (p);
545 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
546 && (p->sym != ASMRP_SYM_ID)) {
547 printf ("error: number or string expected\n");
548 return;
550 asmrp_get_sym (p);
552 lprintf ("assignment done\n");
555 static int asmrp_rule (asmrp_t *p) {
557 int ret;
559 lprintf ("rule\n");
561 ret = 1;
563 if (p->sym == ASMRP_SYM_HASH) {
565 asmrp_get_sym (p);
566 ret = asmrp_condition (p);
568 while (p->sym == ASMRP_SYM_COMMA) {
570 asmrp_get_sym (p);
572 asmrp_assignment (p);
575 } else if (p->sym != ASMRP_SYM_SEMICOLON) {
577 asmrp_assignment (p);
579 while (p->sym == ASMRP_SYM_COMMA) {
581 asmrp_get_sym (p);
582 asmrp_assignment (p);
586 lprintf ("rule done = %d\n", ret);
588 if (p->sym != ASMRP_SYM_SEMICOLON) {
589 printf ("semicolon expected.\n");
590 return ret;
593 asmrp_get_sym (p);
595 return ret;
598 static int asmrp_eval (asmrp_t *p, int *matches, int matchsize) {
600 int rule_num, num_matches;
602 lprintf ("eval\n");
604 asmrp_get_sym (p);
606 rule_num = 0; num_matches = 0;
607 while (p->sym != ASMRP_SYM_EOF && num_matches < matchsize - 1) {
609 if (asmrp_rule (p)) {
610 lprintf ("rule #%d is true\n", rule_num);
612 matches[num_matches] = rule_num;
613 num_matches++;
616 rule_num++;
619 matches[num_matches] = -1;
620 return num_matches;
623 int asmrp_match (const char *rules, int bandwidth, int *matches, int matchsize) {
625 asmrp_t *p;
626 int num_matches;
628 p = asmrp_new ();
630 asmrp_init (p, rules);
632 asmrp_set_id (p, "Bandwidth", bandwidth);
633 asmrp_set_id (p, "OldPNMPlayer", 0);
635 num_matches = asmrp_eval (p, matches, matchsize);
637 asmrp_dispose (p);
639 return num_matches;