xref: /aosp_15_r20/bootable/deprecated-ota/edify/README.md (revision acea8879c968027b49a027136800575dd9783ddf)
1*acea8879SAndroid Build Coastguard Workeredify
2*acea8879SAndroid Build Coastguard Worker=====
3*acea8879SAndroid Build Coastguard Worker
4*acea8879SAndroid Build Coastguard WorkerUpdate scripts (from donut onwards) are written in a new little
5*acea8879SAndroid Build Coastguard Workerscripting language ("edify") that is superficially somewhat similar to
6*acea8879SAndroid Build Coastguard Workerthe old one ("amend").  This is a brief overview of the new language.
7*acea8879SAndroid Build Coastguard Worker
8*acea8879SAndroid Build Coastguard Worker- The entire script is a single expression.
9*acea8879SAndroid Build Coastguard Worker
10*acea8879SAndroid Build Coastguard Worker- All expressions are string-valued.
11*acea8879SAndroid Build Coastguard Worker
12*acea8879SAndroid Build Coastguard Worker- String literals appear in double quotes.  \n, \t, \", and \\ are
13*acea8879SAndroid Build Coastguard Worker  understood, as are hexadecimal escapes like \x4a.
14*acea8879SAndroid Build Coastguard Worker
15*acea8879SAndroid Build Coastguard Worker- String literals consisting of only letters, numbers, colons,
16*acea8879SAndroid Build Coastguard Worker  underscores, slashes, and periods don't need to be in double quotes.
17*acea8879SAndroid Build Coastguard Worker
18*acea8879SAndroid Build Coastguard Worker- The following words are reserved:
19*acea8879SAndroid Build Coastguard Worker
20*acea8879SAndroid Build Coastguard Worker       if    then    else   endif
21*acea8879SAndroid Build Coastguard Worker
22*acea8879SAndroid Build Coastguard Worker  They have special meaning when unquoted.  (In quotes, they are just
23*acea8879SAndroid Build Coastguard Worker  string literals.)
24*acea8879SAndroid Build Coastguard Worker
25*acea8879SAndroid Build Coastguard Worker- When used as a boolean, the empty string is "false" and all other
26*acea8879SAndroid Build Coastguard Worker  strings are "true".
27*acea8879SAndroid Build Coastguard Worker
28*acea8879SAndroid Build Coastguard Worker- All functions are actually macros (in the Lisp sense); the body of
29*acea8879SAndroid Build Coastguard Worker  the function can control which (if any) of the arguments are
30*acea8879SAndroid Build Coastguard Worker  evaluated.  This means that functions can act as control
31*acea8879SAndroid Build Coastguard Worker  structures.
32*acea8879SAndroid Build Coastguard Worker
33*acea8879SAndroid Build Coastguard Worker- Operators (like "&&" and "||") are just syntactic sugar for builtin
34*acea8879SAndroid Build Coastguard Worker  functions, so they can act as control structures as well.
35*acea8879SAndroid Build Coastguard Worker
36*acea8879SAndroid Build Coastguard Worker- ";" is a binary operator; evaluating it just means to first evaluate
37*acea8879SAndroid Build Coastguard Worker  the left side, then the right.  It can also appear after any
38*acea8879SAndroid Build Coastguard Worker  expression.
39*acea8879SAndroid Build Coastguard Worker
40*acea8879SAndroid Build Coastguard Worker- Comments start with "#" and run to the end of the line.
41*acea8879SAndroid Build Coastguard Worker
42*acea8879SAndroid Build Coastguard Worker
43*acea8879SAndroid Build Coastguard Worker
44*acea8879SAndroid Build Coastguard WorkerSome examples:
45*acea8879SAndroid Build Coastguard Worker
46*acea8879SAndroid Build Coastguard Worker- There's no distinction between quoted and unquoted strings; the
47*acea8879SAndroid Build Coastguard Worker  quotes are only needed if you want characters like whitespace to
48*acea8879SAndroid Build Coastguard Worker  appear in the string.  The following expressions all evaluate to the
49*acea8879SAndroid Build Coastguard Worker  same string.
50*acea8879SAndroid Build Coastguard Worker
51*acea8879SAndroid Build Coastguard Worker     "a b"
52*acea8879SAndroid Build Coastguard Worker     a + " " + b
53*acea8879SAndroid Build Coastguard Worker     "a" + " " + "b"
54*acea8879SAndroid Build Coastguard Worker     "a\x20b"
55*acea8879SAndroid Build Coastguard Worker     a + "\x20b"
56*acea8879SAndroid Build Coastguard Worker     concat(a, " ", "b")
57*acea8879SAndroid Build Coastguard Worker     "concat"(a, " ", "b")
58*acea8879SAndroid Build Coastguard Worker
59*acea8879SAndroid Build Coastguard Worker  As shown in the last example, function names are just strings,
60*acea8879SAndroid Build Coastguard Worker  too.  They must be string *literals*, however.  This is not legal:
61*acea8879SAndroid Build Coastguard Worker
62*acea8879SAndroid Build Coastguard Worker     ("con" + "cat")(a, " ", b)         # syntax error!
63*acea8879SAndroid Build Coastguard Worker
64*acea8879SAndroid Build Coastguard Worker
65*acea8879SAndroid Build Coastguard Worker- The ifelse() builtin takes three arguments:  it evaluates exactly
66*acea8879SAndroid Build Coastguard Worker  one of the second and third, depending on whether the first one is
67*acea8879SAndroid Build Coastguard Worker  true.  There is also some syntactic sugar to make expressions that
68*acea8879SAndroid Build Coastguard Worker  look like if/else statements:
69*acea8879SAndroid Build Coastguard Worker
70*acea8879SAndroid Build Coastguard Worker     # these are all equivalent
71*acea8879SAndroid Build Coastguard Worker     ifelse(something(), "yes", "no")
72*acea8879SAndroid Build Coastguard Worker     if something() then yes else no endif
73*acea8879SAndroid Build Coastguard Worker     if something() then "yes" else "no" endif
74*acea8879SAndroid Build Coastguard Worker
75*acea8879SAndroid Build Coastguard Worker  The else part is optional.
76*acea8879SAndroid Build Coastguard Worker
77*acea8879SAndroid Build Coastguard Worker     if something() then "yes" endif    # if something() is false,
78*acea8879SAndroid Build Coastguard Worker                                        # evaluates to false
79*acea8879SAndroid Build Coastguard Worker
80*acea8879SAndroid Build Coastguard Worker     ifelse(condition(), "", abort())   # abort() only called if
81*acea8879SAndroid Build Coastguard Worker                                        # condition() is false
82*acea8879SAndroid Build Coastguard Worker
83*acea8879SAndroid Build Coastguard Worker  The last example is equivalent to:
84*acea8879SAndroid Build Coastguard Worker
85*acea8879SAndroid Build Coastguard Worker     assert(condition())
86*acea8879SAndroid Build Coastguard Worker
87*acea8879SAndroid Build Coastguard Worker
88*acea8879SAndroid Build Coastguard Worker- The && and || operators can be used similarly; they evaluate their
89*acea8879SAndroid Build Coastguard Worker  second argument only if it's needed to determine the truth of the
90*acea8879SAndroid Build Coastguard Worker  expression.  Their value is the value of the last-evaluated
91*acea8879SAndroid Build Coastguard Worker  argument:
92*acea8879SAndroid Build Coastguard Worker
93*acea8879SAndroid Build Coastguard Worker     file_exists("/data/system/bad") && delete("/data/system/bad")
94*acea8879SAndroid Build Coastguard Worker
95*acea8879SAndroid Build Coastguard Worker     file_exists("/data/system/missing") || create("/data/system/missing")
96*acea8879SAndroid Build Coastguard Worker
97*acea8879SAndroid Build Coastguard Worker     get_it() || "xxx"     # returns value of get_it() if that value is
98*acea8879SAndroid Build Coastguard Worker                           # true, otherwise returns "xxx"
99*acea8879SAndroid Build Coastguard Worker
100*acea8879SAndroid Build Coastguard Worker
101*acea8879SAndroid Build Coastguard Worker- The purpose of ";" is to simulate imperative statements, of course,
102*acea8879SAndroid Build Coastguard Worker  but the operator can be used anywhere.  Its value is the value of
103*acea8879SAndroid Build Coastguard Worker  its right side:
104*acea8879SAndroid Build Coastguard Worker
105*acea8879SAndroid Build Coastguard Worker     concat(a;b;c, d, e;f)     # evaluates to "cdf"
106*acea8879SAndroid Build Coastguard Worker
107*acea8879SAndroid Build Coastguard Worker  A more useful example might be something like:
108*acea8879SAndroid Build Coastguard Worker
109*acea8879SAndroid Build Coastguard Worker     ifelse(condition(),
110*acea8879SAndroid Build Coastguard Worker            (first_step(); second_step();),   # second ; is optional
111*acea8879SAndroid Build Coastguard Worker            alternative_procedure())
112