Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.16-rc6 983 lines 19 kB view raw
1%define api.pure full 2%parse-param {void *_parse_state} 3%parse-param {void *scanner} 4%lex-param {void* scanner} 5%locations 6 7%{ 8 9#define YYDEBUG 1 10 11#include <fnmatch.h> 12#include <stdio.h> 13#include <linux/compiler.h> 14#include <linux/types.h> 15#include <linux/zalloc.h> 16#include "pmu.h" 17#include "evsel.h" 18#include "parse-events.h" 19#include "parse-events-bison.h" 20 21void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); 22 23#define ABORT_ON(val) \ 24do { \ 25 if (val) \ 26 YYABORT; \ 27} while (0) 28 29static struct list_head* alloc_list(void) 30{ 31 struct list_head *list; 32 33 list = malloc(sizeof(*list)); 34 if (!list) 35 return NULL; 36 37 INIT_LIST_HEAD(list); 38 return list; 39} 40 41static void free_list_evsel(struct list_head* list_evsel) 42{ 43 struct evsel *evsel, *tmp; 44 45 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) { 46 list_del_init(&evsel->core.node); 47 evsel__delete(evsel); 48 } 49 free(list_evsel); 50} 51 52static void inc_group_count(struct list_head *list, 53 struct parse_events_state *parse_state) 54{ 55 /* Count groups only have more than 1 members */ 56 if (!list_is_last(list->next, list)) 57 parse_state->nr_groups++; 58} 59 60%} 61 62%token PE_START_EVENTS PE_START_TERMS 63%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM 64%token PE_VALUE_SYM_TOOL 65%token PE_EVENT_NAME 66%token PE_NAME 67%token PE_BPF_OBJECT PE_BPF_SOURCE 68%token PE_MODIFIER_EVENT PE_MODIFIER_BP 69%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 70%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 71%token PE_ERROR 72%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE 73%token PE_ARRAY_ALL PE_ARRAY_RANGE 74%token PE_DRV_CFG_TERM 75%type <num> PE_VALUE 76%type <num> PE_VALUE_SYM_HW 77%type <num> PE_VALUE_SYM_SW 78%type <num> PE_VALUE_SYM_TOOL 79%type <num> PE_RAW 80%type <num> PE_TERM 81%type <num> value_sym 82%type <str> PE_NAME 83%type <str> PE_BPF_OBJECT 84%type <str> PE_BPF_SOURCE 85%type <str> PE_NAME_CACHE_TYPE 86%type <str> PE_NAME_CACHE_OP_RESULT 87%type <str> PE_MODIFIER_EVENT 88%type <str> PE_MODIFIER_BP 89%type <str> PE_EVENT_NAME 90%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE 91%type <str> PE_DRV_CFG_TERM 92%type <str> event_pmu_name 93%destructor { free ($$); } <str> 94%type <term> event_term 95%destructor { parse_events_term__delete ($$); } <term> 96%type <list_terms> event_config 97%type <list_terms> opt_event_config 98%type <list_terms> opt_pmu_config 99%destructor { parse_events_terms__delete ($$); } <list_terms> 100%type <list_evsel> event_pmu 101%type <list_evsel> event_legacy_symbol 102%type <list_evsel> event_legacy_cache 103%type <list_evsel> event_legacy_mem 104%type <list_evsel> event_legacy_tracepoint 105%type <list_evsel> event_legacy_numeric 106%type <list_evsel> event_legacy_raw 107%type <list_evsel> event_bpf_file 108%type <list_evsel> event_def 109%type <list_evsel> event_mod 110%type <list_evsel> event_name 111%type <list_evsel> event 112%type <list_evsel> events 113%type <list_evsel> group_def 114%type <list_evsel> group 115%type <list_evsel> groups 116%destructor { free_list_evsel ($$); } <list_evsel> 117%type <tracepoint_name> tracepoint_name 118%destructor { free ($$.sys); free ($$.event); } <tracepoint_name> 119%type <array> array 120%type <array> array_term 121%type <array> array_terms 122%destructor { free ($$.ranges); } <array> 123 124%union 125{ 126 char *str; 127 u64 num; 128 struct list_head *list_evsel; 129 struct list_head *list_terms; 130 struct parse_events_term *term; 131 struct tracepoint_name { 132 char *sys; 133 char *event; 134 } tracepoint_name; 135 struct parse_events_array array; 136} 137%% 138 139start: 140PE_START_EVENTS start_events 141| 142PE_START_TERMS start_terms 143 144start_events: groups 145{ 146 struct parse_events_state *parse_state = _parse_state; 147 148 /* frees $1 */ 149 parse_events_update_lists($1, &parse_state->list); 150} 151 152groups: 153groups ',' group 154{ 155 struct list_head *list = $1; 156 struct list_head *group = $3; 157 158 /* frees $3 */ 159 parse_events_update_lists(group, list); 160 $$ = list; 161} 162| 163groups ',' event 164{ 165 struct list_head *list = $1; 166 struct list_head *event = $3; 167 168 /* frees $3 */ 169 parse_events_update_lists(event, list); 170 $$ = list; 171} 172| 173group 174| 175event 176 177group: 178group_def ':' PE_MODIFIER_EVENT 179{ 180 struct list_head *list = $1; 181 int err; 182 183 err = parse_events__modifier_group(list, $3); 184 free($3); 185 if (err) { 186 struct parse_events_state *parse_state = _parse_state; 187 struct parse_events_error *error = parse_state->error; 188 189 parse_events_error__handle(error, @3.first_column, 190 strdup("Bad modifier"), NULL); 191 free_list_evsel(list); 192 YYABORT; 193 } 194 $$ = list; 195} 196| 197group_def 198 199group_def: 200PE_NAME '{' events '}' 201{ 202 struct list_head *list = $3; 203 204 inc_group_count(list, _parse_state); 205 parse_events__set_leader($1, list, _parse_state); 206 free($1); 207 $$ = list; 208} 209| 210'{' events '}' 211{ 212 struct list_head *list = $2; 213 214 inc_group_count(list, _parse_state); 215 parse_events__set_leader(NULL, list, _parse_state); 216 $$ = list; 217} 218 219events: 220events ',' event 221{ 222 struct list_head *event = $3; 223 struct list_head *list = $1; 224 225 /* frees $3 */ 226 parse_events_update_lists(event, list); 227 $$ = list; 228} 229| 230event 231 232event: event_mod 233 234event_mod: 235event_name PE_MODIFIER_EVENT 236{ 237 struct list_head *list = $1; 238 int err; 239 240 /* 241 * Apply modifier on all events added by single event definition 242 * (there could be more events added for multiple tracepoint 243 * definitions via '*?'. 244 */ 245 err = parse_events__modifier_event(list, $2, false); 246 free($2); 247 if (err) { 248 struct parse_events_state *parse_state = _parse_state; 249 struct parse_events_error *error = parse_state->error; 250 251 parse_events_error__handle(error, @2.first_column, 252 strdup("Bad modifier"), NULL); 253 free_list_evsel(list); 254 YYABORT; 255 } 256 $$ = list; 257} 258| 259event_name 260 261event_name: 262PE_EVENT_NAME event_def 263{ 264 int err; 265 266 err = parse_events_name($2, $1); 267 free($1); 268 if (err) { 269 free_list_evsel($2); 270 YYABORT; 271 } 272 $$ = $2; 273} 274| 275event_def 276 277event_def: event_pmu | 278 event_legacy_symbol | 279 event_legacy_cache sep_dc | 280 event_legacy_mem | 281 event_legacy_tracepoint sep_dc | 282 event_legacy_numeric sep_dc | 283 event_legacy_raw sep_dc | 284 event_bpf_file 285 286event_pmu_name: 287PE_NAME | PE_PMU_EVENT_PRE 288 289event_pmu: 290event_pmu_name opt_pmu_config 291{ 292 struct parse_events_state *parse_state = _parse_state; 293 struct parse_events_error *error = parse_state->error; 294 struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL; 295 char *pattern = NULL; 296 297#define CLEANUP_YYABORT \ 298 do { \ 299 parse_events_terms__delete($2); \ 300 parse_events_terms__delete(orig_terms); \ 301 free(list); \ 302 free($1); \ 303 free(pattern); \ 304 YYABORT; \ 305 } while(0) 306 307 if (parse_events_copy_term_list($2, &orig_terms)) 308 CLEANUP_YYABORT; 309 310 if (error) 311 error->idx = @1.first_column; 312 313 list = alloc_list(); 314 if (!list) 315 CLEANUP_YYABORT; 316 if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { 317 struct perf_pmu *pmu = NULL; 318 int ok = 0; 319 320 if (asprintf(&pattern, "%s*", $1) < 0) 321 CLEANUP_YYABORT; 322 323 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 324 char *name = pmu->name; 325 326 if (!strncmp(name, "uncore_", 7) && 327 strncmp($1, "uncore_", 7)) 328 name += 7; 329 if (!perf_pmu__match(pattern, name, $1) || 330 !perf_pmu__match(pattern, pmu->alias_name, $1)) { 331 if (parse_events_copy_term_list(orig_terms, &terms)) 332 CLEANUP_YYABORT; 333 if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false)) 334 ok++; 335 parse_events_terms__delete(terms); 336 } 337 } 338 339 if (!ok) 340 CLEANUP_YYABORT; 341 } 342 parse_events_terms__delete($2); 343 parse_events_terms__delete(orig_terms); 344 free(pattern); 345 free($1); 346 $$ = list; 347#undef CLEANUP_YYABORT 348} 349| 350PE_KERNEL_PMU_EVENT sep_dc 351{ 352 struct list_head *list; 353 int err; 354 355 err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list); 356 free($1); 357 if (err < 0) 358 YYABORT; 359 $$ = list; 360} 361| 362PE_KERNEL_PMU_EVENT opt_pmu_config 363{ 364 struct list_head *list; 365 int err; 366 367 /* frees $2 */ 368 err = parse_events_multi_pmu_add(_parse_state, $1, $2, &list); 369 free($1); 370 if (err < 0) 371 YYABORT; 372 $$ = list; 373} 374| 375PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc 376{ 377 struct list_head *list; 378 char pmu_name[128]; 379 380 snprintf(pmu_name, sizeof(pmu_name), "%s-%s", $1, $3); 381 free($1); 382 free($3); 383 if (parse_events_multi_pmu_add(_parse_state, pmu_name, NULL, &list) < 0) 384 YYABORT; 385 $$ = list; 386} 387| 388PE_PMU_EVENT_FAKE sep_dc 389{ 390 struct list_head *list; 391 int err; 392 393 list = alloc_list(); 394 if (!list) 395 YYABORT; 396 397 err = parse_events_add_pmu(_parse_state, list, $1, NULL, false, false); 398 free($1); 399 if (err < 0) { 400 free(list); 401 YYABORT; 402 } 403 $$ = list; 404} 405| 406PE_PMU_EVENT_FAKE opt_pmu_config 407{ 408 struct list_head *list; 409 int err; 410 411 list = alloc_list(); 412 if (!list) 413 YYABORT; 414 415 err = parse_events_add_pmu(_parse_state, list, $1, $2, false, false); 416 free($1); 417 parse_events_terms__delete($2); 418 if (err < 0) { 419 free(list); 420 YYABORT; 421 } 422 $$ = list; 423} 424 425value_sym: 426PE_VALUE_SYM_HW 427| 428PE_VALUE_SYM_SW 429 430event_legacy_symbol: 431value_sym '/' event_config '/' 432{ 433 struct list_head *list; 434 int type = $1 >> 16; 435 int config = $1 & 255; 436 int err; 437 438 list = alloc_list(); 439 ABORT_ON(!list); 440 err = parse_events_add_numeric(_parse_state, list, type, config, $3); 441 parse_events_terms__delete($3); 442 if (err) { 443 free_list_evsel(list); 444 YYABORT; 445 } 446 $$ = list; 447} 448| 449value_sym sep_slash_slash_dc 450{ 451 struct list_head *list; 452 int type = $1 >> 16; 453 int config = $1 & 255; 454 455 list = alloc_list(); 456 ABORT_ON(!list); 457 ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); 458 $$ = list; 459} 460| 461PE_VALUE_SYM_TOOL sep_slash_slash_dc 462{ 463 struct list_head *list; 464 465 list = alloc_list(); 466 ABORT_ON(!list); 467 ABORT_ON(parse_events_add_tool(_parse_state, list, $1)); 468 $$ = list; 469} 470 471event_legacy_cache: 472PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config 473{ 474 struct parse_events_state *parse_state = _parse_state; 475 struct parse_events_error *error = parse_state->error; 476 struct list_head *list; 477 int err; 478 479 list = alloc_list(); 480 ABORT_ON(!list); 481 err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6, 482 parse_state); 483 parse_events_terms__delete($6); 484 free($1); 485 free($3); 486 free($5); 487 if (err) { 488 free_list_evsel(list); 489 YYABORT; 490 } 491 $$ = list; 492} 493| 494PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config 495{ 496 struct parse_events_state *parse_state = _parse_state; 497 struct parse_events_error *error = parse_state->error; 498 struct list_head *list; 499 int err; 500 501 list = alloc_list(); 502 ABORT_ON(!list); 503 err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4, 504 parse_state); 505 parse_events_terms__delete($4); 506 free($1); 507 free($3); 508 if (err) { 509 free_list_evsel(list); 510 YYABORT; 511 } 512 $$ = list; 513} 514| 515PE_NAME_CACHE_TYPE opt_event_config 516{ 517 struct parse_events_state *parse_state = _parse_state; 518 struct parse_events_error *error = parse_state->error; 519 struct list_head *list; 520 int err; 521 522 list = alloc_list(); 523 ABORT_ON(!list); 524 err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2, 525 parse_state); 526 parse_events_terms__delete($2); 527 free($1); 528 if (err) { 529 free_list_evsel(list); 530 YYABORT; 531 } 532 $$ = list; 533} 534 535event_legacy_mem: 536PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc 537{ 538 struct parse_events_state *parse_state = _parse_state; 539 struct list_head *list; 540 int err; 541 542 list = alloc_list(); 543 ABORT_ON(!list); 544 err = parse_events_add_breakpoint(list, &parse_state->idx, 545 $2, $6, $4); 546 free($6); 547 if (err) { 548 free(list); 549 YYABORT; 550 } 551 $$ = list; 552} 553| 554PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc 555{ 556 struct parse_events_state *parse_state = _parse_state; 557 struct list_head *list; 558 559 list = alloc_list(); 560 ABORT_ON(!list); 561 if (parse_events_add_breakpoint(list, &parse_state->idx, 562 $2, NULL, $4)) { 563 free(list); 564 YYABORT; 565 } 566 $$ = list; 567} 568| 569PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc 570{ 571 struct parse_events_state *parse_state = _parse_state; 572 struct list_head *list; 573 int err; 574 575 list = alloc_list(); 576 ABORT_ON(!list); 577 err = parse_events_add_breakpoint(list, &parse_state->idx, 578 $2, $4, 0); 579 free($4); 580 if (err) { 581 free(list); 582 YYABORT; 583 } 584 $$ = list; 585} 586| 587PE_PREFIX_MEM PE_VALUE sep_dc 588{ 589 struct parse_events_state *parse_state = _parse_state; 590 struct list_head *list; 591 592 list = alloc_list(); 593 ABORT_ON(!list); 594 if (parse_events_add_breakpoint(list, &parse_state->idx, 595 $2, NULL, 0)) { 596 free(list); 597 YYABORT; 598 } 599 $$ = list; 600} 601 602event_legacy_tracepoint: 603tracepoint_name opt_event_config 604{ 605 struct parse_events_state *parse_state = _parse_state; 606 struct parse_events_error *error = parse_state->error; 607 struct list_head *list; 608 int err; 609 610 list = alloc_list(); 611 ABORT_ON(!list); 612 if (error) 613 error->idx = @1.first_column; 614 615 err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, 616 error, $2); 617 618 parse_events_terms__delete($2); 619 free($1.sys); 620 free($1.event); 621 if (err) { 622 free(list); 623 YYABORT; 624 } 625 $$ = list; 626} 627 628tracepoint_name: 629PE_NAME '-' PE_NAME ':' PE_NAME 630{ 631 struct tracepoint_name tracepoint; 632 633 ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0); 634 tracepoint.event = $5; 635 free($1); 636 free($3); 637 $$ = tracepoint; 638} 639| 640PE_NAME ':' PE_NAME 641{ 642 struct tracepoint_name tracepoint = {$1, $3}; 643 644 $$ = tracepoint; 645} 646 647event_legacy_numeric: 648PE_VALUE ':' PE_VALUE opt_event_config 649{ 650 struct list_head *list; 651 int err; 652 653 list = alloc_list(); 654 ABORT_ON(!list); 655 err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4); 656 parse_events_terms__delete($4); 657 if (err) { 658 free(list); 659 YYABORT; 660 } 661 $$ = list; 662} 663 664event_legacy_raw: 665PE_RAW opt_event_config 666{ 667 struct list_head *list; 668 int err; 669 670 list = alloc_list(); 671 ABORT_ON(!list); 672 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2); 673 parse_events_terms__delete($2); 674 if (err) { 675 free(list); 676 YYABORT; 677 } 678 $$ = list; 679} 680 681event_bpf_file: 682PE_BPF_OBJECT opt_event_config 683{ 684 struct parse_events_state *parse_state = _parse_state; 685 struct list_head *list; 686 int err; 687 688 list = alloc_list(); 689 ABORT_ON(!list); 690 err = parse_events_load_bpf(parse_state, list, $1, false, $2); 691 parse_events_terms__delete($2); 692 free($1); 693 if (err) { 694 free(list); 695 YYABORT; 696 } 697 $$ = list; 698} 699| 700PE_BPF_SOURCE opt_event_config 701{ 702 struct list_head *list; 703 int err; 704 705 list = alloc_list(); 706 ABORT_ON(!list); 707 err = parse_events_load_bpf(_parse_state, list, $1, true, $2); 708 parse_events_terms__delete($2); 709 if (err) { 710 free(list); 711 YYABORT; 712 } 713 $$ = list; 714} 715 716opt_event_config: 717'/' event_config '/' 718{ 719 $$ = $2; 720} 721| 722'/' '/' 723{ 724 $$ = NULL; 725} 726| 727{ 728 $$ = NULL; 729} 730 731opt_pmu_config: 732'/' event_config '/' 733{ 734 $$ = $2; 735} 736| 737'/' '/' 738{ 739 $$ = NULL; 740} 741 742start_terms: event_config 743{ 744 struct parse_events_state *parse_state = _parse_state; 745 if (parse_state->terms) { 746 parse_events_terms__delete ($1); 747 YYABORT; 748 } 749 parse_state->terms = $1; 750} 751 752event_config: 753event_config ',' event_term 754{ 755 struct list_head *head = $1; 756 struct parse_events_term *term = $3; 757 758 if (!head) { 759 parse_events_term__delete(term); 760 YYABORT; 761 } 762 list_add_tail(&term->list, head); 763 $$ = $1; 764} 765| 766event_term 767{ 768 struct list_head *head = malloc(sizeof(*head)); 769 struct parse_events_term *term = $1; 770 771 ABORT_ON(!head); 772 INIT_LIST_HEAD(head); 773 list_add_tail(&term->list, head); 774 $$ = head; 775} 776 777event_term: 778PE_RAW 779{ 780 struct parse_events_term *term; 781 782 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG, 783 NULL, $1, false, &@1, NULL)); 784 $$ = term; 785} 786| 787PE_NAME '=' PE_NAME 788{ 789 struct parse_events_term *term; 790 791 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 792 $1, $3, &@1, &@3)) { 793 free($1); 794 free($3); 795 YYABORT; 796 } 797 $$ = term; 798} 799| 800PE_NAME '=' PE_VALUE 801{ 802 struct parse_events_term *term; 803 804 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 805 $1, $3, false, &@1, &@3)) { 806 free($1); 807 YYABORT; 808 } 809 $$ = term; 810} 811| 812PE_NAME '=' PE_VALUE_SYM_HW 813{ 814 struct parse_events_term *term; 815 int config = $3 & 255; 816 817 if (parse_events_term__sym_hw(&term, $1, config)) { 818 free($1); 819 YYABORT; 820 } 821 $$ = term; 822} 823| 824PE_NAME 825{ 826 struct parse_events_term *term; 827 828 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 829 $1, 1, true, &@1, NULL)) { 830 free($1); 831 YYABORT; 832 } 833 $$ = term; 834} 835| 836PE_VALUE_SYM_HW 837{ 838 struct parse_events_term *term; 839 int config = $1 & 255; 840 841 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); 842 $$ = term; 843} 844| 845PE_TERM '=' PE_NAME 846{ 847 struct parse_events_term *term; 848 849 if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) { 850 free($3); 851 YYABORT; 852 } 853 $$ = term; 854} 855| 856PE_TERM '=' PE_VALUE 857{ 858 struct parse_events_term *term; 859 860 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); 861 $$ = term; 862} 863| 864PE_TERM 865{ 866 struct parse_events_term *term; 867 868 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); 869 $$ = term; 870} 871| 872PE_NAME array '=' PE_NAME 873{ 874 struct parse_events_term *term; 875 876 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 877 $1, $4, &@1, &@4)) { 878 free($1); 879 free($4); 880 free($2.ranges); 881 YYABORT; 882 } 883 term->array = $2; 884 $$ = term; 885} 886| 887PE_NAME array '=' PE_VALUE 888{ 889 struct parse_events_term *term; 890 891 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 892 $1, $4, false, &@1, &@4)) { 893 free($1); 894 free($2.ranges); 895 YYABORT; 896 } 897 term->array = $2; 898 $$ = term; 899} 900| 901PE_DRV_CFG_TERM 902{ 903 struct parse_events_term *term; 904 char *config = strdup($1); 905 906 ABORT_ON(!config); 907 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, 908 config, $1, &@1, NULL)) { 909 free($1); 910 free(config); 911 YYABORT; 912 } 913 $$ = term; 914} 915 916array: 917'[' array_terms ']' 918{ 919 $$ = $2; 920} 921| 922PE_ARRAY_ALL 923{ 924 $$.nr_ranges = 0; 925 $$.ranges = NULL; 926} 927 928array_terms: 929array_terms ',' array_term 930{ 931 struct parse_events_array new_array; 932 933 new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges; 934 new_array.ranges = realloc($1.ranges, 935 sizeof(new_array.ranges[0]) * 936 new_array.nr_ranges); 937 ABORT_ON(!new_array.ranges); 938 memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges, 939 $3.nr_ranges * sizeof(new_array.ranges[0])); 940 free($3.ranges); 941 $$ = new_array; 942} 943| 944array_term 945 946array_term: 947PE_VALUE 948{ 949 struct parse_events_array array; 950 951 array.nr_ranges = 1; 952 array.ranges = malloc(sizeof(array.ranges[0])); 953 ABORT_ON(!array.ranges); 954 array.ranges[0].start = $1; 955 array.ranges[0].length = 1; 956 $$ = array; 957} 958| 959PE_VALUE PE_ARRAY_RANGE PE_VALUE 960{ 961 struct parse_events_array array; 962 963 ABORT_ON($3 < $1); 964 array.nr_ranges = 1; 965 array.ranges = malloc(sizeof(array.ranges[0])); 966 ABORT_ON(!array.ranges); 967 array.ranges[0].start = $1; 968 array.ranges[0].length = $3 - $1 + 1; 969 $$ = array; 970} 971 972sep_dc: ':' | 973 974sep_slash_slash_dc: '/' '/' | ':' | 975 976%% 977 978void parse_events_error(YYLTYPE *loc, void *parse_state, 979 void *scanner __maybe_unused, 980 char const *msg __maybe_unused) 981{ 982 parse_events_evlist_error(parse_state, loc->last_column, "parser error"); 983}