def parse_struct(scanner, fields, line, dep, filename, ret=False): """convert a struct (array of parameters) into a dictionary""" res = {} nparam = 0 for param in line: param = param.replace("\n", " ").strip() if not param: continue elif param[0] == ".": m = field_init_re.match(param) if m: field, value = m.groups() else: m = subfield_re.match(param) if m: field, value = m.groups() value = "{" + value + "}" else: raise lkddb.ParserError("in parse_line(): %s, %s, %s" % (filename, line, param)) res[field] = value else: try: res[fields[nparam]] = param except IndexError: logger.exception("Index error: %s, %s, %s, %s" % (scanner.name, fields, line, filename)) return {} nparam += 1 if res: if ret: return res scanner.raw.append((res, filename, dep))
def extract_struct(field, dictionary, default=""): if field in dictionary: v = dictionary[field] if v[0] == '{' and v[-1] == '}': return v[1:-1].strip() raise lkddb.ParserError("Unknown structure format: %s" % v) else: return default
def extract_value(field, dictionary): if field in dictionary: val = dictionary[field] if val[0] == "{" and val[-1] == "}": val = val[1:-1].strip() try: ret = eval(val) except SyntaxError: if val[-2:] == "UL" or val[-2:] == "ul": return eval(val[:-2]) elif val.find("?") >= 0: return value_expand_tri(val) elif val.find("=") >= 0: logger.warning("Hmmmm, %s in '%s'" % (field, dictionary)) return eval(val[val.find("=") + 1:]) else: logger.error("error in extract_value: %s, %s --- '%s'" % (field, dictionary, val)) assert False, "error in extract_value, 1: %s, %s --- '%s'" % ( field, dictionary, val) except NameError: logger.exception( "error in extract_value: expected number in field %s from %s" % (field, dictionary)) return -1 except: raise lkddb.ParserError( "error in extract_value, 2: %s, %s --- '%s'" % (field, dictionary, val)) try: return int(ret) except ValueError: if len(ret) == 1: # ('X') --eval()--> X --> ord(X) return ord(ret) else: raise lkddb.ParserError("str_value(): Numeric value of '%s'" % ret) else: return 0
def value_expand_tri(val): """expand 'b ? c : c' construct""" val = val.replace("(unsigned)", "") for r in (tri_re, tri_re2, tri_re3): m = r.search(val) while m is not None: cond, t, f = m.groups() try: if eval(cond): if t: res = t else: res = cond else: res = f except: raise lkddb.ParserError( "Error on value_expand_tri(val=%s): match: %s --- %s ---- %s" % (val, cond, t, f)) val = val[:m.start()] + res + val[m.end():] m = r.search(val) return eval(val)
def __parse_kconfig(self, filename): """read config menu in Kconfig""" f = open(filename, encoding='utf8', errors='replace') context = C_TOP config = None help = "" conf_type = None descr = "" depends = [] for line in f: line = line.expandtabs() if context == C_HELP: ident_new = len(line) - len(line.lstrip()) if ident < 0: ident = ident_new if ident_new >= ident or line.strip() == "": help += line.strip() + "\n" continue context = C_CONF line = line.strip() if len(line) == 0 or line[0] == "#": continue try: tok, args = line.split(None, 1) except ValueError: tok, args = line, "" if tok in frozenset(("menu", "endmenu", "source", "if", "endif", "endchoice", "mainmenu")): if context == C_CONF: self.__kconf_save(config, dict, conf_type, descr, depends, help, filename) context = C_TOP continue if tok in frozenset(("config", "menuconfig", "choice")): if context == C_CONF: self.__kconf_save(config, dict, conf_type, descr, depends, help, filename) else: context = C_CONF config = args help = "" dict = {} conf_type = None descr = "" depends = [] continue if tok in frozenset(("help", "---help---")): if context != C_CONF: help = "" logger.error( "kconfig: error: help out of context (%s), in %s, after '%s'" % (context, filename, config)) context = C_HELP ident = -1 continue if tok in frozenset( ("bool", "boolean", "tristate", "string", "hex", "int")): if tok == "boolean": tok = "bool" conf_type = tok if not args or args[0] == "#": descr = "" else: div = args[0] if not (div == '"' or div == "'"): descr = args logger.warning("kconfig: bad line in %s %s: '%s'" % (filename, config, line)) else: if div == '"': args = args.replace('\\"', "'").replace("\\'", "'") s = args.split(div) descr = s[1] else: args = args.replace('\\"', '"').replace("\\'", '"') s = args.split(div) descr = s[1].replace('"', "'") if len(s) < 3: logger.warning( "kconfig: bad line in %s %s: '%s': args=<%s>, s=%s" % (filename, config, line, args, s)) assert False else: d = s[2].split() if len(d) > 1 and d[0] == "if": depends.append(" ".join(d[1:])) if tok in frozenset(("default", "def_bool", "def_tristate")): if tok[3] == "_": conf_type = tok[4:] descr = "" if "#" in args: args = args.split("#", 1)[0] s = args.split('if') if len(s) > 1: d = s[1].split() depends.append(" ".join(d)) if tok == "prompt": div = args[0] assert div == '"' or div == "'" if div == '"': args = args.replace('\\"', "'").replace("\\'", "'") s = args.split(div) descr = s[1] else: args = args.replace('\\"', '"').replace("\\'", '"') s = args.split(div) descr = s[1].replace('"', "'") d = s[2].split() if len(d) > 1 and d[0] == "if": depends.append(" ".join(d[1:])) if tok == "depends": if "#" in args: args = args.split("#", 1)[0] d = args.split() if len(d) > 1 and d[0] == "on": depends.append(" ".join(d[1:])) else: raise lkddb.ParserError("kconfig: Cannot parse 'depends'") if not context == C_CONF: # e.g. depents after "menu" or prompt and default after "choice" continue dict[tok] = args if context == C_CONF or context == C_HELP: self.__kconf_save(config, dict, conf_type, descr, depends, help, filename)