1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# stringref
https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.4.7-stringref
`stringref` statement helps to get string values to the VFR code:
```
EFI_IFR_STRING_REF1
Summary:
Push a string on the expression stack.
Prototype:
#define EFI_IFR_STRING_REF1_OP 0x4e
typedef struct _EFI_IFR_STRING_REF1 {
EFI_IFR_OP_HEADER Header;
EFI_STRING_ID StringId;
} EFI_IFR_STRING_REF1;
Members:
Header The byte sequence that defines the type of opcode as well as the length of the opcode being defined.
Header.OpCode = EFI_IFR_STRING_REF1_OP.
StringId The string’s identifier, which must be unique within the package list.
Description:
Push the string specified by StringId on to the expression stack. If the string does not exist, then push an empty string.
```
For example this condition in a `suppressif` statement is TRUE only if a string element has a specific data in itself:
```
string
name = StringQuestion,
...
endstring;
suppressif questionref(StringQuestion) == stringref(STRING_TOKEN(TEST_STRING));
...
endif;
```
Off course you need to define this new token that we use here for comparision:
```
#string TEST_STRING #language en-US "EDKII"
```
Another example of potential `stringref` usage:
```
string
varid = FormData.StringValue,
prompt = STRING_TOKEN(STRING_PROMPT),
help = STRING_TOKEN(STRING_HELP),
minsize = 5,
maxsize = 10,
warningif
prompt = STRING_TOKEN(WARNING_IF_PROMPT),
pushthis == stringref(STRING_TOKEN(TEST_STRING))
endif;
endstring;
```
This code outputs a warning message if input string is equal to "EDKII".
# toupper/tolower
https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.6.8-toupper
https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.6.9-tolower
The `toupper` and `tolower` builtin functions are encoded in `EFI_IFR_TO_UPPER` (=0x21) and `EFI_IFR_TO_LOWER` (=0x20) opcodes and help to change case-register of the string data.
For example this code will output warning on "EDKII" input as well as on "Edkii", "EDkii", "EDKii", "eDKii" and so on:
```
string
varid = FormData.StringValue,
prompt = STRING_TOKEN(STRING_PROMPT),
help = STRING_TOKEN(STRING_HELP),
minsize = 5,
maxsize = 10,
warningif
prompt = STRING_TOKEN(WARNING_IF_PROMPT),
toupper(pushthis) == stringref(STRING_TOKEN(TEST_STRING))
endif;
endstring;
```
And this code outputs warning only on "edkii" input:
```
string
name = StringQuestion,
varid = FormData.StringValue,
prompt = STRING_TOKEN(STRING_PROMPT),
help = STRING_TOKEN(STRING_HELP),
minsize = 5,
maxsize = 10,
warningif
prompt = STRING_TOKEN(WARNING_IF_PROMPT),
pushthis == tolower(stringref(STRING_TOKEN(TEST_STRING)))
endif;
endstring;
```
# length
https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.6.1-length
The `length` keyword help get length of a buffer or a string. It is encoded with the `EFI_IFR_LENGTH_OP = 0x56` opcode.
For example here the code suppressed only if the string question data is a string exactly of 7 symbols:
```
suppressif length(questionref(StringQuestion)) == 7;
...
endif;
```
# More advanced atring builtins
| keyword | IFR opcode | link |
| --------| -----------| ---- |
| `catenate` | `EFI_IFR_CATENATE` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.1-catenate |
| `match` | `EFI_IFR_MATCH` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.2-match |
| `match2` | `EFI_IFR_MATCH2` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.9-match2 |
| `find` | `EFI_IFR_FIND` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.7.2-find |
| `mid` | `EFI_IFR_MID` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.7.3-mid |
| `token` | `EFI_IFR_TOKEN` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.7.4-tok |
| `span` | `EFI_IFR_SPAN` | https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/212_vfr_expression_statement_definition#2.12.11.7.5-span |
|