2 * This file was ported to MPlayer from xine CVS asmrp.c,v 1.2 2002/12/17 16:49:48
6 * Copyright (C) 2002 the xine project
8 * This file is part of xine, a free video player.
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.
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.
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
25 * a parser for real's asm rules
27 * grammar for these rules:
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 ')' )
50 #define ASMRP_SYM_NONE 0
51 #define ASMRP_SYM_EOF 1
53 #define ASMRP_SYM_NUM 2
54 #define ASMRP_SYM_ID 3
55 #define ASMRP_SYM_STRING 4
57 #define ASMRP_SYM_HASH 10
58 #define ASMRP_SYM_SEMICOLON 11
59 #define ASMRP_SYM_COMMA 12
60 #define ASMRP_SYM_EQUALS 13
61 #define ASMRP_SYM_AND 14
62 #define ASMRP_SYM_OR 15
63 #define ASMRP_SYM_LESS 16
64 #define ASMRP_SYM_LEQ 17
65 #define ASMRP_SYM_GEQ 18
66 #define ASMRP_SYM_GREATER 19
67 #define ASMRP_SYM_DOLLAR 20
68 #define ASMRP_SYM_LPAREN 21
69 #define ASMRP_SYM_RPAREN 22
71 #define ASMRP_MAX_ID 1024
73 #define ASMRP_MAX_SYMTAB 10
87 char str
[ASMRP_MAX_ID
];
95 asmrp_sym_t sym_tab
[ASMRP_MAX_SYMTAB
];
100 static asmrp_t
*asmrp_new (void) {
104 p
= malloc (sizeof (asmrp_t
));
107 p
->sym
= ASMRP_SYM_NONE
;
112 static void asmrp_dispose (asmrp_t
*p
) {
116 for (i
=0; i
<p
->sym_tab_num
; i
++)
117 free (p
->sym_tab
[i
].id
);
123 static void asmrp_getch (asmrp_t
*p
) {
124 p
->ch
= p
->buf
[p
->pos
];
128 printf ("%c\n", p
->ch
);
133 static void asmrp_init (asmrp_t
*p
, const char *str
) {
135 p
->buf
= strdup (str
);
141 static void asmrp_number (asmrp_t
*p
) {
146 while ( (p
->ch
>='0') && (p
->ch
<='9') ) {
148 num
= num
*10 + (p
->ch
- '0');
153 p
->sym
= ASMRP_SYM_NUM
;
157 static void asmrp_string (asmrp_t
*p
) {
163 while ( (p
->ch
!='"') && (p
->ch
>=32) ) {
165 if(l
< ASMRP_MAX_ID
- 1)
168 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: string too long, ignoring char %c.\n", p
->ch
);
177 p
->sym
= ASMRP_SYM_STRING
;
180 static void asmrp_identifier (asmrp_t
*p
) {
186 while ( ((p
->ch
>='A') && (p
->ch
<='z'))
187 || ((p
->ch
>='0') && (p
->ch
<='9'))) {
189 if(l
< ASMRP_MAX_ID
- 1)
192 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: identifier too long, ignoring char %c.\n", p
->ch
);
198 p
->sym
= ASMRP_SYM_ID
;
202 static void asmrp_print_sym (asmrp_t
*p
) {
217 printf ("NUM %d\n", p
->num
);
221 printf ("ID '%s'\n", p
->str
);
224 case ASMRP_SYM_STRING
:
225 printf ("STRING \"%s\"\n", p
->str
);
232 case ASMRP_SYM_SEMICOLON
:
235 case ASMRP_SYM_COMMA
:
238 case ASMRP_SYM_EQUALS
:
256 case ASMRP_SYM_GREATER
:
259 case ASMRP_SYM_DOLLAR
:
262 case ASMRP_SYM_LPAREN
:
265 case ASMRP_SYM_RPAREN
:
270 printf ("unknown symbol %d\n", p
->sym
);
275 static void asmrp_get_sym (asmrp_t
*p
) {
277 while (p
->ch
<= 32) {
279 p
->sym
= ASMRP_SYM_EOF
;
292 p
->sym
= ASMRP_SYM_HASH
;
296 p
->sym
= ASMRP_SYM_SEMICOLON
;
300 p
->sym
= ASMRP_SYM_COMMA
;
304 p
->sym
= ASMRP_SYM_EQUALS
;
310 p
->sym
= ASMRP_SYM_AND
;
316 p
->sym
= ASMRP_SYM_OR
;
322 p
->sym
= ASMRP_SYM_LESS
;
325 p
->sym
= ASMRP_SYM_LEQ
;
330 p
->sym
= ASMRP_SYM_GREATER
;
333 p
->sym
= ASMRP_SYM_GEQ
;
338 p
->sym
= ASMRP_SYM_DOLLAR
;
342 p
->sym
= ASMRP_SYM_LPAREN
;
346 p
->sym
= ASMRP_SYM_RPAREN
;
355 case '0': case '1': case '2': case '3': case '4':
356 case '5': case '6': case '7': case '8': case '9':
361 asmrp_identifier (p
);
370 static int asmrp_find_id (asmrp_t
*p
, char *s
) {
374 for (i
=0; i
<p
->sym_tab_num
; i
++) {
375 if (!strcmp (s
, p
->sym_tab
[i
].id
))
382 static int asmrp_set_id (asmrp_t
*p
, char *s
, int v
) {
386 i
= asmrp_find_id (p
, s
);
389 if (p
->sym_tab_num
== ASMRP_MAX_SYMTAB
- 1) {
390 mp_msg(MSGT_STREAM
, MSGL_ERR
, "sym_tab overflow, ignoring identifier %s\n", s
);
395 p
->sym_tab
[i
].id
= strdup (s
);
398 printf ("new symbol '%s'\n", s
);
406 printf ("symbol '%s' assigned %d\n", s
, v
);
412 static int asmrp_condition (asmrp_t
*p
) ;
414 static int asmrp_operand (asmrp_t
*p
) {
419 printf ("operand\n");
426 case ASMRP_SYM_DOLLAR
:
430 if (p
->sym
!= ASMRP_SYM_ID
) {
431 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: identifier expected.\n");
435 i
= asmrp_find_id (p
, p
->str
);
437 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: unknown identifier %s\n", p
->str
);
439 ret
= p
->sym_tab
[i
].v
;
450 case ASMRP_SYM_LPAREN
:
453 ret
= asmrp_condition (p
);
455 if (p
->sym
!= ASMRP_SYM_RPAREN
) {
456 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: ) expected.\n");
464 mp_msg(MSGT_STREAM
, MSGL_ERR
, "syntax error, $ number or ( expected\n");
468 printf ("operand done, =%d\n", ret
);
475 static int asmrp_comp_expression (asmrp_t
*p
) {
480 printf ("comp_expression\n");
483 a
= asmrp_operand (p
);
485 while ( (p
->sym
== ASMRP_SYM_LESS
)
486 || (p
->sym
== ASMRP_SYM_LEQ
)
487 || (p
->sym
== ASMRP_SYM_EQUALS
)
488 || (p
->sym
== ASMRP_SYM_GEQ
)
489 || (p
->sym
== ASMRP_SYM_GREATER
) ) {
495 b
= asmrp_operand (p
);
504 case ASMRP_SYM_EQUALS
:
510 case ASMRP_SYM_GREATER
:
518 printf ("comp_expression done = %d\n", a
);
523 static int asmrp_condition (asmrp_t
*p
) {
528 printf ("condition\n");
531 a
= asmrp_comp_expression (p
);
533 while ( (p
->sym
== ASMRP_SYM_AND
) || (p
->sym
== ASMRP_SYM_OR
) ) {
540 b
= asmrp_comp_expression (p
);
553 printf ("condition done = %d\n", a
);
558 static void asmrp_assignment (asmrp_t
*p
) {
561 printf ("assignment\n");
564 if (p
->sym
== ASMRP_SYM_COMMA
|| p
->sym
== ASMRP_SYM_SEMICOLON
) {
566 printf ("empty assignment\n");
571 if (p
->sym
!= ASMRP_SYM_ID
) {
572 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: identifier expected\n");
577 if (p
->sym
!= ASMRP_SYM_EQUALS
) {
578 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: = expected\n");
583 if ( (p
->sym
!= ASMRP_SYM_NUM
) && (p
->sym
!= ASMRP_SYM_STRING
)
584 && (p
->sym
!= ASMRP_SYM_ID
)) {
585 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: number or string expected\n");
591 printf ("assignment done\n");
595 static int asmrp_rule (asmrp_t
*p
) {
605 if (p
->sym
== ASMRP_SYM_HASH
) {
608 ret
= asmrp_condition (p
);
610 while (p
->sym
== ASMRP_SYM_COMMA
) {
614 asmrp_assignment (p
);
617 } else if (p
->sym
!= ASMRP_SYM_SEMICOLON
) {
619 asmrp_assignment (p
);
621 while (p
->sym
== ASMRP_SYM_COMMA
) {
624 asmrp_assignment (p
);
629 printf ("rule done = %d\n", ret
);
632 if (p
->sym
!= ASMRP_SYM_SEMICOLON
) {
633 mp_msg(MSGT_STREAM
, MSGL_ERR
, "semicolon expected.\n");
642 static int asmrp_eval (asmrp_t
*p
, int *matches
) {
644 int rule_num
, num_matches
;
652 rule_num
= 0; num_matches
= 0;
653 while (p
->sym
!= ASMRP_SYM_EOF
) {
655 if (asmrp_rule (p
)) {
657 printf ("rule #%d is true\n", rule_num
);
659 if(num_matches
< MAX_RULEMATCHES
- 1)
660 matches
[num_matches
++] = rule_num
;
662 mp_msg(MSGT_STREAM
, MSGL_ERR
,
663 "Ignoring matched asm rule %d, too many matched rules.\n", rule_num
);
669 matches
[num_matches
] = -1;
673 int asmrp_match (const char *rules
, int bandwidth
, int *matches
) {
680 asmrp_init (p
, rules
);
682 asmrp_set_id (p
, "Bandwidth", bandwidth
);
683 asmrp_set_id (p
, "OldPNMPlayer", 0);
685 num_matches
= asmrp_eval (p
, matches
);