Mercurial > mplayer.hg
annotate stream/realrtsp/asmrp.c @ 33959:ef089a8affc6
Perform a wsHandleEvents() when playback ends.
This fixes a redraw problem with the subwindow (video window) image
that could appear twice (on a wrong position).
author | ib |
---|---|
date | Thu, 01 Sep 2011 19:14:11 +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 |