Cross Reference: tparm.c
xref
: /
osnet-11
/
usr
/
src
/
grub
/
grub-0.97
/
stage2
/
tparm.c
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
1
N/A
/****************************************************************************
1
N/A
* Copyright (c) 1998,2000,2002 Free Software Foundation, Inc. *
1
N/A
* *
1
N/A
* Permission is hereby granted, free of charge, to any person obtaining a *
1
N/A
* copy of this software and associated documentation files (the *
1
N/A
* "Software"), to deal in the Software without restriction, including *
1
N/A
* without limitation the rights to use, copy, modify, merge, publish, *
1
N/A
* distribute, distribute with modifications, sublicense,
and
/
or
sell *
1
N/A
* copies of the Software, and to permit persons to whom the Software is *
1
N/A
* furnished to do so, subject to the following conditions: *
1
N/A
* *
1
N/A
* The above copyright notice and this permission notice shall be included *
1
N/A
* in all copies or substantial portions of the Software. *
1
N/A
* *
1
N/A
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
1
N/A
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
1
N/A
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
1
N/A
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
1
N/A
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
1
N/A
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
1
N/A
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
1
N/A
* *
1
N/A
* Except as contained in this notice, the name(s) of the above copyright *
1
N/A
* holders shall not be used in advertising or otherwise to promote the *
1
N/A
* sale, use or other dealings in this Software without prior written *
1
N/A
* authorization. *
1
N/A
****************************************************************************/
1
N/A
1
N/A
/**********************************************************************
1
N/A
* This code is a modification of
lib_tparm.c
found in ncurses-5.2. The
1
N/A
* modification are for use in grub by replacing all libc function through
1
N/A
* special grub functions. This also meant to delete all dynamic memory
1
N/A
* allocation and replace it by a number of fixed buffers.
1
N/A
*
1
N/A
* Modifications by Tilmann Bubeck <t.bubeck@reinform.de> 2002
1
N/A
**********************************************************************/
1
N/A
1
N/A
/****************************************************************************
1
N/A
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
1
N/A
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
1
N/A
****************************************************************************/
1
N/A
1
N/A
/*
1
N/A
*
tparm.c
1
N/A
*
1
N/A
*/
1
N/A
1
N/A
#
include
"
shared.h
"
1
N/A
1
N/A
#
include
"
tparm.h
"
1
N/A
1
N/A
/*
1
N/A
*
Common
/
troublesome
character definitions
1
N/A
*/
1
N/A
typedef
char
grub_bool
;
1
N/A
#
undef
isdigit
1
N/A
#
define
isdigit
(c) ((c) >=
'0'
&& (c) <=
'9'
)
1
N/A
#
ifndef
FALSE
1
N/A
#
define
FALSE
(0)
1
N/A
#
endif
1
N/A
#
ifndef
TRUE
1
N/A
#
define
TRUE
(!
FALSE
)
1
N/A
#
endif
1
N/A
#
define
MAX_FORMAT_LEN
256
1
N/A
#
define
max
(a,b) ((a) > (b) ? (a) : (b))
1
N/A
1
N/A
//MODULE_ID("$Id:
tparm.c
,v 1.1.1.1 2003/11/20 02:04:59 fengshuo Exp $")
1
N/A
1
N/A
/*
1
N/A
* char *
1
N/A
* tparm(string, ...)
1
N/A
*
1
N/A
* Substitute the given parameters into the given string by the following
1
N/A
* rules (taken from terminfo(5)):
1
N/A
*
1
N/A
* Cursor addressing and other strings requiring parame-
1
N/A
* ters in the terminal are described by a parameterized string
1
N/A
* capability, with like escapes %x in it. For example, to
1
N/A
* address the cursor, the cup capability is given, using two
1
N/A
* parameters: the row and column to address to. (Rows and
1
N/A
* columns are numbered from zero and refer to the physical
1
N/A
* screen visible to the user, not to any unseen memory.) If
1
N/A
* the terminal has memory relative cursor addressing, that can
1
N/A
* be indicated by
1
N/A
*
1
N/A
* The parameter mechanism uses a stack and special %
1
N/A
* codes to manipulate it. Typically a sequence will push one
1
N/A
* of the parameters onto the stack and then print it in some
1
N/A
* format. Often more complex operations are necessary.
1
N/A
*
1
N/A
* The % encodings have the following meanings:
1
N/A
*
1
N/A
* %% outputs `%'
1
N/A
* %c print pop() like %c in printf()
1
N/A
* %s print pop() like %s in printf()
1
N/A
* %[[:]flags][width[.precision]][doxXs]
1
N/A
* as in printf, flags are [-+#] and space
1
N/A
* The ':' is used to avoid making %+ or %-
1
N/A
* patterns (see below).
1
N/A
*
1
N/A
* %p[1-9] push ith parm
1
N/A
* %P[a-z] set dynamic variable [a-z] to pop()
1
N/A
* %g[a-z] get dynamic variable [a-z] and push it
1
N/A
* %P[A-Z] set static variable [A-Z] to pop()
1
N/A
* %g[A-Z] get static variable [A-Z] and push it
1
N/A
* %l push strlen(pop)
1
N/A
* %'c' push char constant c
1
N/A
* %{nn} push integer constant nn
1
N/A
*
1
N/A
* %+ %- %* %/ %m
1
N/A
* arithmetic (%m is mod): push(pop() op pop())
1
N/A
* %& %| %^ bit operations: push(pop() op pop())
1
N/A
* %= %> %< logical operations: push(pop() op pop())
1
N/A
* %A %O logical and & or operations for conditionals
1
N/A
* %! %~ unary operations push(op pop())
1
N/A
* %i add 1 to first two parms (for ANSI terminals)
1
N/A
*
1
N/A
* %? expr %t thenpart %e elsepart %;
1
N/A
* if-then-else, %e elsepart is optional.
1
N/A
* else-if's are possible ala Algol 68:
1
N/A
* %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
1
N/A
*
1
N/A
* For those of the above operators which are binary and not commutative,
1
N/A
* the stack works in the usual way, with
1
N/A
* %gx %gy %m
1
N/A
* resulting in x mod y, not the reverse.
1
N/A
*/
1
N/A
1
N/A
#
define
STACKSIZE
20
1
N/A
1
N/A
typedef
struct
{
1
N/A
union
{
1
N/A
unsigned
int
num
;
1
N/A
char
*
str
;
1
N/A
}
data
;
1
N/A
grub_bool
num_type
;
1
N/A
}
stack_frame
;
1
N/A
1
N/A
static
stack_frame
stack
[
STACKSIZE
];
1
N/A
static
int
stack_ptr
;
1
N/A
1
N/A
static
char
out_buff
[
256
];
1
N/A
static
int
out_size
=
256
;
1
N/A
static
int
out_used
;
1
N/A
1
N/A
static
inline
void
1
N/A
get_space
(
int
need
)
1
N/A
{
1
N/A
need
+=
out_used
;
1
N/A
if
(
need
>
out_size
) {
1
N/A
// FIX ME! buffer full, what now?
1
N/A
;
1
N/A
}
1
N/A
}
1
N/A
1
N/A
static
inline
void
1
N/A
save_text
(
const
char
*
fmt
,
const
char
*s,
int
len
)
1
N/A
{
1
N/A
int
s_len
=
grub_strlen
(s);
1
N/A
if
(
len
> (
int
)
s_len
)
1
N/A
s_len
=
len
;
1
N/A
1
N/A
get_space
(
s_len
+
1
);
1
N/A
1
N/A
(
void
)
grub_sprintf
(
out_buff
+
out_used
,
fmt
, s);
1
N/A
out_used
+=
grub_strlen
(
out_buff
+
out_used
);
1
N/A
}
1
N/A
1
N/A
static
inline
void
1
N/A
save_number
(
const
char
*
fmt
,
int
number
,
int
len
)
1
N/A
{
1
N/A
if
(
len
<
30
)
1
N/A
len
=
30
;
/* actually log10(MAX_INT)+1 */
1
N/A
1
N/A
get_space
(
len
+
1
);
1
N/A
1
N/A
(
void
)
grub_sprintf
(
out_buff
+
out_used
,
fmt
,
number
);
1
N/A
out_used
+=
grub_strlen
(
out_buff
+
out_used
);
1
N/A
}
1
N/A
1
N/A
static
inline
void
1
N/A
save_char
(
int
c)
1
N/A
{
1
N/A
if
(c == 0)
1
N/A
c = 0
200
;
1
N/A
get_space
(
1
);
1
N/A
out_buff
[
out_used
++] = c;
1
N/A
}
1
N/A
1
N/A
static
inline
void
1
N/A
npush
(
int
x)
1
N/A
{
1
N/A
if
(
stack_ptr
<
STACKSIZE
) {
1
N/A
stack
[
stack_ptr
].
num_type
=
TRUE
;
1
N/A
stack
[
stack_ptr
].
data
.
num
= x;
1
N/A
stack_ptr
++;
1
N/A
}
1
N/A
}
1
N/A
1
N/A
static
inline
int
1
N/A
npop
(
void
)
1
N/A
{
1
N/A
int
result
= 0;
1
N/A
if
(
stack_ptr
> 0) {
1
N/A
stack_ptr
--;
1
N/A
if
(
stack
[
stack_ptr
].
num_type
)
1
N/A
result
=
stack
[
stack_ptr
].
data
.
num
;
1
N/A
}
1
N/A
return
result
;
1
N/A
}
1
N/A
1
N/A
static
inline
void
1
N/A
spush
(
char
*x)
1
N/A
{
1
N/A
if
(
stack_ptr
<
STACKSIZE
) {
1
N/A
stack
[
stack_ptr
].
num_type
=
FALSE
;
1
N/A
stack
[
stack_ptr
].
data
.
str
= x;
1
N/A
stack_ptr
++;
1
N/A
}
1
N/A
}
1
N/A
1
N/A
static
inline
char
*
1
N/A
spop
(
void
)
1
N/A
{
1
N/A
static
char
dummy
[] =
""
;
/* avoid const-cast */
1
N/A
char
*
result
=
dummy
;
1
N/A
if
(
stack_ptr
> 0) {
1
N/A
stack_ptr
--;
1
N/A
if
(!
stack
[
stack_ptr
].
num_type
&&
stack
[
stack_ptr
].
data
.
str
!= 0)
1
N/A
result
=
stack
[
stack_ptr
].
data
.
str
;
1
N/A
}
1
N/A
return
result
;
1
N/A
}
1
N/A
1
N/A
static
inline
const
char
*
1
N/A
parse_format
(
const
char
*s,
char
*
format
,
int
*
len
)
1
N/A
{
1
N/A
grub_bool
done
=
FALSE
;
1
N/A
grub_bool
allowminus
=
FALSE
;
1
N/A
grub_bool
dot
=
FALSE
;
1
N/A
grub_bool
err
=
FALSE
;
1
N/A
char
*
fmt
=
format
;
1
N/A
int
prec
= 0;
1
N/A
int
width
= 0;
1
N/A
int
value
= 0;
1
N/A
1
N/A
*
len
= 0;
1
N/A
*
format
++ =
'%'
;
1
N/A
while
(*s !=
'\0'
&& !
done
) {
1
N/A
switch
(*s) {
1
N/A
case
'c'
:
/* FALLTHRU */
1
N/A
case
'd'
:
/* FALLTHRU */
1
N/A
case
'o'
:
/* FALLTHRU */
1
N/A
case
'x'
:
/* FALLTHRU */
1
N/A
case
'X'
:
/* FALLTHRU */
1
N/A
case
's'
:
1
N/A
*
format
++ = *s;
1
N/A
done
=
TRUE
;
1
N/A
break
;
1
N/A
case
'.'
:
1
N/A
*
format
++ = *s++;
1
N/A
if
(
dot
) {
1
N/A
err
=
TRUE
;
1
N/A
}
else
{
1
N/A
dot
=
TRUE
;
1
N/A
prec
=
value
;
1
N/A
}
1
N/A
value
= 0;
1
N/A
break
;
1
N/A
case
'#'
:
1
N/A
*
format
++ = *s++;
1
N/A
break
;
1
N/A
case
' '
:
1
N/A
*
format
++ = *s++;
1
N/A
break
;
1
N/A
case
':'
:
1
N/A
s++;
1
N/A
allowminus
=
TRUE
;
1
N/A
break
;
1
N/A
case
'-'
:
1
N/A
if
(
allowminus
) {
1
N/A
*
format
++ = *s++;
1
N/A
}
else
{
1
N/A
done
=
TRUE
;
1
N/A
}
1
N/A
break
;
1
N/A
default
:
1
N/A
if
(
isdigit
(*s)) {
1
N/A
value
= (
value
*
10
) + (*s -
'0'
);
1
N/A
if
(
value
>
10000
)
1
N/A
err
=
TRUE
;
1
N/A
*
format
++ = *s++;
1
N/A
}
else
{
1
N/A
done
=
TRUE
;
1
N/A
}
1
N/A
}
1
N/A
}
1
N/A
1
N/A
/*
1
N/A
* If we found an error, ignore (and remove) the flags.
1
N/A
*/
1
N/A
if
(
err
) {
1
N/A
prec
=
width
=
value
= 0;
1
N/A
format
=
fmt
;
1
N/A
*
format
++ =
'%'
;
1
N/A
*
format
++ = *s;
1
N/A
}
1
N/A
1
N/A
if
(
dot
)
1
N/A
width
=
value
;
1
N/A
else
1
N/A
prec
=
value
;
1
N/A
1
N/A
*
format
=
'\0'
;
1
N/A
/* return maximum string length in print */
1
N/A
*
len
= (
prec
>
width
) ?
prec
:
width
;
1
N/A
return
s;
1
N/A
}
1
N/A
1
N/A
#
define
isUPPER
(c) ((c) >=
'A'
&& (c) <=
'Z'
)
1
N/A
#
define
isLOWER
(c) ((c) >=
'a'
&& (c) <=
'z'
)
1
N/A
1
N/A
static
inline
char
*
1
N/A
tparam_internal
(
const
char
*
string
,
int
*
dataptr
)
1
N/A
{
1
N/A
#
define
NUM_VARS
26
1
N/A
char
*
p_is_s
[
9
];
1
N/A
int
param
[
9
];
1
N/A
int
lastpop
;
1
N/A
int
popcount
;
1
N/A
int
number
;
1
N/A
int
len
;
1
N/A
int
level
;
1
N/A
int
x, y;
1
N/A
int
i;
1
N/A
int
len2
;
1
N/A
register
const
char
*
cp
;
1
N/A
static
int
len_fmt
=
MAX_FORMAT_LEN
;
1
N/A
static
char
dummy
[] =
""
;
1
N/A
static
char
format
[
MAX_FORMAT_LEN
];
1
N/A
static
int
dynamic_var
[
NUM_VARS
];
1
N/A
static
int
static_vars
[
NUM_VARS
];
1
N/A
1
N/A
out_used
= 0;
1
N/A
if
(
string
==
NULL
)
1
N/A
return
NULL
;
1
N/A
1
N/A
if
((
len2
=
grub_strlen
(
string
)) >
len_fmt
) {
1
N/A
return
NULL
;
1
N/A
}
1
N/A
1
N/A
/*
1
N/A
* Find the highest parameter-number referred to in the format string.
1
N/A
* Use this value to limit the number of arguments copied from the
1
N/A
* variable-length argument list.
1
N/A
*/
1
N/A
1
N/A
number
= 0;
1
N/A
lastpop
= -
1
;
1
N/A
popcount
= 0;
1
N/A
grub_memset
(
p_is_s
, 0,
sizeof
(
p_is_s
));
1
N/A
1
N/A
/*
1
N/A
* Analyze the string to see how many parameters we need from the varargs
1
N/A
* list, and what their types are. We will only accept string parameters
1
N/A
* if they appear as a %l or %s format following an explicit parameter
1
N/A
* reference (e.g., %p2%s). All other parameters are numbers.
1
N/A
*
1
N/A
* 'number' counts coarsely the number of pop's we see in the string, and
1
N/A
* 'popcount' shows the highest parameter number in the string. We would
1
N/A
* like to simply use the latter count, but if we are reading termcap
1
N/A
* strings, there may be cases that we cannot see the explicit parameter
1
N/A
* numbers.
1
N/A
*/
1
N/A
for
(
cp
=
string
; (
cp
-
string
) < (
int
)
len2
;) {
1
N/A
if
(*
cp
==
'%'
) {
1
N/A
cp
++;
1
N/A
cp
=
parse_format
(
cp
,
format
, &
len
);
1
N/A
switch
(*
cp
) {
1
N/A
default
:
1
N/A
break
;
1
N/A
1
N/A
case
'd'
:
/* FALLTHRU */
1
N/A
case
'o'
:
/* FALLTHRU */
1
N/A
case
'x'
:
/* FALLTHRU */
1
N/A
case
'X'
:
/* FALLTHRU */
1
N/A
case
'c'
:
/* FALLTHRU */
1
N/A
number
++;
1
N/A
lastpop
= -
1
;
1
N/A
break
;
1
N/A
1
N/A
case
'l'
:
1
N/A
case
's'
:
1
N/A
if
(
lastpop
> 0)
1
N/A
p_is_s
[
lastpop
-
1
] =
dummy
;
1
N/A
++
number
;
1
N/A
break
;
1
N/A
1
N/A
case
'p'
:
1
N/A
cp
++;
1
N/A
i = (*
cp
-
'0'
);
1
N/A
if
(i >= 0 && i <=
9
) {
1
N/A
lastpop
= i;
1
N/A
if
(
lastpop
>
popcount
)
1
N/A
popcount
=
lastpop
;
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
'P'
:
1
N/A
case
'g'
:
1
N/A
cp
++;
1
N/A
break
;
1
N/A
1
N/A
case
'\''
:
1
N/A
cp
+=
2
;
1
N/A
lastpop
= -
1
;
1
N/A
break
;
1
N/A
1
N/A
case
'{'
:
1
N/A
cp
++;
1
N/A
while
(*
cp
>=
'0'
&& *
cp
<=
'9'
) {
1
N/A
cp
++;
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
'+'
:
1
N/A
case
'-'
:
1
N/A
case
'*'
:
1
N/A
case
'/'
:
1
N/A
case
'm'
:
1
N/A
case
'A'
:
1
N/A
case
'O'
:
1
N/A
case
'&'
:
1
N/A
case
'|'
:
1
N/A
case
'^'
:
1
N/A
case
'='
:
1
N/A
case
'<'
:
1
N/A
case
'>'
:
1
N/A
case
'!'
:
1
N/A
case
'~'
:
1
N/A
lastpop
= -
1
;
1
N/A
number
+=
2
;
1
N/A
break
;
1
N/A
1
N/A
case
'i'
:
1
N/A
lastpop
= -
1
;
1
N/A
if
(
popcount
<
2
)
1
N/A
popcount
=
2
;
1
N/A
break
;
1
N/A
}
1
N/A
}
1
N/A
if
(*
cp
!=
'\0'
)
1
N/A
cp
++;
1
N/A
}
1
N/A
1
N/A
if
(
number
>
9
)
1
N/A
number
=
9
;
1
N/A
for
(i = 0; i <
max
(
popcount
,
number
); i++) {
1
N/A
/*
1
N/A
* A few caps (such as plab_norm) have string-valued parms.
1
N/A
* We'll have to assume that the caller knows the difference, since
1
N/A
* a char* and an int may not be the same size on the stack.
1
N/A
*/
1
N/A
if
(
p_is_s
[i] != 0) {
1
N/A
p_is_s
[i] = (
char
*)(*(
dataptr
++));
1
N/A
}
else
{
1
N/A
param
[i] = (
int
)(*(
dataptr
++));
1
N/A
}
1
N/A
}
1
N/A
1
N/A
/*
1
N/A
* This is a termcap compatibility hack. If there are no explicit pop
1
N/A
* operations in the string, load the stack in such a way that
1
N/A
* successive pops will grab successive parameters. That will make
1
N/A
* the expansion of (for example) \E[%d;%dH work correctly in termcap
1
N/A
* style, which means tparam() will expand termcap strings OK.
1
N/A
*/
1
N/A
stack_ptr
= 0;
1
N/A
if
(
popcount
== 0) {
1
N/A
popcount
=
number
;
1
N/A
for
(i =
number
-
1
; i >= 0; i--)
1
N/A
npush
(
param
[i]);
1
N/A
}
1
N/A
1
N/A
while
(*
string
) {
1
N/A
/* skip delay timings */
1
N/A
if
(*
string
==
'$'
&& *(
string
+
1
) ==
'<'
) {
1
N/A
while
( *
string
&& *
string
!=
'>'
)
1
N/A
string
++;
1
N/A
if
( *
string
==
'>'
)
string
++;
1
N/A
}
else
if
( *
string
==
'%'
) {
1
N/A
string
++;
1
N/A
string
=
parse_format
(
string
,
format
, &
len
);
1
N/A
switch
(*
string
) {
1
N/A
default
:
1
N/A
break
;
1
N/A
case
'%'
:
1
N/A
save_char
(
'%'
);
1
N/A
break
;
1
N/A
1
N/A
case
'd'
:
/* FALLTHRU */
1
N/A
case
'o'
:
/* FALLTHRU */
1
N/A
case
'x'
:
/* FALLTHRU */
1
N/A
case
'X'
:
/* FALLTHRU */
1
N/A
case
'c'
:
/* FALLTHRU */
1
N/A
save_number
(
format
,
npop
(),
len
);
1
N/A
break
;
1
N/A
1
N/A
case
'l'
:
1
N/A
save_number
(
"%d"
,
strlen
(
spop
()), 0);
1
N/A
break
;
1
N/A
1
N/A
case
's'
:
1
N/A
save_text
(
format
,
spop
(),
len
);
1
N/A
break
;
1
N/A
1
N/A
case
'p'
:
1
N/A
string
++;
1
N/A
i = (*
string
-
'1'
);
1
N/A
if
(i >= 0 && i <
9
) {
1
N/A
if
(
p_is_s
[i])
1
N/A
spush
(
p_is_s
[i]);
1
N/A
else
1
N/A
npush
(
param
[i]);
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
'P'
:
1
N/A
string
++;
1
N/A
if
(
isUPPER
(*
string
)) {
1
N/A
i = (*
string
-
'A'
);
1
N/A
static_vars
[i] =
npop
();
1
N/A
}
else
if
(
isLOWER
(*
string
)) {
1
N/A
i = (*
string
-
'a'
);
1
N/A
dynamic_var
[i] =
npop
();
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
'g'
:
1
N/A
string
++;
1
N/A
if
(
isUPPER
(*
string
)) {
1
N/A
i = (*
string
-
'A'
);
1
N/A
npush
(
static_vars
[i]);
1
N/A
}
else
if
(
isLOWER
(*
string
)) {
1
N/A
i = (*
string
-
'a'
);
1
N/A
npush
(
dynamic_var
[i]);
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
'\''
:
1
N/A
string
++;
1
N/A
npush
(*
string
);
1
N/A
string
++;
1
N/A
break
;
1
N/A
1
N/A
case
'{'
:
1
N/A
number
= 0;
1
N/A
string
++;
1
N/A
while
(*
string
>=
'0'
&& *
string
<=
'9'
) {
1
N/A
number
=
number
*
10
+ *
string
-
'0'
;
1
N/A
string
++;
1
N/A
}
1
N/A
npush
(
number
);
1
N/A
break
;
1
N/A
1
N/A
case
'+'
:
1
N/A
npush
(
npop
() +
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'-'
:
1
N/A
y =
npop
();
1
N/A
x =
npop
();
1
N/A
npush
(x - y);
1
N/A
break
;
1
N/A
1
N/A
case
'*'
:
1
N/A
npush
(
npop
() *
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'/'
:
1
N/A
y =
npop
();
1
N/A
x =
npop
();
1
N/A
npush
(y ? (x / y) : 0);
1
N/A
break
;
1
N/A
1
N/A
case
'm'
:
1
N/A
y =
npop
();
1
N/A
x =
npop
();
1
N/A
npush
(y ? (x % y) : 0);
1
N/A
break
;
1
N/A
1
N/A
case
'A'
:
1
N/A
npush
(
npop
() &&
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'O'
:
1
N/A
npush
(
npop
() ||
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'&'
:
1
N/A
npush
(
npop
() &
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'|'
:
1
N/A
npush
(
npop
() |
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'^'
:
1
N/A
npush
(
npop
() ^
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'='
:
1
N/A
y =
npop
();
1
N/A
x =
npop
();
1
N/A
npush
(x == y);
1
N/A
break
;
1
N/A
1
N/A
case
'<'
:
1
N/A
y =
npop
();
1
N/A
x =
npop
();
1
N/A
npush
(x < y);
1
N/A
break
;
1
N/A
1
N/A
case
'>'
:
1
N/A
y =
npop
();
1
N/A
x =
npop
();
1
N/A
npush
(x > y);
1
N/A
break
;
1
N/A
1
N/A
case
'!'
:
1
N/A
npush
(!
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'~'
:
1
N/A
npush
(~
npop
());
1
N/A
break
;
1
N/A
1
N/A
case
'i'
:
1
N/A
if
(
p_is_s
[0] == 0)
1
N/A
param
[0]++;
1
N/A
if
(
p_is_s
[
1
] == 0)
1
N/A
param
[
1
]++;
1
N/A
break
;
1
N/A
1
N/A
case
'?'
:
1
N/A
break
;
1
N/A
1
N/A
case
't'
:
1
N/A
x =
npop
();
1
N/A
if
(!x) {
1
N/A
/* scan forward for %e or %; at level zero */
1
N/A
string
++;
1
N/A
level
= 0;
1
N/A
while
(*
string
) {
1
N/A
if
(*
string
==
'%'
) {
1
N/A
string
++;
1
N/A
if
(*
string
==
'?'
)
1
N/A
level
++;
1
N/A
else
if
(*
string
==
';'
) {
1
N/A
if
(
level
> 0)
1
N/A
level
--;
1
N/A
else
1
N/A
break
;
1
N/A
}
else
if
(*
string
==
'e'
&&
level
== 0)
1
N/A
break
;
1
N/A
}
1
N/A
1
N/A
if
(*
string
)
1
N/A
string
++;
1
N/A
}
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
'e'
:
1
N/A
/* scan forward for a %; at level zero */
1
N/A
string
++;
1
N/A
level
= 0;
1
N/A
while
(*
string
) {
1
N/A
if
(*
string
==
'%'
) {
1
N/A
string
++;
1
N/A
if
(*
string
==
'?'
)
1
N/A
level
++;
1
N/A
else
if
(*
string
==
';'
) {
1
N/A
if
(
level
> 0)
1
N/A
level
--;
1
N/A
else
1
N/A
break
;
1
N/A
}
1
N/A
}
1
N/A
1
N/A
if
(*
string
)
1
N/A
string
++;
1
N/A
}
1
N/A
break
;
1
N/A
1
N/A
case
';'
:
1
N/A
break
;
1
N/A
1
N/A
}
/* endswitch (*string) */
1
N/A
}
else
{
/* endelse (*string == '%') */
1
N/A
save_char
(*
string
);
1
N/A
}
1
N/A
1
N/A
if
(*
string
==
'\0'
)
1
N/A
break
;
1
N/A
1
N/A
string
++;
1
N/A
}
/* endwhile (*string) */
1
N/A
1
N/A
get_space
(
1
);
1
N/A
out_buff
[
out_used
] =
'\0'
;
1
N/A
1
N/A
return
(
out_buff
);
1
N/A
}
1
N/A
1
N/A
char
*
1
N/A
grub_tparm
(
const
char
*
string
,...)
1
N/A
{
1
N/A
char
*
result
;
1
N/A
int
*
dataptr
= (
int
*) &
string
;
1
N/A
1
N/A
dataptr
++;
1
N/A
1
N/A
result
=
tparam_internal
(
string
,
dataptr
);
1
N/A
1
N/A
return
result
;
1
N/A
}