From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_NONE,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD564C11F69 for ; Thu, 1 Jul 2021 06:18:50 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1BC2C6148E for ; Thu, 1 Jul 2021 06:18:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1BC2C6148E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EBC7383246; Thu, 1 Jul 2021 08:17:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="CH/X4sVj"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 973D88322D; Thu, 1 Jul 2021 08:16:46 +0200 (CEST) Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 792518324C for ; Thu, 1 Jul 2021 08:16:26 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanga2@gmail.com Received: by mail-qk1-x72b.google.com with SMTP id b2so4986606qka.7 for ; Wed, 30 Jun 2021 23:16:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oQbmnjCPN0OG6omllTvCcV09BDM4xXSjTSyDDHFFB40=; b=CH/X4sVjV2qHQvVH14G+naAGQgbzqqEAwjVuGms26b6loUTc6WnM7SKn21pgVqVmKy pwlVzFnYJOLcOtk1YpBmjLS6WHOODBkUdI2F6WkwnxvIT/BqME6Oe/RnPRGA9c0QR9Au maGu/Q4Yog0TL0UGmrCSTCl2fKG3GT3dXBX/hR/QNk3wG9CxWbVOWKJBE4Yb4EER061J JlQawihFtol12Nqi4VwFsyZHi1NoSP5sYjeWutt7sTtceU7ebCE+c7tp79fQ57YBEZ+U DV71LdVd3yJd46fprSTTnfgoQkogSpOGoAOTuiiFJGPOU+CsD+8CNsQcMCU9EdsJepIU NlvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oQbmnjCPN0OG6omllTvCcV09BDM4xXSjTSyDDHFFB40=; b=jD6C6GGHM+vh6X+SAK6ffhlC3hBZYwl/+JVmeu7rGEzSzmhApUAY5m6MCxhf5vfHwb Lrbry3Jb4AvJAyyvlHAqQSiYShLQ6qhiBBobwE7WrQRa2U2aFRcTMi6a5E8DF8vkJn26 XKuUdAUaNI0vTvAnn5lBQM95Fh+t9I37xiz1xLlfEhIEFFG60IzINo+BOMwup0DDAg0o qLPADCaoiUj5ikhYhS6xp7LmDTctYMxmGW8/8DjP/QIzhGrdmQxzqq9aZsgluDXkz4fK GqK9tUTSbTuWm58pXKnDEvA+Qv5wu43GBwEzBeIrKeuKnAk/bftV70IOGbkbk6LPDXw3 U2mQ== X-Gm-Message-State: AOAM530PenYd2awtZf0yxZrohOJdDXNnU/9zjE5qhQxzeeLlMsiuZz9b IqV2mR+zTpiiTc9QGYSKM+98/hQ/f50= X-Google-Smtp-Source: ABdhPJzFPYIOD9NSAa2GNE7OFhx1g0HpNC/PT8X6uXDHANZNl1vyIwDsUek5lCoUQfi8P/65Q/4f/g== X-Received: by 2002:a05:620a:2229:: with SMTP id n9mr40058661qkh.41.1625120185146; Wed, 30 Jun 2021 23:16:25 -0700 (PDT) Received: from godwin.fios-router.home (pool-74-96-87-9.washdc.fios.verizon.net. [74.96.87.9]) by smtp.gmail.com with ESMTPSA id g21sm1684673qts.90.2021.06.30.23.16.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Jun 2021 23:16:24 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de, Tom Rini Cc: =?UTF-8?q?Marek=20Beh=C3=BAn?= , Wolfgang Denk , Simon Glass , Roland Gaudig , Heinrich Schuchardt , Kostas Michalopoulos , Sean Anderson Subject: [RFC PATCH 14/28] cli: lil: Document structures Date: Thu, 1 Jul 2021 02:15:57 -0400 Message-Id: <20210701061611.957918-15-seanga2@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210701061611.957918-1-seanga2@gmail.com> References: <20210701061611.957918-1-seanga2@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean This documents the major structures of LIL. Signed-off-by: Sean Anderson --- common/cli_lil.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ include/cli_lil.h | 57 ++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) diff --git a/common/cli_lil.c b/common/cli_lil.c index 66ee62bf33..7fbae1964a 100644 --- a/common/cli_lil.c +++ b/common/cli_lil.c @@ -29,20 +29,44 @@ #define HASHMAP_CELLS 256 #define HASHMAP_CELLMASK 0xFF +/** + * struct hashentry - An entry in a cell + * @k: The key + * @v: The value + */ struct hashentry { char *k; void *v; }; +/** + * struct hashcell - A list of entries with the same hash + * @e: An array of entries + * @c: The capacity of this cell + */ struct hashcell { struct hashentry *e; size_t c; }; +/** + * struct hashmap - An array-based hash map + * @cell: An array of cells + * + * This hash map uses separate chaining with an array for each cell. We cannot + * use the existing hash map functions (hsearch_r et al.) because they assume + * that the value is a string. + */ struct hashmap { struct hashcell cell[HASHMAP_CELLS]; }; +/** + * struct lil_value - A string and its length + * @l: The length of the value. + * @c: The capacity of this value (maximum of @l before requiring reallocation). + * @d: The contents of the value, as a nul-terminated string. + */ struct lil_value { size_t l; #ifdef LIL_ENABLE_POOLS @@ -51,12 +75,34 @@ struct lil_value { char *d; }; +/** + * struct lil_var - A variable + * @n: The name of this variable + * @env: The environment containing this variable + * @v: The value of this variable + */ struct lil_var { char *n; struct lil_env *env; struct lil_value *v; }; +/** + * struct lil_env - A function call's execution environment + * @parent: The parent of this environment. This is %NULL for the root + * environment. + * @func: The currently-executing function + * @proc: The name of the currently-executing built-in procedure + * @var: A list of the variables in this environment + * @vars: The number of variables in @var + * @varmap: A hash map mapping variable names to pointers to variables in @var + * @retval: The value set by "return" or "result" + * @retval_set: Whether @retval has been set + * @breakrun: Whether to immediately break out the current run of execution. + * This is set by "return" + * + * Variables are inherited from @parent. + */ struct lil_env { struct lil_env *parent; struct lil_func *func; @@ -69,12 +115,28 @@ struct lil_env { int breakrun; }; +/** + * struct list - A list of values + * @v: A list of pointers to &struct lil_value + * @c: The number of values in this list + * @cap: The space allocated for @v + */ struct lil_list { struct lil_value **v; size_t c; size_t cap; }; +/** + * struct lil_func - A function which may be evaluated with a list of arguments + * @name: The name of the function + * @code: A value containing LIL code to be evaluated + * @argnames: The names of variables to assign to the passed-in arguments + * @proc: A C function to use to evaluate this function + * + * @code and @argnames are only used to evaluate the function if @proc is %NULL. + * If @argnames is empty, then the arguments are assigned to a variable "args". + */ struct lil_func { char *name; struct lil_value *code; @@ -82,6 +144,31 @@ struct lil_func { lil_func_proc_t proc; }; +/** + * struct lil - The current state of the interpreter + * @code: The code which is being interpreted + * @rootcode: The top-level code (e.g. the code for the initial call to + * lil_parse()) + * @clen: The length of @code + * @head: The first uninterpreted part of this code, as an index of @code + * @ignoreeol: Whether to treat newlines as whitespace or command terminators + * @cmd: A list of the current commands + * @cmds: The number of commands in @cmd + * @cmdmap: A hash map mapping command names to pointers to commands in @cmd + * @env: The current environment to evaluate commands in + * @rootenv: The top-level "root" environment + * @downenv: The original environment after a call to "topeval" or "upeval" + * @empty: An empty value, allocated once + * @ERROR_NOERROR: There is no error. + * @ERROR_DEFAULT: There was an error. + * @ERROR_FIXHEAD: There was an error, but @err_head needs to be fixed. + * @ERROR_UNBALANCED: An opening quote or bracket lacks a balancing closing + * quote or bracket. + * @error: The current error status + * @err_head: The offset in @code which caused the @error + * @err_msg: An optional string describing the current @error + * @parse_depth: The depth of recursive function calls + */ struct lil { const char *code; /* need save on parse */ const char *rootcode; @@ -101,6 +188,19 @@ struct lil { size_t parse_depth; }; +/** + * struct expreval - A (mathematical) expression being evaluated + * @code: The complete code for this expression + * @len: The length of @code + * @head: The first unevaluated part of this expression, as an index of @code + * @ival: The integer value of this expression + * @EERR_NO_ERROR: There is no error + * @EERR_SYNTAX_ERROR: Syntax error. For now this is just mismatched + * parentheses. + * @EERR_DIVISION_BY_ZERO: Attempted division by zero + * @EERR_INVALID_EXPRESSION: A non-number was present + * @error: The error of this expression (if any) + */ struct expreval { const char *code; size_t len, head; diff --git a/include/cli_lil.h b/include/cli_lil.h index cdaa79fd15..91e79c12f4 100644 --- a/include/cli_lil.h +++ b/include/cli_lil.h @@ -13,10 +13,35 @@ #define LIL_VERSION_STRING "0.1" +/** + * enum lil_setvar - The strategy to use when creating new variables + */ enum lil_setvar { + /** + * @LIL_SETVAR_GLOBAL: Set in the root environment + */ LIL_SETVAR_GLOBAL = 0, + /** + * @LIL_SETVAR_LOCAL: Set, starting with the local environment + * + * Search for a variable. If one is found, overwrite it. Otherwise, + * create a new variable in the local environment. + */ LIL_SETVAR_LOCAL, + /** + * @LIL_SETVAR_LOCAL_NEW: Create in the local environment + * + * Create a new variable in the local environment. This never overrides + * existing variables (even if one exists in the local environment). + */ LIL_SETVAR_LOCAL_NEW, + /** + * @LIL_SETVAR_LOCAL_ONLY: Set in a local environment only + * + * Search for a variable in the local environment. If one is found, + * overwrite it. Otherwise, create a new variable in the local + * environment. + */ LIL_SETVAR_LOCAL_ONLY, }; @@ -32,9 +57,41 @@ struct lil; typedef struct lil_value *(*lil_func_proc_t)(struct lil *lil, size_t argc, struct lil_value **argv); +/** + * struct lil_callbacks - Functions called by LIL to allow overriding behavior + */ struct lil_callbacks { + /** + * @setvar: Called when a non-existent global variable is assigned + * + * @lil: The LIL interpreter + * + * @name: The name of the variable + * + * @value: A pointer to the value which would be assigned. This may be + * modified to assign a different value. + * + * This can be used to override or cancel the assignment of a variable + * + * @Return: A negative value to prevent the assignment, %0 to assign the + * original value, or a positive value to assign @value. + */ int (*setvar)(struct lil *lil, const char *name, struct lil_value **value); + /** + * @getvar: Called when a global variable is read + * + * @lil: The LIL interpreter + * + * @name The name of the variable + * + * @value: The pointer to the value which would be read. This may be + * modified to read a different value. + * + * @Return: A non-zero value to read the value pointed to by @value + * instead of the original value, or anything else to use the + * original value + */ int (*getvar)(struct lil *lil, const char *name, struct lil_value **value); }; -- 2.32.0