14#include <Library/BaseLib.h>
15#include <Library/BaseMemoryLib.h>
41#define GRUB_LINE "in grub.cfg at line"
46#define VAR_FLAGS_NONE (0)
47#define VAR_FLAGS_BRACE BIT0
48#define VAR_FLAGS_NUMERIC BIT1
50#define SHIFT_TOKEN(offset) do {\
51 CopyMem (*Token + (offset), *Token, &Content[*Pos] - *Token); \
71 BOOLEAN TokenCompleted;
81 *ContainsVars = FALSE;
87 TokenCompleted = FALSE;
95 }
else if (!((Ch ==
'\0') || (Ch ==
'\t') || ((Ch >= 32) && (Ch <= 127)))) {
96 DEBUG ((DEBUG_WARN,
"LNX: Invalid char 0x%x %a %u\n", Ch,
GRUB_LINE, Line));
97 return EFI_INVALID_PARAMETER;
104 Ch2 = Content[(*Pos) + 1];
106 if ((Ch2 ==
'\0') || (Ch2 ==
'\n')) {
115 DEBUG ((DEBUG_WARN,
"LNX: Illegal line continuation within variable name %a %u\n",
GRUB_LINE, Line));
116 return EFI_INVALID_PARAMETER;
122 Add = (Ch2 ==
'\n' ? 2 : 1);
142 if ((Ch2 ==
'$') || (Ch2 ==
'"')) {
178 *ContainsVars = TRUE;
182 DEBUG ((DEBUG_WARN,
"LNX: Illegal character in variable name %a %u\n",
GRUB_LINE, Line));
183 return EFI_INVALID_PARAMETER;
187 }
else if (Ch ==
'}') {
192 DEBUG ((DEBUG_WARN,
"LNX: Illegal character in variable name %a %u\n",
GRUB_LINE, Line));
193 return EFI_INVALID_PARAMETER;
197 }
else if ((Ch ==
'@') || (Ch ==
'?') || (Ch ==
'#')) {
202 }
else if ((Ch ==
'_') ||
IS_ALPHA (Ch)) {
205 DEBUG ((DEBUG_WARN,
"LNX: Illegal character in variable name %a %u\n",
GRUB_LINE, Line));
206 return EFI_INVALID_PARAMETER;
214 DEBUG ((DEBUG_WARN,
"LNX: Illegal character in variable name %a %u\n",
GRUB_LINE, Line));
215 return EFI_INVALID_PARAMETER;
227 && ((Ch ==
'_') ||
IS_ALPHA (Ch)))))
242 if ((Ch ==
'\0') || (Ch ==
'\n') || (!Escaped && (Ch ==
';'))) {
243 TokenCompleted = TRUE;
245 }
else if ((Ch ==
' ') || (Ch ==
'\t')) {
247 }
else if (Ch ==
'#') {
250 *Token = &Content[*
Pos];
258 if ((Ch ==
'\n') || (Ch ==
'\0')) {
259 TokenCompleted = TRUE;
266 if ((Ch ==
'\n') || (Ch ==
'\0') || (!Escaped && ((Ch ==
';') || (Ch ==
' ') || (Ch ==
'\t')))) {
267 TokenCompleted = TRUE;
269 }
else if (!Escaped && (Ch ==
'\'')) {
272 }
else if (!Escaped && (Ch ==
'"')) {
275 }
else if (!Escaped && (Ch ==
'$')) {
286 }
else if (Ch ==
'$') {
294 if (!Escaped && (Ch ==
'"')) {
297 }
else if (!Escaped && (Ch ==
'$')) {
308 }
else if (Ch !=
'\0') {
311 }
while (Ch !=
'\0' && !TokenCompleted);
314 DEBUG ((DEBUG_WARN,
"LNX: Syntax error (state=%u) %a %u\n", GrubState,
GRUB_LINE, Line));
315 return EFI_INVALID_PARAMETER;
332 if ((Ch ==
';') || (Ch ==
'\n')) {
337 ASSERT (Ch ==
' ' || Ch ==
'\t');
361 if (Equals == NULL) {
362 DEBUG ((DEBUG_WARN,
"LNX: Invalid set command %a %u\n",
GRUB_LINE, Line));
363 return EFI_INVALID_PARAMETER;
369 if (Dollar != NULL) {
376 DEBUG ((DEBUG_WARN,
"LNX: Ignoring tokenised %a %a %a %u\n",
"variable name", Token,
GRUB_LINE, Line));
390 if (EFI_ERROR (Status)) {
399 IN OUT CHAR8 *Content
412 BOOLEAN ContainsVars;
414 BOOLEAN SetIsIndented;
428 Status =
GrubNextToken (Content, &
Pos, &NextLine, &Token, &IsIndented, &ContainsVars);
429 if (EFI_ERROR (Status)) {
436 LastChar = Content[
Pos];
440 if (TokenIndex == 0) {
447 if (Dollar != NULL) {
449 if ((Equals == NULL) || (Dollar < Equals)) {
450 DEBUG ((DEBUG_WARN,
"LNX: Ignoring tokenised %a %a %a %u\n",
"command", Token,
GRUB_LINE, Line));
456 if (AsciiStrCmp (
"blscfg", Token) == 0) {
463 if (AsciiStrCmp (
"set", Token) == 0) {
465 SetIsIndented = IsIndented;
468 }
else if ((TokenIndex == 1) && SetCommand) {
469 Status =
SetVar (Line, Token, SetIsIndented, ContainsVars);
470 if (EFI_ERROR (Status)) {
480 }
while (LastChar !=
'\0');
485 DEBUG ((DEBUG_WARN,
"LNX: blscfg command not found in grub.cfg\n"));
486 return EFI_NOT_FOUND;
enum GRUB_VAR_STATE_ GRUB_VAR_STATE
#define VAR_FLAGS_NUMERIC
enum GRUB_PARSE_STATE_ GRUB_PARSE_STATE
STATIC BOOLEAN GrubNextLine(CHAR8 Ch, UINTN *Pos)
STATIC EFI_STATUS SetVar(UINTN Line, CHAR8 *Token, BOOLEAN IsIndented, BOOLEAN ContainsVars)
#define SHIFT_TOKEN(offset)
EFI_STATUS InternalProcessGrubCfg(IN OUT CHAR8 *Content)
STATIC EFI_STATUS GrubNextToken(CHAR8 *Content, UINTN *Pos, UINTN *Line, CHAR8 **Token, BOOLEAN *IsIndented, BOOLEAN *ContainsVars)
EFI_STATUS InternalSetGrubVar(CHAR8 *Key, CHAR8 *Value, UINTN Errors)
CHAR8 *EFIAPI OcAsciiStrChr(IN CONST CHAR8 *String, IN CHAR8 Char)