18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef EXPR_H 78c2ecf20Sopenharmony_ci#define EXPR_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#ifdef __cplusplus 108c2ecf20Sopenharmony_ciextern "C" { 118c2ecf20Sopenharmony_ci#endif 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <assert.h> 148c2ecf20Sopenharmony_ci#include <stdio.h> 158c2ecf20Sopenharmony_ci#include "list.h" 168c2ecf20Sopenharmony_ci#ifndef __cplusplus 178c2ecf20Sopenharmony_ci#include <stdbool.h> 188c2ecf20Sopenharmony_ci#endif 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistruct file { 218c2ecf20Sopenharmony_ci struct file *next; 228c2ecf20Sopenharmony_ci struct file *parent; 238c2ecf20Sopenharmony_ci const char *name; 248c2ecf20Sopenharmony_ci int lineno; 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_citypedef enum tristate { 288c2ecf20Sopenharmony_ci no, mod, yes 298c2ecf20Sopenharmony_ci} tristate; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cienum expr_type { 328c2ecf20Sopenharmony_ci E_NONE, E_OR, E_AND, E_NOT, 338c2ecf20Sopenharmony_ci E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ, 348c2ecf20Sopenharmony_ci E_LIST, E_SYMBOL, E_RANGE 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciunion expr_data { 388c2ecf20Sopenharmony_ci struct expr *expr; 398c2ecf20Sopenharmony_ci struct symbol *sym; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistruct expr { 438c2ecf20Sopenharmony_ci enum expr_type type; 448c2ecf20Sopenharmony_ci union expr_data left, right; 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) 488c2ecf20Sopenharmony_ci#define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) 498c2ecf20Sopenharmony_ci#define EXPR_NOT(dep) (2-(dep)) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define expr_list_for_each_sym(l, e, s) \ 528c2ecf20Sopenharmony_ci for (e = (l); e && (s = e->right.sym); e = e->left.expr) 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistruct expr_value { 558c2ecf20Sopenharmony_ci struct expr *expr; 568c2ecf20Sopenharmony_ci tristate tri; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistruct symbol_value { 608c2ecf20Sopenharmony_ci void *val; 618c2ecf20Sopenharmony_ci tristate tri; 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cienum symbol_type { 658c2ecf20Sopenharmony_ci S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* enum values are used as index to symbol.def[] */ 698c2ecf20Sopenharmony_cienum { 708c2ecf20Sopenharmony_ci S_DEF_USER, /* main user value */ 718c2ecf20Sopenharmony_ci S_DEF_AUTO, /* values read from auto.conf */ 728c2ecf20Sopenharmony_ci S_DEF_DEF3, /* Reserved for UI usage */ 738c2ecf20Sopenharmony_ci S_DEF_DEF4, /* Reserved for UI usage */ 748c2ecf20Sopenharmony_ci S_DEF_COUNT 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci/* 788c2ecf20Sopenharmony_ci * Represents a configuration symbol. 798c2ecf20Sopenharmony_ci * 808c2ecf20Sopenharmony_ci * Choices are represented as a special kind of symbol and have the 818c2ecf20Sopenharmony_ci * SYMBOL_CHOICE bit set in 'flags'. 828c2ecf20Sopenharmony_ci */ 838c2ecf20Sopenharmony_cistruct symbol { 848c2ecf20Sopenharmony_ci /* The next symbol in the same bucket in the symbol hash table */ 858c2ecf20Sopenharmony_ci struct symbol *next; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci /* The name of the symbol, e.g. "FOO" for 'config FOO' */ 888c2ecf20Sopenharmony_ci char *name; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci /* S_BOOLEAN, S_TRISTATE, ... */ 918c2ecf20Sopenharmony_ci enum symbol_type type; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci /* 948c2ecf20Sopenharmony_ci * The calculated value of the symbol. The SYMBOL_VALID bit is set in 958c2ecf20Sopenharmony_ci * 'flags' when this is up to date. Note that this value might differ 968c2ecf20Sopenharmony_ci * from the user value set in e.g. a .config file, due to visibility. 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_ci struct symbol_value curr; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* 1018c2ecf20Sopenharmony_ci * Values for the symbol provided from outside. def[S_DEF_USER] holds 1028c2ecf20Sopenharmony_ci * the .config value. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_ci struct symbol_value def[S_DEF_COUNT]; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci /* 1078c2ecf20Sopenharmony_ci * An upper bound on the tristate value the user can set for the symbol 1088c2ecf20Sopenharmony_ci * if it is a boolean or tristate. Calculated from prompt dependencies, 1098c2ecf20Sopenharmony_ci * which also inherit dependencies from enclosing menus, choices, and 1108c2ecf20Sopenharmony_ci * ifs. If 'n', the user value will be ignored. 1118c2ecf20Sopenharmony_ci * 1128c2ecf20Sopenharmony_ci * Symbols lacking prompts always have visibility 'n'. 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_ci tristate visible; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* SYMBOL_* flags */ 1178c2ecf20Sopenharmony_ci int flags; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* List of properties. See prop_type. */ 1208c2ecf20Sopenharmony_ci struct property *prop; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci /* Dependencies from enclosing menus, choices, and ifs */ 1238c2ecf20Sopenharmony_ci struct expr_value dir_dep; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* Reverse dependencies through being selected by other symbols */ 1268c2ecf20Sopenharmony_ci struct expr_value rev_dep; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* 1298c2ecf20Sopenharmony_ci * "Weak" reverse dependencies through being implied by other symbols 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ci struct expr_value implied; 1328c2ecf20Sopenharmony_ci}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#define SYMBOL_CONST 0x0001 /* symbol is const */ 1378c2ecf20Sopenharmony_ci#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ 1388c2ecf20Sopenharmony_ci#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ 1398c2ecf20Sopenharmony_ci#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ 1408c2ecf20Sopenharmony_ci#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ 1418c2ecf20Sopenharmony_ci#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ 1428c2ecf20Sopenharmony_ci#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ 1438c2ecf20Sopenharmony_ci#define SYMBOL_CHANGED 0x0400 /* ? */ 1448c2ecf20Sopenharmony_ci#define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */ 1458c2ecf20Sopenharmony_ci#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */ 1468c2ecf20Sopenharmony_ci#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ 1478c2ecf20Sopenharmony_ci#define SYMBOL_WARNED 0x8000 /* warning has been issued */ 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/* Set when symbol.def[] is used */ 1508c2ecf20Sopenharmony_ci#define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */ 1518c2ecf20Sopenharmony_ci#define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */ 1528c2ecf20Sopenharmony_ci#define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ 1538c2ecf20Sopenharmony_ci#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ 1548c2ecf20Sopenharmony_ci#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci/* choice values need to be set before calculating this symbol value */ 1578c2ecf20Sopenharmony_ci#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* Set symbol to y if allnoconfig; used for symbols that hide others */ 1608c2ecf20Sopenharmony_ci#define SYMBOL_ALLNOCONFIG_Y 0x200000 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci#define SYMBOL_MAXLENGTH 256 1638c2ecf20Sopenharmony_ci#define SYMBOL_HASHSIZE 9973 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* A property represent the config options that can be associated 1668c2ecf20Sopenharmony_ci * with a config "symbol". 1678c2ecf20Sopenharmony_ci * Sample: 1688c2ecf20Sopenharmony_ci * config FOO 1698c2ecf20Sopenharmony_ci * default y 1708c2ecf20Sopenharmony_ci * prompt "foo prompt" 1718c2ecf20Sopenharmony_ci * select BAR 1728c2ecf20Sopenharmony_ci * config BAZ 1738c2ecf20Sopenharmony_ci * int "BAZ Value" 1748c2ecf20Sopenharmony_ci * range 1..255 1758c2ecf20Sopenharmony_ci * 1768c2ecf20Sopenharmony_ci * Please, also check parser.y:print_symbol() when modifying the 1778c2ecf20Sopenharmony_ci * list of property types! 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_cienum prop_type { 1808c2ecf20Sopenharmony_ci P_UNKNOWN, 1818c2ecf20Sopenharmony_ci P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ 1828c2ecf20Sopenharmony_ci P_COMMENT, /* text associated with a comment */ 1838c2ecf20Sopenharmony_ci P_MENU, /* prompt associated with a menu or menuconfig symbol */ 1848c2ecf20Sopenharmony_ci P_DEFAULT, /* default y */ 1858c2ecf20Sopenharmony_ci P_CHOICE, /* choice value */ 1868c2ecf20Sopenharmony_ci P_SELECT, /* select BAR */ 1878c2ecf20Sopenharmony_ci P_IMPLY, /* imply BAR */ 1888c2ecf20Sopenharmony_ci P_RANGE, /* range 7..100 (for a symbol) */ 1898c2ecf20Sopenharmony_ci P_SYMBOL, /* where a symbol is defined */ 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistruct property { 1938c2ecf20Sopenharmony_ci struct property *next; /* next property - null if last */ 1948c2ecf20Sopenharmony_ci enum prop_type type; /* type of property */ 1958c2ecf20Sopenharmony_ci const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ 1968c2ecf20Sopenharmony_ci struct expr_value visible; 1978c2ecf20Sopenharmony_ci struct expr *expr; /* the optional conditional part of the property */ 1988c2ecf20Sopenharmony_ci struct menu *menu; /* the menu the property are associated with 1998c2ecf20Sopenharmony_ci * valid for: P_SELECT, P_RANGE, P_CHOICE, 2008c2ecf20Sopenharmony_ci * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ 2018c2ecf20Sopenharmony_ci struct file *file; /* what file was this property defined */ 2028c2ecf20Sopenharmony_ci int lineno; /* what lineno was this property defined */ 2038c2ecf20Sopenharmony_ci}; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#define for_all_properties(sym, st, tok) \ 2068c2ecf20Sopenharmony_ci for (st = sym->prop; st; st = st->next) \ 2078c2ecf20Sopenharmony_ci if (st->type == (tok)) 2088c2ecf20Sopenharmony_ci#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) 2098c2ecf20Sopenharmony_ci#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) 2108c2ecf20Sopenharmony_ci#define for_all_prompts(sym, st) \ 2118c2ecf20Sopenharmony_ci for (st = sym->prop; st; st = st->next) \ 2128c2ecf20Sopenharmony_ci if (st->text) 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci/* 2158c2ecf20Sopenharmony_ci * Represents a node in the menu tree, as seen in e.g. menuconfig (though used 2168c2ecf20Sopenharmony_ci * for all front ends). Each symbol, menu, etc. defined in the Kconfig files 2178c2ecf20Sopenharmony_ci * gets a node. A symbol defined in multiple locations gets one node at each 2188c2ecf20Sopenharmony_ci * location. 2198c2ecf20Sopenharmony_ci */ 2208c2ecf20Sopenharmony_cistruct menu { 2218c2ecf20Sopenharmony_ci /* The next menu node at the same level */ 2228c2ecf20Sopenharmony_ci struct menu *next; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci /* The parent menu node, corresponding to e.g. a menu or choice */ 2258c2ecf20Sopenharmony_ci struct menu *parent; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci /* The first child menu node, for e.g. menus and choices */ 2288c2ecf20Sopenharmony_ci struct menu *list; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci /* 2318c2ecf20Sopenharmony_ci * The symbol associated with the menu node. Choices are implemented as 2328c2ecf20Sopenharmony_ci * a special kind of symbol. NULL for menus, comments, and ifs. 2338c2ecf20Sopenharmony_ci */ 2348c2ecf20Sopenharmony_ci struct symbol *sym; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci /* 2378c2ecf20Sopenharmony_ci * The prompt associated with the node. This holds the prompt for a 2388c2ecf20Sopenharmony_ci * symbol as well as the text for a menu or comment, along with the 2398c2ecf20Sopenharmony_ci * type (P_PROMPT, P_MENU, etc.) 2408c2ecf20Sopenharmony_ci */ 2418c2ecf20Sopenharmony_ci struct property *prompt; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci /* 2448c2ecf20Sopenharmony_ci * 'visible if' dependencies. If more than one is given, they will be 2458c2ecf20Sopenharmony_ci * ANDed together. 2468c2ecf20Sopenharmony_ci */ 2478c2ecf20Sopenharmony_ci struct expr *visibility; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci /* 2508c2ecf20Sopenharmony_ci * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed 2518c2ecf20Sopenharmony_ci * together 2528c2ecf20Sopenharmony_ci */ 2538c2ecf20Sopenharmony_ci struct expr *dep; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci /* MENU_* flags */ 2568c2ecf20Sopenharmony_ci unsigned int flags; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci /* Any help text associated with the node */ 2598c2ecf20Sopenharmony_ci char *help; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci /* The location where the menu node appears in the Kconfig files */ 2628c2ecf20Sopenharmony_ci struct file *file; 2638c2ecf20Sopenharmony_ci int lineno; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci /* For use by front ends that need to store auxiliary data */ 2668c2ecf20Sopenharmony_ci void *data; 2678c2ecf20Sopenharmony_ci}; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci/* 2708c2ecf20Sopenharmony_ci * Set on a menu node when the corresponding symbol changes state in some way. 2718c2ecf20Sopenharmony_ci * Can be checked by front ends. 2728c2ecf20Sopenharmony_ci */ 2738c2ecf20Sopenharmony_ci#define MENU_CHANGED 0x0001 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci#define MENU_ROOT 0x0002 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistruct jump_key { 2788c2ecf20Sopenharmony_ci struct list_head entries; 2798c2ecf20Sopenharmony_ci size_t offset; 2808c2ecf20Sopenharmony_ci struct menu *target; 2818c2ecf20Sopenharmony_ci int index; 2828c2ecf20Sopenharmony_ci}; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci#define JUMP_NB 9 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ciextern struct file *file_list; 2878c2ecf20Sopenharmony_ciextern struct file *current_file; 2888c2ecf20Sopenharmony_cistruct file *lookup_file(const char *name); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ciextern struct symbol symbol_yes, symbol_no, symbol_mod; 2918c2ecf20Sopenharmony_ciextern struct symbol *modules_sym; 2928c2ecf20Sopenharmony_ciextern struct symbol *sym_defconfig_list; 2938c2ecf20Sopenharmony_ciextern int cdebug; 2948c2ecf20Sopenharmony_cistruct expr *expr_alloc_symbol(struct symbol *sym); 2958c2ecf20Sopenharmony_cistruct expr *expr_alloc_one(enum expr_type type, struct expr *ce); 2968c2ecf20Sopenharmony_cistruct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); 2978c2ecf20Sopenharmony_cistruct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); 2988c2ecf20Sopenharmony_cistruct expr *expr_alloc_and(struct expr *e1, struct expr *e2); 2998c2ecf20Sopenharmony_cistruct expr *expr_alloc_or(struct expr *e1, struct expr *e2); 3008c2ecf20Sopenharmony_cistruct expr *expr_copy(const struct expr *org); 3018c2ecf20Sopenharmony_civoid expr_free(struct expr *e); 3028c2ecf20Sopenharmony_civoid expr_eliminate_eq(struct expr **ep1, struct expr **ep2); 3038c2ecf20Sopenharmony_ciint expr_eq(struct expr *e1, struct expr *e2); 3048c2ecf20Sopenharmony_citristate expr_calc_value(struct expr *e); 3058c2ecf20Sopenharmony_cistruct expr *expr_trans_bool(struct expr *e); 3068c2ecf20Sopenharmony_cistruct expr *expr_eliminate_dups(struct expr *e); 3078c2ecf20Sopenharmony_cistruct expr *expr_transform(struct expr *e); 3088c2ecf20Sopenharmony_ciint expr_contains_symbol(struct expr *dep, struct symbol *sym); 3098c2ecf20Sopenharmony_cibool expr_depends_symbol(struct expr *dep, struct symbol *sym); 3108c2ecf20Sopenharmony_cistruct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_civoid expr_fprint(struct expr *e, FILE *out); 3138c2ecf20Sopenharmony_cistruct gstr; /* forward */ 3148c2ecf20Sopenharmony_civoid expr_gstr_print(struct expr *e, struct gstr *gs); 3158c2ecf20Sopenharmony_civoid expr_gstr_print_revdep(struct expr *e, struct gstr *gs, 3168c2ecf20Sopenharmony_ci tristate pr_type, const char *title); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cistatic inline int expr_is_yes(struct expr *e) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cistatic inline int expr_is_no(struct expr *e) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci#ifdef __cplusplus 3298c2ecf20Sopenharmony_ci} 3308c2ecf20Sopenharmony_ci#endif 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci#endif /* EXPR_H */ 333