Mercurial > mplayer.hg
annotate stream/realrtsp/asmrp.c @ 34972:445009e9ee8d
When the LUMINANCE16 format is less than 14 bit try to use
a depth texture instead.
On Intel 945 this is vastly faster (after re-enabling the
Z16 support in the driver again for newer versions) due
to no need for any software conversion.
It also has slightly higher precision, good enough for
the 14 and possibly 12 bit formats.
10 and 9 bit formats still look horrible, no idea what
causes this, there is very little information on the internal
precision of the hardware.
It is still useful for those since swscale is faster
converting 10 bit formats to 16 bit than to 8 bit.
author | reimar |
---|---|
date | Wed, 08 Aug 2012 19:18:02 +0000 |
parents | 10eefb258465 |
children |
rev | line source |
---|---|
9922 | 1 /* |
2 * This file was ported to MPlayer from xine CVS asmrp.c,v 1.2 2002/12/17 16:49:48 | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (C) 2002 the xine project | |
7 * | |
8 * This file is part of xine, a free video player. | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
9 * |
9922 | 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. | |
14 * | |
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. | |
19 * | |
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 | |
23 * | |
24 * | |
25 * a parser for real's asm rules | |
26 * | |
27 * grammar for these rules: | |
28 * | |
29 | |
30 rule_book = { rule } | |
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 ')' ) | |
37 | |
38 */ | |
39 | |
40 #include <stdlib.h> | |
41 #include <stdio.h> | |
42 #include <string.h> | |
20701 | 43 #include "mp_msg.h" |
21783
4511c04bc4a0
Fix potential buffer overflow in asm rules matching code
rtogni
parents:
20701
diff
changeset
|
44 #include "asmrp.h" |
9922 | 45 |
46 /* | |
47 #define LOG | |
48 */ | |
49 | |
50 #define ASMRP_SYM_NONE 0 | |
51 #define ASMRP_SYM_EOF 1 | |
52 | |
53 #define ASMRP_SYM_NUM 2 | |
54 #define ASMRP_SYM_ID 3 | |
55 #define ASMRP_SYM_STRING 4 | |
56 | |
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 | |
70 | |
71 #define ASMRP_MAX_ID 1024 | |
72 | |
73 #define ASMRP_MAX_SYMTAB 10 | |
74 | |
75 typedef struct { | |
76 char *id; | |
77 int v; | |
78 } asmrp_sym_t; | |
79 | |
80 typedef struct { | |
81 | |
82 /* public part */ | |
83 | |
84 int sym; | |
85 int num; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
86 |
9922 | 87 char str[ASMRP_MAX_ID]; |
88 | |
89 /* private part */ | |
90 | |
91 char *buf; | |
92 int pos; | |
93 char ch; | |
94 | |
95 asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB]; | |
96 int sym_tab_num; | |
97 | |
98 } asmrp_t; | |
99 | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
13203
diff
changeset
|
100 static asmrp_t *asmrp_new (void) { |
9922 | 101 |
102 asmrp_t *p; | |
103 | |
104 p = malloc (sizeof (asmrp_t)); | |
105 | |
106 p->sym_tab_num = 0; | |
107 p->sym = ASMRP_SYM_NONE; | |
108 | |
109 return p; | |
110 } | |
111 | |
112 static void asmrp_dispose (asmrp_t *p) { | |
113 | |
114 int i; | |
115 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
116 for (i=0; i<p->sym_tab_num; i++) |
9922 | 117 free (p->sym_tab[i].id); |
118 | |
29582 | 119 free(p->buf); |
9922 | 120 free (p); |
121 } | |
122 | |
123 static void asmrp_getch (asmrp_t *p) { | |
124 p->ch = p->buf[p->pos]; | |
125 p->pos++; | |
126 | |
127 #ifdef LOG | |
128 printf ("%c\n", p->ch); | |
129 #endif | |
130 | |
131 } | |
132 | |
133 static void asmrp_init (asmrp_t *p, const char *str) { | |
134 | |
135 p->buf = strdup (str); | |
136 p->pos = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
137 |
9922 | 138 asmrp_getch (p); |
139 } | |
140 | |
141 static void asmrp_number (asmrp_t *p) { | |
142 | |
143 int num; | |
144 | |
145 num = 0; | |
146 while ( (p->ch>='0') && (p->ch<='9') ) { | |
147 | |
148 num = num*10 + (p->ch - '0'); | |
149 | |
150 asmrp_getch (p); | |
151 } | |
152 | |
153 p->sym = ASMRP_SYM_NUM; | |
154 p->num = num; | |
155 } | |
156 | |
157 static void asmrp_string (asmrp_t *p) { | |
158 | |
159 int l; | |
160 | |
161 l = 0; | |
162 | |
163 while ( (p->ch!='"') && (p->ch>=32) ) { | |
164 | |
22185
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
165 if(l < ASMRP_MAX_ID - 1) |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
166 p->str[l++] = p->ch; |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
167 else |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
168 mp_msg(MSGT_STREAM, MSGL_ERR, "error: string too long, ignoring char %c.\n", p->ch); |
9922 | 169 |
170 asmrp_getch (p); | |
171 } | |
172 p->str[l]=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
173 |
9922 | 174 if (p->ch=='"') |
175 asmrp_getch (p); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
176 |
9922 | 177 p->sym = ASMRP_SYM_STRING; |
178 } | |
179 | |
180 static void asmrp_identifier (asmrp_t *p) { | |
181 | |
182 int l; | |
183 | |
184 l = 0; | |
185 | |
186 while ( ((p->ch>='A') && (p->ch<='z')) | |
187 || ((p->ch>='0') && (p->ch<='9'))) { | |
188 | |
22185
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
189 if(l < ASMRP_MAX_ID - 1) |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
190 p->str[l++] = p->ch; |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
191 else |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
192 mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier too long, ignoring char %c.\n", p->ch); |
9922 | 193 |
194 asmrp_getch (p); | |
195 } | |
196 p->str[l]=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
197 |
9922 | 198 p->sym = ASMRP_SYM_ID; |
199 } | |
200 | |
201 #ifdef LOG | |
202 static void asmrp_print_sym (asmrp_t *p) { | |
203 | |
204 printf ("symbol: "); | |
205 | |
206 switch (p->sym) { | |
207 | |
208 case ASMRP_SYM_NONE: | |
209 printf ("NONE\n"); | |
210 break; | |
211 | |
212 case ASMRP_SYM_EOF: | |
213 printf ("EOF\n"); | |
214 break; | |
215 | |
216 case ASMRP_SYM_NUM: | |
217 printf ("NUM %d\n", p->num); | |
218 break; | |
219 | |
220 case ASMRP_SYM_ID: | |
221 printf ("ID '%s'\n", p->str); | |
222 break; | |
223 | |
224 case ASMRP_SYM_STRING: | |
225 printf ("STRING \"%s\"\n", p->str); | |
226 break; | |
227 | |
228 case ASMRP_SYM_HASH: | |
229 printf ("#\n"); | |
230 break; | |
231 | |
232 case ASMRP_SYM_SEMICOLON: | |
233 printf (";\n"); | |
234 break; | |
235 case ASMRP_SYM_COMMA: | |
236 printf (",\n"); | |
237 break; | |
238 case ASMRP_SYM_EQUALS: | |
239 printf ("==\n"); | |
240 break; | |
241 case ASMRP_SYM_AND: | |
242 printf ("&&\n"); | |
243 break; | |
244 case ASMRP_SYM_OR: | |
245 printf ("||\n"); | |
246 break; | |
247 case ASMRP_SYM_LESS: | |
248 printf ("<\n"); | |
249 break; | |
250 case ASMRP_SYM_LEQ: | |
251 printf ("<=\n"); | |
252 break; | |
253 case ASMRP_SYM_GEQ: | |
254 printf (">=\n"); | |
255 break; | |
256 case ASMRP_SYM_GREATER: | |
257 printf (">\n"); | |
258 break; | |
259 case ASMRP_SYM_DOLLAR: | |
260 printf ("$\n"); | |
261 break; | |
262 case ASMRP_SYM_LPAREN: | |
263 printf ("(\n"); | |
264 break; | |
265 case ASMRP_SYM_RPAREN: | |
266 printf (")\n"); | |
267 break; | |
268 | |
269 default: | |
270 printf ("unknown symbol %d\n", p->sym); | |
271 } | |
272 } | |
273 #endif | |
274 | |
275 static void asmrp_get_sym (asmrp_t *p) { | |
276 | |
277 while (p->ch <= 32) { | |
278 if (p->ch == 0) { | |
279 p->sym = ASMRP_SYM_EOF; | |
280 return; | |
281 } | |
282 | |
283 asmrp_getch (p); | |
284 } | |
285 | |
286 if (p->ch == '\\') | |
287 asmrp_getch (p); | |
288 | |
289 switch (p->ch) { | |
290 | |
291 case '#': | |
292 p->sym = ASMRP_SYM_HASH; | |
293 asmrp_getch (p); | |
294 break; | |
295 case ';': | |
296 p->sym = ASMRP_SYM_SEMICOLON; | |
297 asmrp_getch (p); | |
298 break; | |
299 case ',': | |
300 p->sym = ASMRP_SYM_COMMA; | |
301 asmrp_getch (p); | |
302 break; | |
303 case '=': | |
304 p->sym = ASMRP_SYM_EQUALS; | |
305 asmrp_getch (p); | |
306 if (p->ch=='=') | |
307 asmrp_getch (p); | |
308 break; | |
309 case '&': | |
310 p->sym = ASMRP_SYM_AND; | |
311 asmrp_getch (p); | |
312 if (p->ch=='&') | |
313 asmrp_getch (p); | |
314 break; | |
315 case '|': | |
316 p->sym = ASMRP_SYM_OR; | |
317 asmrp_getch (p); | |
318 if (p->ch=='|') | |
319 asmrp_getch (p); | |
320 break; | |
321 case '<': | |
322 p->sym = ASMRP_SYM_LESS; | |
323 asmrp_getch (p); | |
324 if (p->ch=='=') { | |
325 p->sym = ASMRP_SYM_LEQ; | |
326 asmrp_getch (p); | |
327 } | |
328 break; | |
329 case '>': | |
330 p->sym = ASMRP_SYM_GREATER; | |
331 asmrp_getch (p); | |
332 if (p->ch=='=') { | |
333 p->sym = ASMRP_SYM_GEQ; | |
334 asmrp_getch (p); | |
335 } | |
336 break; | |
337 case '$': | |
338 p->sym = ASMRP_SYM_DOLLAR; | |
339 asmrp_getch (p); | |
340 break; | |
341 case '(': | |
342 p->sym = ASMRP_SYM_LPAREN; | |
343 asmrp_getch (p); | |
344 break; | |
345 case ')': | |
346 p->sym = ASMRP_SYM_RPAREN; | |
347 asmrp_getch (p); | |
348 break; | |
349 | |
350 case '"': | |
351 asmrp_getch (p); | |
352 asmrp_string (p); | |
353 break; | |
354 | |
355 case '0': case '1': case '2': case '3': case '4': | |
356 case '5': case '6': case '7': case '8': case '9': | |
357 asmrp_number (p); | |
358 break; | |
359 | |
360 default: | |
361 asmrp_identifier (p); | |
362 } | |
363 | |
364 #ifdef LOG | |
365 asmrp_print_sym (p); | |
366 #endif | |
367 | |
368 } | |
369 | |
370 static int asmrp_find_id (asmrp_t *p, char *s) { | |
371 | |
372 int i; | |
373 | |
374 for (i=0; i<p->sym_tab_num; i++) { | |
375 if (!strcmp (s, p->sym_tab[i].id)) | |
376 return i; | |
377 } | |
378 | |
379 return -1; | |
380 } | |
381 | |
382 static int asmrp_set_id (asmrp_t *p, char *s, int v) { | |
383 | |
384 int i; | |
385 | |
386 i = asmrp_find_id (p, s); | |
387 | |
388 if (i<0) { | |
22185
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
389 if (p->sym_tab_num == ASMRP_MAX_SYMTAB - 1) { |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
390 mp_msg(MSGT_STREAM, MSGL_ERR, "sym_tab overflow, ignoring identifier %s\n", s); |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
391 return 0; |
80ff3962cef4
More boundary checks for fixed-length arrays. Some of them may have been
rtogni
parents:
21787
diff
changeset
|
392 } |
9922 | 393 i = p->sym_tab_num; |
394 p->sym_tab_num++; | |
395 p->sym_tab[i].id = strdup (s); | |
396 | |
397 #ifdef LOG | |
398 printf ("new symbol '%s'\n", s); | |
399 #endif | |
400 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
401 } |
9922 | 402 |
403 p->sym_tab[i].v = v; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
404 |
9922 | 405 #ifdef LOG |
406 printf ("symbol '%s' assigned %d\n", s, v); | |
407 #endif | |
408 | |
409 return i; | |
410 } | |
411 | |
412 static int asmrp_condition (asmrp_t *p) ; | |
413 | |
414 static int asmrp_operand (asmrp_t *p) { | |
415 | |
416 int i, ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
417 |
9922 | 418 #ifdef LOG |
419 printf ("operand\n"); | |
420 #endif | |
421 | |
422 ret = 0; | |
423 | |
424 switch (p->sym) { | |
425 | |
426 case ASMRP_SYM_DOLLAR: | |
427 | |
428 asmrp_get_sym (p); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
429 |
9922 | 430 if (p->sym != ASMRP_SYM_ID) { |
20699 | 431 mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected.\n"); |
20697 | 432 break; |
9922 | 433 } |
434 | |
435 i = asmrp_find_id (p, p->str); | |
436 if (i<0) { | |
20699 | 437 mp_msg(MSGT_STREAM, MSGL_ERR, "error: unknown identifier %s\n", p->str); |
21787
899739212237
Fix invalid memory access if identifier is unknown
rtogni
parents:
21783
diff
changeset
|
438 } else |
9922 | 439 ret = p->sym_tab[i].v; |
440 | |
441 asmrp_get_sym (p); | |
442 break; | |
443 | |
444 case ASMRP_SYM_NUM: | |
445 ret = p->num; | |
446 | |
447 asmrp_get_sym (p); | |
448 break; | |
449 | |
450 case ASMRP_SYM_LPAREN: | |
451 asmrp_get_sym (p); | |
452 | |
453 ret = asmrp_condition (p); | |
454 | |
455 if (p->sym != ASMRP_SYM_RPAREN) { | |
20699 | 456 mp_msg(MSGT_STREAM, MSGL_ERR, "error: ) expected.\n"); |
20697 | 457 break; |
9922 | 458 } |
459 | |
460 asmrp_get_sym (p); | |
461 break; | |
462 | |
463 default: | |
20699 | 464 mp_msg(MSGT_STREAM, MSGL_ERR, "syntax error, $ number or ( expected\n"); |
9922 | 465 } |
466 | |
467 #ifdef LOG | |
468 printf ("operand done, =%d\n", ret); | |
469 #endif | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
470 |
9922 | 471 return ret; |
472 } | |
473 | |
20697 | 474 |
9922 | 475 static int asmrp_comp_expression (asmrp_t *p) { |
476 | |
477 int a; | |
478 | |
479 #ifdef LOG | |
480 printf ("comp_expression\n"); | |
481 #endif | |
482 | |
483 a = asmrp_operand (p); | |
484 | |
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) ) { | |
490 int op = p->sym; | |
491 int b; | |
492 | |
493 asmrp_get_sym (p); | |
494 | |
495 b = asmrp_operand (p); | |
496 | |
497 switch (op) { | |
498 case ASMRP_SYM_LESS: | |
499 a = a<b; | |
500 break; | |
501 case ASMRP_SYM_LEQ: | |
502 a = a<=b; | |
503 break; | |
504 case ASMRP_SYM_EQUALS: | |
505 a = a==b; | |
506 break; | |
507 case ASMRP_SYM_GEQ: | |
508 a = a>=b; | |
509 break; | |
510 case ASMRP_SYM_GREATER: | |
511 a = a>b; | |
512 break; | |
513 } | |
514 | |
515 } | |
516 | |
517 #ifdef LOG | |
518 printf ("comp_expression done = %d\n", a); | |
519 #endif | |
520 return a; | |
521 } | |
522 | |
523 static int asmrp_condition (asmrp_t *p) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
524 |
9922 | 525 int a; |
526 | |
527 #ifdef LOG | |
528 printf ("condition\n"); | |
529 #endif | |
530 | |
531 a = asmrp_comp_expression (p); | |
532 | |
533 while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) { | |
534 int op, b; | |
535 | |
536 op = p->sym; | |
537 | |
538 asmrp_get_sym (p); | |
539 | |
540 b = asmrp_comp_expression (p); | |
541 | |
542 switch (op) { | |
543 case ASMRP_SYM_AND: | |
544 a = a & b; | |
545 break; | |
546 case ASMRP_SYM_OR: | |
547 a = a | b; | |
548 break; | |
549 } | |
550 } | |
551 | |
552 #ifdef LOG | |
553 printf ("condition done = %d\n", a); | |
554 #endif | |
555 return a; | |
556 } | |
557 | |
558 static void asmrp_assignment (asmrp_t *p) { | |
559 | |
560 #ifdef LOG | |
561 printf ("assignment\n"); | |
562 #endif | |
563 | |
13203
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
564 if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) { |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
565 #ifdef LOG |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
566 printf ("empty assignment\n"); |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
567 #endif |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
568 return; |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
569 } |
0d38a501c6a5
allow empty assignments, necessary for some weird servers...
reimar
parents:
9922
diff
changeset
|
570 |
9922 | 571 if (p->sym != ASMRP_SYM_ID) { |
20699 | 572 mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected\n"); |
20697 | 573 return; |
9922 | 574 } |
575 asmrp_get_sym (p); | |
576 | |
577 if (p->sym != ASMRP_SYM_EQUALS) { | |
20699 | 578 mp_msg(MSGT_STREAM, MSGL_ERR, "error: = expected\n"); |
20697 | 579 return; |
9922 | 580 } |
581 asmrp_get_sym (p); | |
582 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
583 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) |
9922 | 584 && (p->sym != ASMRP_SYM_ID)) { |
20699 | 585 mp_msg(MSGT_STREAM, MSGL_ERR, "error: number or string expected\n"); |
20697 | 586 return; |
9922 | 587 } |
588 asmrp_get_sym (p); | |
589 | |
590 #ifdef LOG | |
591 printf ("assignment done\n"); | |
592 #endif | |
593 } | |
594 | |
595 static int asmrp_rule (asmrp_t *p) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
596 |
9922 | 597 int ret; |
598 | |
599 #ifdef LOG | |
600 printf ("rule\n"); | |
601 #endif | |
602 | |
603 ret = 1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
604 |
9922 | 605 if (p->sym == ASMRP_SYM_HASH) { |
606 | |
607 asmrp_get_sym (p); | |
608 ret = asmrp_condition (p); | |
609 | |
610 while (p->sym == ASMRP_SYM_COMMA) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
611 |
9922 | 612 asmrp_get_sym (p); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
22185
diff
changeset
|
613 |
9922 | 614 asmrp_assignment (p); |
615 } | |
616 | |
617 } else if (p->sym != ASMRP_SYM_SEMICOLON) { | |
618 | |
619 asmrp_assignment (p); | |
620 | |
621 while (p->sym == ASMRP_SYM_COMMA) { | |
622 | |
623 asmrp_get_sym (p); | |
624 asmrp_assignment (p); | |
625 } | |
626 } | |
627 | |
628 #ifdef LOG | |
629 printf ("rule done = %d\n", ret); | |
630 #endif | |
631 | |
632 if (p->sym != ASMRP_SYM_SEMICOLON) { | |
20699 | 633 mp_msg(MSGT_STREAM, MSGL_ERR, "semicolon expected.\n"); |
20697 | 634 return ret; |
9922 | 635 } |
636 | |
637 asmrp_get_sym (p); | |
638 | |
639 return ret; | |
640 } | |
641 | |
642 static int asmrp_eval (asmrp_t *p, int *matches) { | |
643 | |
644 int rule_num, num_matches; | |
645 | |
646 #ifdef LOG | |
647 printf ("eval\n"); | |
648 #endif | |
649 | |
650 asmrp_get_sym (p); | |
651 | |
652 rule_num = 0; num_matches = 0; | |
653 while (p->sym != ASMRP_SYM_EOF) { | |
654 | |
655 if (asmrp_rule (p)) { | |
656 #ifdef LOG | |
657 printf ("rule #%d is true\n", rule_num); | |
658 #endif | |
21783
4511c04bc4a0
Fix potential buffer overflow in asm rules matching code
rtogni
parents:
20701
diff
changeset
|
659 if(num_matches < MAX_RULEMATCHES - 1) |
4511c04bc4a0
Fix potential buffer overflow in asm rules matching code
rtogni
parents:
20701
diff
changeset
|
660 matches[num_matches++] = rule_num; |
4511c04bc4a0
Fix potential buffer overflow in asm rules matching code
rtogni
parents:
20701
diff
changeset
|
661 else |
4511c04bc4a0
Fix potential buffer overflow in asm rules matching code
rtogni
parents:
20701
diff
changeset
|
662 mp_msg(MSGT_STREAM, MSGL_ERR, |
4511c04bc4a0
Fix potential buffer overflow in asm rules matching code
rtogni
parents:
20701
diff
changeset
|
663 "Ignoring matched asm rule %d, too many matched rules.\n", rule_num); |
9922 | 664 } |
665 | |
666 rule_num++; | |
667 } | |
668 | |
669 matches[num_matches] = -1; | |
670 return num_matches; | |
671 } | |
672 | |
673 int asmrp_match (const char *rules, int bandwidth, int *matches) { | |
674 | |
675 asmrp_t *p; | |
676 int num_matches; | |
677 | |
678 p = asmrp_new (); | |
679 | |
680 asmrp_init (p, rules); | |
681 | |
682 asmrp_set_id (p, "Bandwidth", bandwidth); | |
683 asmrp_set_id (p, "OldPNMPlayer", 0); | |
684 | |
685 num_matches = asmrp_eval (p, matches); | |
686 | |
687 asmrp_dispose (p); | |
688 | |
689 return num_matches; | |
690 } | |
691 |