From: Serbinenko Vladimir <serbinenko.vova@list.ru>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: Bash pre-alpha
Date: Sat, 29 Jan 2005 19:03:41 +0100 [thread overview]
Message-ID: <41FBCFFC.8060507@list.ru> (raw)
In-Reply-To: <871xc4rzlq.fsf@marco.marco-g.com>
Marco Gerards wrote:
>Serbinenko Vladimir <serbinenko.vova@list.ru> writes:
>
>
>
>>I'm sorry but I had some diff issues I confused run_menu and
>>run_menu_entry. Here is a patch to correct this error and update
>>i386.mk
>>
>>
>
>Urgh... It seems that I do not get all my emails. The one you sent
>now appears to be a follow up on an email I never received. The same
>seems to be true for other emails on this list. So if I don't reply
>to an email, I most likely did not receive it...
>
>
>
Perhaps you have a mail filter that filters out big messages? Spam filter?
>It's our custom not to send in patches for generated files. Perhaps
>it is possible to use .cvsignore to make sure they are not added, it's
>annoying that I always have to remove the files before making a patch.
>
>So please just send in a patch for *.rmk next time. :)
>
>
>
>>./grub2pr/normal/menu.c ./grub2/normal/menu.c
>>--- ./grub2pr/normal/menu.c 2005-01-29 14:55:55.000000000 +0100
>>+++ ./grub2/normal/menu.c 2005-01-29 15:00:11.000000000 +0100
>>
>>
>
>What does this patch do? Because I missed your last email I missed
>the description. I don't see that email in the archives yet. :/
>
>Anyway, this patch looks interesting at least. :)
>
>Thanks,
>Marco
>
>
>
>
>
I resend a text part of my message. I don't want to resend a patch
because it's quite big and I suppose that not all subscribers have a
broad channel. If you want I can resend it to you personally.
With this mail I also send an incremental patch.
It contains some bugfixing(some newline handling) and new commands '.',
'while,'until', 'break', 'continue' and 'return'
About help it can be optimised as in new syntax title is not used
anymore but some script commands are integrated in parse engine because
they control executition and/or parsing. I could prepare a small help
which will be simply printed as a text-string
Best wishes
Vladimir
---------------------------------------------------------------------
Here I prepared first preview version of bash scripting engine. I repeat
*first preview version*
That means I haven't really tested it nor cleaned up or commented. This
version is only for discussions.
For now supported features are:
arrays both syntaxes i=([0]=7 ...) and i[0]
arithmetic expansion and ((...))
commands echo, ':',source
Function support:
[function ] name() { list; }
Menu entries support like
entry "<description>" { list; }
Now configuration file is parsed the same way as any script file or
console entering
menu is automatically shown after configfile is parsed or you can use
showmenu command
In arithmetical expansion some additional commands are present:
i{9} means 10-th character of i
"i",'i' means string i
Associative arrays are supported: use
z['hello']=JJJ
This version is made in the goal to show my ideas and receive the
critics. Please send your suggestions,critics and bug-reports.
Known bugs:
possible segmentation faults at incorrect constructions
Not complete GCS compilance
Some plans:
See TODO in script.c
commands clear menu and unregister_entry
Bug fixing
-----------------------------------------------------------------------
diff -b -B -r -u -E -N -x '*~' --expand-tabs ./grub2pr/ChangeLog
./grub2/ChangeLog
--- ./grub2pr/ChangeLog 2005-01-29 15:39:33.000000000 +0100
+++ ./grub2/ChangeLog 2005-01-29 18:51:35.000000000 +0100
@@ -1,4 +1,9 @@
2005-01-29 Serbinenko Vladimir <serbinenko.vov@list.ru>
+ * include/grub/script.h: New type return reason
+ * normal/command.c : New commands: true,false, '.'
+ * normal/script.c: Bug fixed
+ New keywords: until, while,
break,continue,return
+2005-01-29 Serbinenko Vladimir <serbinenko.vov@list.ru>
Scripting support
* normal/script.c: New file
* include/grub/normal.h: New prototype
diff -b -B -r -u -E -N -x '*~' --expand-tabs
./grub2pr/include/grub/script.h ./grub2/include/grub/script.h
--- ./grub2pr/include/grub/script.h 2005-01-29 15:39:33.000000000 +0100
+++ ./grub2/include/grub/script.h 2005-01-29 17:04:57.000000000 +0100
@@ -40,6 +40,7 @@
char* (*func_do)(char*a,char*b,int opn);
};
enum vartype {SCRIPT_STR,SCRIPT_VAR_NAME};
+enum returnreason
{SCRIPT_NONE=0,SCRIPT_RETURN,SCRIPT_BREAK,SCRIPT_CONTINUE};
extern struct script_oper script_opers[];
int
script_find_oper(char*exp,int searchleft);
@@ -72,11 +73,11 @@
int
script_get_strend(char*str);
int
-script_execute(char*cmdline,grub_err_t(*getline)(char**),char**rest);
+script_execute(char*cmdline,grub_err_t(*getline)(char**),char**rest,enum
returnreason*retres,int*depth);
int
-script_exec_file (char*fname,int argc, char**argv);
+script_list_execute( grub_menu_entry_t fn,enum
returnreason*retres,int*depth);
int
-script_list_execute(grub_menu_entry_t fn);
+script_exec_file (char*fname,int argc, char**argv);
grub_menu_t menu;
#define EXPAND_DOLLAR 1
#define EXPAND_ALL 1
diff -b -B -r -u -E -N -x '*~' --expand-tabs ./grub2pr/normal/command.c
./grub2/normal/command.c
--- ./grub2pr/normal/command.c 2005-01-29 15:39:34.000000000 +0100
+++ ./grub2/normal/command.c 2005-01-29 17:01:19.000000000 +0100
@@ -121,7 +121,7 @@
return grub_cmdline_get (">", *s, GRUB_MAX_CMDLINE, 0, 1);
}
- return script_execute(cmdline,cmdline_get,0);
+ return script_execute(cmdline,cmdline_get,0,0,0);
}
int
grub_exec_norm(char*exp)
@@ -350,6 +350,21 @@
return 0;
}
+static grub_err_t
+true_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ return 0;
+}
+
+static grub_err_t
+false_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ return 1;
+}
void
grub_command_init (void)
@@ -382,6 +397,13 @@
grub_register_command ("source", source_command, GRUB_COMMAND_FLAG_BOTH,
"source FILE [ARGUMENTS ...]", "Execute script
FILE.", 0);
+ grub_register_command (".", source_command, GRUB_COMMAND_FLAG_BOTH,
+ ". FILE [ARGUMENTS ...]", "Execute script
FILE.", 0);
+
grub_register_command ("showmenu", showmenu_command,
GRUB_COMMAND_FLAG_BOTH,
"showmenu", "Show menu.", 0);
+ grub_register_command ("true", true_command, GRUB_COMMAND_FLAG_BOTH,
+ "true", "Return success.", 0);
+ grub_register_command ("false", false_command, GRUB_COMMAND_FLAG_BOTH,
+ "false", "Return failure.", 0);
}
diff -b -B -r -u -E -N -x '*~' --expand-tabs ./grub2pr/normal/menu.c
./grub2/normal/menu.c
--- ./grub2pr/normal/menu.c 2005-01-29 15:39:34.000000000 +0100
+++ ./grub2/normal/menu.c 2005-01-29 17:07:57.000000000 +0100
@@ -379,8 +379,7 @@
static void
run_menu_entry (grub_menu_entry_t entry)
{
-
- script_list_execute(entry);
+ script_list_execute(entry,0,0);
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot");
diff -b -B -r -u -E -N -x '*~' --expand-tabs ./grub2pr/normal/script.c
./grub2/normal/script.c
--- ./grub2pr/normal/script.c 2005-01-29 15:39:34.000000000 +0100
+++ ./grub2/normal/script.c 2005-01-29 18:43:28.000000000 +0100
@@ -1427,9 +1427,9 @@
return rtval;
}
void
-script_parse_list(grub_menu_entry_t
fnptr,char**cmd,grub_err_t(*getline)(char**),int no1stskip)
+script_parse_list(grub_menu_entry_t
fnptr,char**cmd,grub_err_t(*getline)(char**),int flgs)
{
- grub_command_list_t listptr=0;char*lastcmd=*cmd,*bfrcmd=*cmd;
+ grub_command_list_t listptr=0;char*lastcmd=*cmd,*bfrcmd=0;
/* Get one character from the commandline. If the caller reads
beyond the end of the string a new line will be read. This
function will not chech for errors, the caller has to check for
@@ -1497,19 +1497,13 @@
}
}
char c;int brack=1;int lmin=0;
- if(!no1stskip)
+ if(!(flgs&1))
{
while(grub_isspace((c=getchar())));
switch(c)
{
case '{':
break;
- case 'd':
- if(getchar()!='o')
- break;
- if(!script_islexend(getchar()))
- break;
- break;
default:
grub_error(GRUB_ERR_BAD_ARGUMENT,"unexpected %c
'{' expected",c);
return;
@@ -1523,7 +1517,11 @@
while(brack)
{
lmin=0;
- while(grub_isspace(c=getchar()));
+ c=getchar();
+ if(grub_isspace(c))
+ continue;
+ if(c=='\n' || c==';')
+ continue;
if(c=='}')
{
brack--;
@@ -1570,6 +1568,11 @@
c=getchar();
if(script_islexend(c))
{
+ if((flgs&2) && brack==1)
+ {
+ lmin=3;
+ break;
+ }
brack++;
continue;
}
@@ -1594,7 +1597,7 @@
while(1)
{
if((c=getchar())!='l')
- break;;
+ break;
c=getchar();
if(c=='s')
{
@@ -1630,10 +1633,13 @@
listptr->command[(*cmd)-lastcmd]=0;
}
if(!*cmd&& lmin)
+ {
*cmd=bfrcmd-lmin;
+ listptr->command[grub_strlen(listptr->command)-lmin+1]=0;
+ }
}
int
-script_list_execute( grub_menu_entry_t fn)
+script_list_execute( grub_menu_entry_t fn,enum
returnreason*retres,int*depth)
{
grub_command_list_t cmdlist=fn->command_list;
grub_err_t getln(char**s)
@@ -1650,7 +1656,12 @@
int rtval=0;
while(cmdlist)
{
- rtval=script_execute(cmdlist->command,getln,0);
+ enum returnreason rt;
+
if(cmdlist->command[0])rtval=script_execute(cmdlist->command,getln,0,&rt,depth);
+ if(retres)
+ *retres=rt;
+ if(rt)
+ return rtval;
if(cmdlist)
cmdlist=cmdlist->next;
}
@@ -1754,12 +1765,12 @@
getln(&ln);
if(!ln)
break;
- ret=script_execute(ln,getln,0);
+ ret=script_execute(ln,getln,0,0,0);
}
return ret;
}
int
-script_execute(char*cmdline,grub_err_t(*getline)(char**),char**rest)
+script_execute(char*cmdline,grub_err_t(*getline)(char**),char**rest,enum
returnreason*retres,int*depth)
{
int rtval=0,semdel=0;
int invrtval=0;
@@ -1780,6 +1791,8 @@
return 1;
}
if(rest)*rest=0;
+ if(retres)
+ *retres=SCRIPT_NONE;
while(1)
{
if(invrtval)
@@ -1825,9 +1838,17 @@
end+=2;
while(!end || !*end ||
grub_memcmp(end,"then",4)|| !script_islexend(end[4]))
{
+ enum returnreason rt;
if(!end || !*end)
getline(&end);
- ret=!script_execute(end,getline,&end);
+ if(*end)
+ {
+
ret=!script_execute(end,getline,&end,&rt,depth);
+ if(retres)
+ *retres=rt;
+ if(rt)
+ return rtval;
+ }
}
grub_menu_entry_t lst=grub_malloc(sizeof(*lst));
lst->num=0;
@@ -1836,7 +1857,15 @@
end+=4;
script_parse_list(lst,&end,getline,1);
if(ret)
- rtval=script_list_execute(lst);
+ {
+ enum returnreason rt;
+ rtval=script_list_execute(lst,&rt,depth);
+ script_free_list(lst);
+ if(retres)
+ *retres=rt;
+ if(rt)
+ return rtval;
+ }
script_free_list(lst);
while((!grub_memcmp(end,"else",4)&&script_islexend(end[4]))
||(!grub_memcmp(end,"elif",4)&&script_islexend(end[4])))
@@ -1851,9 +1880,17 @@
{
while(!end || !*end ||
grub_memcmp(end,"then",4)|| !script_islexend(end[4]))
{
+ enum returnreason rt;
if(!end || !*end)
getline(&end);
-
crtval=!script_execute(end,getline,&end);
+ if(*end)
+ {
+
ret=!script_execute(end,getline,&end,&rt,depth);
+ if(retres)
+ *retres=rt;
+ if(rt)
+ return
rtval;
+ }
}
end+=4;
}
@@ -1862,14 +1899,63 @@
script_parse_list(lst,&end,getline,1);
if(crtval)
{
- rtval=script_list_execute(lst);
+ enum returnreason rt;
+
rtval=script_list_execute(lst,&rt,depth);
+ script_free_list(lst);
+ if(retres)
+ *retres=rt;
+ if(rt)
+ return rtval;
ret=1;
}
+ else
script_free_list(lst);
}
end+=2;
continue;
}
+ if((!grub_memcmp(end,"while",sizeof("while")-1)&&
script_islexend(end[sizeof("while")-1]))
+
||(!grub_memcmp(end,"until",sizeof("until")-1)&&
script_islexend(end[sizeof("until")-1])))
+ {
+ int invrt=(*end=='u');
+ end+=sizeof("while")-1;
+ grub_menu_entry_t
condlst=grub_malloc(sizeof(*condlst));
+ grub_menu_entry_t lst=grub_malloc(sizeof(*lst));
+ condlst->num=0;
+ condlst->title=0;
+ condlst->next=0;
+ script_parse_list(condlst,&end,getline,3);
+ lst->num=0;
+ lst->title=0;
+ lst->next=0;
+ end+=2;
+ script_parse_list(lst,&end,getline,1);
+ while(1)
+ {
+ enum returnreason rt;
+ int
ret=script_list_execute(condlst,&rt,depth),dpth;
+ if(retres)
+ *retres=rt;
+ if(rt)
+ return rtval;
+ if((!ret)==invrt)
+ break;
+ rtval=script_list_execute(lst,&rt,&dpth);
+ if(retres)
+
*retres=((rt==SCRIPT_CONTINUE||rt==SCRIPT_BREAK)&&dpth==1)?SCRIPT_NONE:rt;
+ if(depth)
+ *depth=dpth-1;
+ if(rt &&
(rt!=SCRIPT_CONTINUE||dpth!=1)&&(rt!=SCRIPT_BREAK||dpth!=1))
+ return rtval;
+ if(rt==SCRIPT_BREAK)
+ {
+ break;
+ }
+ }
+ script_free_list(lst);
+ script_free_list(condlst);
+ continue;
+ }
if(end[0]=='(' && end[1]=='(')
{
char*exp=script_expand(end,getline,&end,EXPAND_DOLLAR);
@@ -1939,6 +2025,40 @@
char*exp=script_expand(end,getline,&end,EXPAND_ALL);
while(grub_isspace(*exp))exp++;
char*expcur=exp;
+
if(!grub_memcmp("return",expcur,sizeof("return")-1)&&script_islexend(expcur[sizeof("return")-1]))
+ {
+ expcur+=sizeof("return")-1;
+ while(grub_isspace(*expcur))expcur++;
+ if(*expcur=='-' ||grub_isdigit(*expcur))
+ rtval=grub_strtol(expcur,&expcur,0);
+ if(retres)
+ *retres=SCRIPT_RETURN;
+ return rtval;
+ }
+
if(!grub_memcmp("continue",expcur,sizeof("continue")-1)&&script_islexend(expcur[sizeof("continue")-1]))
+ {
+ expcur+=sizeof("continue")-1;
+ while(grub_isspace(*expcur))expcur++;
+ if(depth)
+ *depth=1;
+ if(depth && (*expcur=='-'
||grub_isdigit(*expcur) ))
+ *depth=grub_strtol(expcur,&expcur,0);;
+ if(retres)
+ *retres=SCRIPT_CONTINUE;
+ return rtval;
+ }
+
if(!grub_memcmp("break",expcur,sizeof("break")-1)&&script_islexend(expcur[sizeof("break")-1]))
+ {
+ expcur+=sizeof("break")-1;
+ while(grub_isspace(*expcur))expcur++;
+ if(depth)
+ *depth=1;
+ if(depth && (*expcur=='-'
||grub_isdigit(*expcur) ))
+ *depth=grub_strtol(expcur,&expcur,0);
+ if(retres)
+ *retres=SCRIPT_BREAK;
+ return rtval;
+ }
{
grub_menu_entry_t cur=funcs.entry_list;
if(funcs.entry_list)
@@ -1952,7 +2072,7 @@
if(cur)
{
expcur+=grub_strlen(cur->title);
- rtval=script_list_execute(cur);
+ rtval=script_list_execute(cur,0,0);
continue;
}
}
next prev parent reply other threads:[~2005-01-29 18:35 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-12 9:44 Feature suggestion to grub Aki Tossavainen
2005-01-22 14:03 ` Marco Gerards
2005-01-22 15:18 ` Yoshinori K. Okuji
2005-01-22 16:19 ` Aki Tossavainen
2005-01-22 17:35 ` Yoshinori K. Okuji
2005-01-29 13:18 ` Bash pre-alpha Serbinenko Vladimir
2005-01-29 14:08 ` Serbinenko Vladimir
2005-01-29 16:04 ` Marco Gerards
2005-01-29 18:03 ` Serbinenko Vladimir [this message]
2005-01-31 5:59 ` Serbinenko Vladimir
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41FBCFFC.8060507@list.ru \
--to=serbinenko.vova@list.ru \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.