summaryrefslogtreecommitdiffstats
path: root/stream/realrtsp/asmrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/realrtsp/asmrp.c')
-rw-r--r--stream/realrtsp/asmrp.c677
1 files changed, 677 insertions, 0 deletions
diff --git a/stream/realrtsp/asmrp.c b/stream/realrtsp/asmrp.c
new file mode 100644
index 0000000000..05953daeb8
--- /dev/null
+++ b/stream/realrtsp/asmrp.c
@@ -0,0 +1,677 @@
+/*
+ * This file was ported to MPlayer from xine CVS asmrp.c,v 1.2 2002/12/17 16:49:48
+ */
+
+/*
+ * Copyright (C) 2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ *
+ * a parser for real's asm rules
+ *
+ * grammar for these rules:
+ *
+
+ rule_book = { rule }
+ rule = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';'
+ assignment = id '=' const
+ const = ( number | string )
+ condition = comp_expr { ( '&&' | '||' ) comp_expr }
+ comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand }
+ operand = ( '$' id | num | '(' condition ')' )
+
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+#define LOG
+*/
+
+#define ASMRP_SYM_NONE 0
+#define ASMRP_SYM_EOF 1
+
+#define ASMRP_SYM_NUM 2
+#define ASMRP_SYM_ID 3
+#define ASMRP_SYM_STRING 4
+
+#define ASMRP_SYM_HASH 10
+#define ASMRP_SYM_SEMICOLON 11
+#define ASMRP_SYM_COMMA 12
+#define ASMRP_SYM_EQUALS 13
+#define ASMRP_SYM_AND 14
+#define ASMRP_SYM_OR 15
+#define ASMRP_SYM_LESS 16
+#define ASMRP_SYM_LEQ 17
+#define ASMRP_SYM_GEQ 18
+#define ASMRP_SYM_GREATER 19
+#define ASMRP_SYM_DOLLAR 20
+#define ASMRP_SYM_LPAREN 21
+#define ASMRP_SYM_RPAREN 22
+
+#define ASMRP_MAX_ID 1024
+
+#define ASMRP_MAX_SYMTAB 10
+
+typedef struct {
+ char *id;
+ int v;
+} asmrp_sym_t;
+
+typedef struct {
+
+ /* public part */
+
+ int sym;
+ int num;
+
+ char str[ASMRP_MAX_ID];
+
+ /* private part */
+
+ char *buf;
+ int pos;
+ char ch;
+
+ asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB];
+ int sym_tab_num;
+
+} asmrp_t;
+
+static asmrp_t *asmrp_new (void) {
+
+ asmrp_t *p;
+
+ p = malloc (sizeof (asmrp_t));
+
+ p->sym_tab_num = 0;
+ p->sym = ASMRP_SYM_NONE;
+
+ return p;
+}
+
+static void asmrp_dispose (asmrp_t *p) {
+
+ int i;
+
+ for (i=0; i<p->sym_tab_num; i++)
+ free (p->sym_tab[i].id);
+
+ free (p);
+}
+
+static void asmrp_getch (asmrp_t *p) {
+ p->ch = p->buf[p->pos];
+ p->pos++;
+
+#ifdef LOG
+ printf ("%c\n", p->ch);
+#endif
+
+}
+
+static void asmrp_init (asmrp_t *p, const char *str) {
+
+ p->buf = strdup (str);
+ p->pos = 0;
+
+ asmrp_getch (p);
+}
+
+static void asmrp_number (asmrp_t *p) {
+
+ int num;
+
+ num = 0;
+ while ( (p->ch>='0') && (p->ch<='9') ) {
+
+ num = num*10 + (p->ch - '0');
+
+ asmrp_getch (p);
+ }
+
+ p->sym = ASMRP_SYM_NUM;
+ p->num = num;
+}
+
+static void asmrp_string (asmrp_t *p) {
+
+ int l;
+
+ l = 0;
+
+ while ( (p->ch!='"') && (p->ch>=32) ) {
+
+ p->str[l] = p->ch;
+
+ l++;
+ asmrp_getch (p);
+ }
+ p->str[l]=0;
+
+ if (p->ch=='"')
+ asmrp_getch (p);
+
+ p->sym = ASMRP_SYM_STRING;
+}
+
+static void asmrp_identifier (asmrp_t *p) {
+
+ int l;
+
+ l = 0;
+
+ while ( ((p->ch>='A') && (p->ch<='z'))
+ || ((p->ch>='0') && (p->ch<='9'))) {
+
+ p->str[l] = p->ch;
+
+ l++;
+ asmrp_getch (p);
+ }
+ p->str[l]=0;
+
+ p->sym = ASMRP_SYM_ID;
+}
+
+#ifdef LOG
+static void asmrp_print_sym (asmrp_t *p) {
+
+ printf ("symbol: ");
+
+ switch (p->sym) {
+
+ case ASMRP_SYM_NONE:
+ printf ("NONE\n");
+ break;
+
+ case ASMRP_SYM_EOF:
+ printf ("EOF\n");
+ break;
+
+ case ASMRP_SYM_NUM:
+ printf ("NUM %d\n", p->num);
+ break;
+
+ case ASMRP_SYM_ID:
+ printf ("ID '%s'\n", p->str);
+ break;
+
+ case ASMRP_SYM_STRING:
+ printf ("STRING \"%s\"\n", p->str);
+ break;
+
+ case ASMRP_SYM_HASH:
+ printf ("#\n");
+ break;
+
+ case ASMRP_SYM_SEMICOLON:
+ printf (";\n");
+ break;
+ case ASMRP_SYM_COMMA:
+ printf (",\n");
+ break;
+ case ASMRP_SYM_EQUALS:
+ printf ("==\n");
+ break;
+ case ASMRP_SYM_AND:
+ printf ("&&\n");
+ break;
+ case ASMRP_SYM_OR:
+ printf ("||\n");
+ break;
+ case ASMRP_SYM_LESS:
+ printf ("<\n");
+ break;
+ case ASMRP_SYM_LEQ:
+ printf ("<=\n");
+ break;
+ case ASMRP_SYM_GEQ:
+ printf (">=\n");
+ break;
+ case ASMRP_SYM_GREATER:
+ printf (">\n");
+ break;
+ case ASMRP_SYM_DOLLAR:
+ printf ("$\n");
+ break;
+ case ASMRP_SYM_LPAREN:
+ printf ("(\n");
+ break;
+ case ASMRP_SYM_RPAREN:
+ printf (")\n");
+ break;
+
+ default:
+ printf ("unknown symbol %d\n", p->sym);
+ }
+}
+#endif
+
+static void asmrp_get_sym (asmrp_t *p) {
+
+ while (p->ch <= 32) {
+ if (p->ch == 0) {
+ p->sym = ASMRP_SYM_EOF;
+ return;
+ }
+
+ asmrp_getch (p);
+ }
+
+ if (p->ch == '\\')
+ asmrp_getch (p);
+
+ switch (p->ch) {
+
+ case '#':
+ p->sym = ASMRP_SYM_HASH;
+ asmrp_getch (p);
+ break;
+ case ';':
+ p->sym = ASMRP_SYM_SEMICOLON;
+ asmrp_getch (p);
+ break;
+ case ',':
+ p->sym = ASMRP_SYM_COMMA;
+ asmrp_getch (p);
+ break;
+ case '=':
+ p->sym = ASMRP_SYM_EQUALS;
+ asmrp_getch (p);
+ if (p->ch=='=')
+ asmrp_getch (p);
+ break;
+ case '&':
+ p->sym = ASMRP_SYM_AND;
+ asmrp_getch (p);
+ if (p->ch=='&')
+ asmrp_getch (p);
+ break;
+ case '|':
+ p->sym = ASMRP_SYM_OR;
+ asmrp_getch (p);
+ if (p->ch=='|')
+ asmrp_getch (p);
+ break;
+ case '<':
+ p->sym = ASMRP_SYM_LESS;
+ asmrp_getch (p);
+ if (p->ch=='=') {
+ p->sym = ASMRP_SYM_LEQ;
+ asmrp_getch (p);
+ }
+ break;
+ case '>':
+ p->sym = ASMRP_SYM_GREATER;
+ asmrp_getch (p);
+ if (p->ch=='=') {
+ p->sym = ASMRP_SYM_GEQ;
+ asmrp_getch (p);
+ }
+ break;
+ case '$':
+ p->sym = ASMRP_SYM_DOLLAR;
+ asmrp_getch (p);
+ break;
+ case '(':
+ p->sym = ASMRP_SYM_LPAREN;
+ asmrp_getch (p);
+ break;
+ case ')':
+ p->sym = ASMRP_SYM_RPAREN;
+ asmrp_getch (p);
+ break;
+
+ case '"':
+ asmrp_getch (p);
+ asmrp_string (p);
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ asmrp_number (p);
+ break;
+
+ default:
+ asmrp_identifier (p);
+ }
+
+#ifdef LOG
+ asmrp_print_sym (p);
+#endif
+
+}
+
+static int asmrp_find_id (asmrp_t *p, char *s) {
+
+ int i;
+
+ for (i=0; i<p->sym_tab_num; i++) {
+ if (!strcmp (s, p->sym_tab[i].id))
+ return i;
+ }
+
+ return -1;
+}
+
+static int asmrp_set_id (asmrp_t *p, char *s, int v) {
+
+ int i;
+
+ i = asmrp_find_id (p, s);
+
+ if (i<0) {
+ i = p->sym_tab_num;
+ p->sym_tab_num++;
+ p->sym_tab[i].id = strdup (s);
+
+#ifdef LOG
+ printf ("new symbol '%s'\n", s);
+#endif
+
+ }
+
+ p->sym_tab[i].v = v;
+
+#ifdef LOG
+ printf ("symbol '%s' assigned %d\n", s, v);
+#endif
+
+ return i;
+}
+
+static int asmrp_condition (asmrp_t *p) ;
+
+static int asmrp_operand (asmrp_t *p) {
+
+ int i, ret;
+
+#ifdef LOG
+ printf ("operand\n");
+#endif
+
+ ret = 0;
+
+ switch (p->sym) {
+
+ case ASMRP_SYM_DOLLAR:
+
+ asmrp_get_sym (p);
+
+ if (p->sym != ASMRP_SYM_ID) {
+ printf ("error: identifier expected.\n");
+ abort();
+ }
+
+ i = asmrp_find_id (p, p->str);
+ if (i<0) {
+ printf ("error: unknown identifier %s\n", p->str);
+ }
+ ret = p->sym_tab[i].v;
+
+ asmrp_get_sym (p);
+ break;
+
+ case ASMRP_SYM_NUM:
+ ret = p->num;
+
+ asmrp_get_sym (p);
+ break;
+
+ case ASMRP_SYM_LPAREN:
+ asmrp_get_sym (p);
+
+ ret = asmrp_condition (p);
+
+ if (p->sym != ASMRP_SYM_RPAREN) {
+ printf ("error: ) expected.\n");
+ abort();
+ }
+
+ asmrp_get_sym (p);
+ break;
+
+ default:
+ printf ("syntax error, $ number or ( expected\n");
+ abort();
+ }
+
+#ifdef LOG
+ printf ("operand done, =%d\n", ret);
+#endif
+
+ return ret;
+}
+
+static int asmrp_comp_expression (asmrp_t *p) {
+
+ int a;
+
+#ifdef LOG
+ printf ("comp_expression\n");
+#endif
+
+ a = asmrp_operand (p);
+
+ while ( (p->sym == ASMRP_SYM_LESS)
+ || (p->sym == ASMRP_SYM_LEQ)
+ || (p->sym == ASMRP_SYM_EQUALS)
+ || (p->sym == ASMRP_SYM_GEQ)
+ || (p->sym == ASMRP_SYM_GREATER) ) {
+ int op = p->sym;
+ int b;
+
+ asmrp_get_sym (p);
+
+ b = asmrp_operand (p);
+
+ switch (op) {
+ case ASMRP_SYM_LESS:
+ a = a<b;
+ break;
+ case ASMRP_SYM_LEQ:
+ a = a<=b;
+ break;
+ case ASMRP_SYM_EQUALS:
+ a = a==b;
+ break;
+ case ASMRP_SYM_GEQ:
+ a = a>=b;
+ break;
+ case ASMRP_SYM_GREATER:
+ a = a>b;
+ break;
+ }
+
+ }
+
+#ifdef LOG
+ printf ("comp_expression done = %d\n", a);
+#endif
+ return a;
+}
+
+static int asmrp_condition (asmrp_t *p) {
+
+ int a;
+
+#ifdef LOG
+ printf ("condition\n");
+#endif
+
+ a = asmrp_comp_expression (p);
+
+ while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) {
+ int op, b;
+
+ op = p->sym;
+
+ asmrp_get_sym (p);
+
+ b = asmrp_comp_expression (p);
+
+ switch (op) {
+ case ASMRP_SYM_AND:
+ a = a & b;
+ break;
+ case ASMRP_SYM_OR:
+ a = a | b;
+ break;
+ }
+ }
+
+#ifdef LOG
+ printf ("condition done = %d\n", a);
+#endif
+ return a;
+}
+
+static void asmrp_assignment (asmrp_t *p) {
+
+#ifdef LOG
+ printf ("assignment\n");
+#endif
+
+ if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) {
+#ifdef LOG
+ printf ("empty assignment\n");
+#endif
+ return;
+ }
+
+ if (p->sym != ASMRP_SYM_ID) {
+ printf ("error: identifier expected\n");
+ abort ();
+ }
+ asmrp_get_sym (p);
+
+ if (p->sym != ASMRP_SYM_EQUALS) {
+ printf ("error: = expected\n");
+ abort ();
+ }
+ asmrp_get_sym (p);
+
+ if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
+ && (p->sym != ASMRP_SYM_ID)) {
+ printf ("error: number or string expected\n");
+ abort ();
+ }
+ asmrp_get_sym (p);
+
+#ifdef LOG
+ printf ("assignment done\n");
+#endif
+}
+
+static int asmrp_rule (asmrp_t *p) {
+
+ int ret;
+
+#ifdef LOG
+ printf ("rule\n");
+#endif
+
+ ret = 1;
+
+ if (p->sym == ASMRP_SYM_HASH) {
+
+ asmrp_get_sym (p);
+ ret = asmrp_condition (p);
+
+ while (p->sym == ASMRP_SYM_COMMA) {
+
+ asmrp_get_sym (p);
+
+ asmrp_assignment (p);
+ }
+
+ } else if (p->sym != ASMRP_SYM_SEMICOLON) {
+
+ asmrp_assignment (p);
+
+ while (p->sym == ASMRP_SYM_COMMA) {
+
+ asmrp_get_sym (p);
+ asmrp_assignment (p);
+ }
+ }
+
+#ifdef LOG
+ printf ("rule done = %d\n", ret);
+#endif
+
+ if (p->sym != ASMRP_SYM_SEMICOLON) {
+ printf ("semicolon expected.\n");
+ abort ();
+ }
+
+ asmrp_get_sym (p);
+
+ return ret;
+}
+
+static int asmrp_eval (asmrp_t *p, int *matches) {
+
+ int rule_num, num_matches;
+
+#ifdef LOG
+ printf ("eval\n");
+#endif
+
+ asmrp_get_sym (p);
+
+ rule_num = 0; num_matches = 0;
+ while (p->sym != ASMRP_SYM_EOF) {
+
+ if (asmrp_rule (p)) {
+#ifdef LOG
+ printf ("rule #%d is true\n", rule_num);
+#endif
+ matches[num_matches] = rule_num;
+ num_matches++;
+ }
+
+ rule_num++;
+ }
+
+ matches[num_matches] = -1;
+ return num_matches;
+}
+
+int asmrp_match (const char *rules, int bandwidth, int *matches) {
+
+ asmrp_t *p;
+ int num_matches;
+
+ p = asmrp_new ();
+
+ asmrp_init (p, rules);
+
+ asmrp_set_id (p, "Bandwidth", bandwidth);
+ asmrp_set_id (p, "OldPNMPlayer", 0);
+
+ num_matches = asmrp_eval (p, matches);
+
+ asmrp_dispose (p);
+
+ return num_matches;
+}
+