Mercurial > mplayer.hg
view stream/realrtsp/asmrp.c @ 27808:2988c38b6620
Make sure that linker flags passed as configure parameters appear before
those detected by configure so that the former can override the latter.
patch by Giacomo Comes, comes naic edu
author | diego |
---|---|
date | Tue, 28 Oct 2008 18:00:11 +0000 |
parents | 80ff3962cef4 |
children | 0f1b5b68af32 |
line wrap: on
line source
/* * 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> #include "mp_msg.h" #include "asmrp.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) ) { if(l < ASMRP_MAX_ID - 1) p->str[l++] = p->ch; else mp_msg(MSGT_STREAM, MSGL_ERR, "error: string too long, ignoring char %c.\n", p->ch); 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'))) { if(l < ASMRP_MAX_ID - 1) p->str[l++] = p->ch; else mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier too long, ignoring char %c.\n", p->ch); 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) { if (p->sym_tab_num == ASMRP_MAX_SYMTAB - 1) { mp_msg(MSGT_STREAM, MSGL_ERR, "sym_tab overflow, ignoring identifier %s\n", s); return 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) { mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected.\n"); break; } i = asmrp_find_id (p, p->str); if (i<0) { mp_msg(MSGT_STREAM, MSGL_ERR, "error: unknown identifier %s\n", p->str); } else 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) { mp_msg(MSGT_STREAM, MSGL_ERR, "error: ) expected.\n"); break; } asmrp_get_sym (p); break; default: mp_msg(MSGT_STREAM, MSGL_ERR, "syntax error, $ number or ( expected\n"); } #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) { mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected\n"); return; } asmrp_get_sym (p); if (p->sym != ASMRP_SYM_EQUALS) { mp_msg(MSGT_STREAM, MSGL_ERR, "error: = expected\n"); return; } asmrp_get_sym (p); if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) && (p->sym != ASMRP_SYM_ID)) { mp_msg(MSGT_STREAM, MSGL_ERR, "error: number or string expected\n"); return; } 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) { mp_msg(MSGT_STREAM, MSGL_ERR, "semicolon expected.\n"); return ret; } 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 if(num_matches < MAX_RULEMATCHES - 1) matches[num_matches++] = rule_num; else mp_msg(MSGT_STREAM, MSGL_ERR, "Ignoring matched asm rule %d, too many matched rules.\n", rule_num); } 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; }