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
);
122 static void asmrp_getch (asmrp_t
*p
) {
123 p
->ch
= p
->buf
[p
->pos
];
127 printf ("%c\n", p
->ch
);
132 static void asmrp_init (asmrp_t
*p
, const char *str
) {
134 p
->buf
= strdup (str
);
140 static void asmrp_number (asmrp_t
*p
) {
145 while ( (p
->ch
>='0') && (p
->ch
<='9') ) {
147 num
= num
*10 + (p
->ch
- '0');
152 p
->sym
= ASMRP_SYM_NUM
;
156 static void asmrp_string (asmrp_t
*p
) {
162 while ( (p
->ch
!='"') && (p
->ch
>=32) ) {
164 if(l
< ASMRP_MAX_ID
- 1)
167 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: string too long, ignoring char %c.\n", p
->ch
);
176 p
->sym
= ASMRP_SYM_STRING
;
179 static void asmrp_identifier (asmrp_t
*p
) {
185 while ( ((p
->ch
>='A') && (p
->ch
<='z'))
186 || ((p
->ch
>='0') && (p
->ch
<='9'))) {
188 if(l
< ASMRP_MAX_ID
- 1)
191 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: identifier too long, ignoring char %c.\n", p
->ch
);
197 p
->sym
= ASMRP_SYM_ID
;
201 static void asmrp_print_sym (asmrp_t
*p
) {
216 printf ("NUM %d\n", p
->num
);
220 printf ("ID '%s'\n", p
->str
);
223 case ASMRP_SYM_STRING
:
224 printf ("STRING \"%s\"\n", p
->str
);
231 case ASMRP_SYM_SEMICOLON
:
234 case ASMRP_SYM_COMMA
:
237 case ASMRP_SYM_EQUALS
:
255 case ASMRP_SYM_GREATER
:
258 case ASMRP_SYM_DOLLAR
:
261 case ASMRP_SYM_LPAREN
:
264 case ASMRP_SYM_RPAREN
:
269 printf ("unknown symbol %d\n", p
->sym
);
274 static void asmrp_get_sym (asmrp_t
*p
) {
276 while (p
->ch
<= 32) {
278 p
->sym
= ASMRP_SYM_EOF
;
291 p
->sym
= ASMRP_SYM_HASH
;
295 p
->sym
= ASMRP_SYM_SEMICOLON
;
299 p
->sym
= ASMRP_SYM_COMMA
;
303 p
->sym
= ASMRP_SYM_EQUALS
;
309 p
->sym
= ASMRP_SYM_AND
;
315 p
->sym
= ASMRP_SYM_OR
;
321 p
->sym
= ASMRP_SYM_LESS
;
324 p
->sym
= ASMRP_SYM_LEQ
;
329 p
->sym
= ASMRP_SYM_GREATER
;
332 p
->sym
= ASMRP_SYM_GEQ
;
337 p
->sym
= ASMRP_SYM_DOLLAR
;
341 p
->sym
= ASMRP_SYM_LPAREN
;
345 p
->sym
= ASMRP_SYM_RPAREN
;
354 case '0': case '1': case '2': case '3': case '4':
355 case '5': case '6': case '7': case '8': case '9':
360 asmrp_identifier (p
);
369 static int asmrp_find_id (asmrp_t
*p
, char *s
) {
373 for (i
=0; i
<p
->sym_tab_num
; i
++) {
374 if (!strcmp (s
, p
->sym_tab
[i
].id
))
381 static int asmrp_set_id (asmrp_t
*p
, char *s
, int v
) {
385 i
= asmrp_find_id (p
, s
);
388 if (p
->sym_tab_num
== ASMRP_MAX_SYMTAB
- 1) {
389 mp_msg(MSGT_STREAM
, MSGL_ERR
, "sym_tab overflow, ignoring identifier %s\n", s
);
394 p
->sym_tab
[i
].id
= strdup (s
);
397 printf ("new symbol '%s'\n", s
);
405 printf ("symbol '%s' assigned %d\n", s
, v
);
411 static int asmrp_condition (asmrp_t
*p
) ;
413 static int asmrp_operand (asmrp_t
*p
) {
418 printf ("operand\n");
425 case ASMRP_SYM_DOLLAR
:
429 if (p
->sym
!= ASMRP_SYM_ID
) {
430 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: identifier expected.\n");
434 i
= asmrp_find_id (p
, p
->str
);
436 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: unknown identifier %s\n", p
->str
);
438 ret
= p
->sym_tab
[i
].v
;
449 case ASMRP_SYM_LPAREN
:
452 ret
= asmrp_condition (p
);
454 if (p
->sym
!= ASMRP_SYM_RPAREN
) {
455 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: ) expected.\n");
463 mp_msg(MSGT_STREAM
, MSGL_ERR
, "syntax error, $ number or ( expected\n");
467 printf ("operand done, =%d\n", ret
);
474 static int asmrp_comp_expression (asmrp_t
*p
) {
479 printf ("comp_expression\n");
482 a
= asmrp_operand (p
);
484 while ( (p
->sym
== ASMRP_SYM_LESS
)
485 || (p
->sym
== ASMRP_SYM_LEQ
)
486 || (p
->sym
== ASMRP_SYM_EQUALS
)
487 || (p
->sym
== ASMRP_SYM_GEQ
)
488 || (p
->sym
== ASMRP_SYM_GREATER
) ) {
494 b
= asmrp_operand (p
);
503 case ASMRP_SYM_EQUALS
:
509 case ASMRP_SYM_GREATER
:
517 printf ("comp_expression done = %d\n", a
);
522 static int asmrp_condition (asmrp_t
*p
) {
527 printf ("condition\n");
530 a
= asmrp_comp_expression (p
);
532 while ( (p
->sym
== ASMRP_SYM_AND
) || (p
->sym
== ASMRP_SYM_OR
) ) {
539 b
= asmrp_comp_expression (p
);
552 printf ("condition done = %d\n", a
);
557 static void asmrp_assignment (asmrp_t
*p
) {
560 printf ("assignment\n");
563 if (p
->sym
== ASMRP_SYM_COMMA
|| p
->sym
== ASMRP_SYM_SEMICOLON
) {
565 printf ("empty assignment\n");
570 if (p
->sym
!= ASMRP_SYM_ID
) {
571 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: identifier expected\n");
576 if (p
->sym
!= ASMRP_SYM_EQUALS
) {
577 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: = expected\n");
582 if ( (p
->sym
!= ASMRP_SYM_NUM
) && (p
->sym
!= ASMRP_SYM_STRING
)
583 && (p
->sym
!= ASMRP_SYM_ID
)) {
584 mp_msg(MSGT_STREAM
, MSGL_ERR
, "error: number or string expected\n");
590 printf ("assignment done\n");
594 static int asmrp_rule (asmrp_t
*p
) {
604 if (p
->sym
== ASMRP_SYM_HASH
) {
607 ret
= asmrp_condition (p
);
609 while (p
->sym
== ASMRP_SYM_COMMA
) {
613 asmrp_assignment (p
);
616 } else if (p
->sym
!= ASMRP_SYM_SEMICOLON
) {
618 asmrp_assignment (p
);
620 while (p
->sym
== ASMRP_SYM_COMMA
) {
623 asmrp_assignment (p
);
628 printf ("rule done = %d\n", ret
);
631 if (p
->sym
!= ASMRP_SYM_SEMICOLON
) {
632 mp_msg(MSGT_STREAM
, MSGL_ERR
, "semicolon expected.\n");
641 static int asmrp_eval (asmrp_t
*p
, int *matches
) {
643 int rule_num
, num_matches
;
651 rule_num
= 0; num_matches
= 0;
652 while (p
->sym
!= ASMRP_SYM_EOF
) {
654 if (asmrp_rule (p
)) {
656 printf ("rule #%d is true\n", rule_num
);
658 if(num_matches
< MAX_RULEMATCHES
- 1)
659 matches
[num_matches
++] = rule_num
;
661 mp_msg(MSGT_STREAM
, MSGL_ERR
,
662 "Ignoring matched asm rule %d, too many matched rules.\n", rule_num
);
668 matches
[num_matches
] = -1;
672 int asmrp_match (const char *rules
, int bandwidth
, int *matches
) {
679 asmrp_init (p
, rules
);
681 asmrp_set_id (p
, "Bandwidth", bandwidth
);
682 asmrp_set_id (p
, "OldPNMPlayer", 0);
684 num_matches
= asmrp_eval (p
, matches
);