6 #define SCHAR "icpPvmnu" /* scale indicators */
8 static int defunit
= 0; /* default scale indicator */
9 static int abspos
= 0; /* absolute position like |1i */
11 static int readunit(int c
, int n
)
17 return n
* SC_IN
* 50 / 127;
19 return n
* SC_IN
/ 72;
25 return n
* n_s
* SC_IN
/ 72;
27 return n
* n_s
* SC_IN
/ 144;
34 static int evalnum(char **_s
)
37 int n
= 0; /* the result */
38 int mag
= 0; /* n should be divided by mag */
39 while (isdigit(*s
) || *s
== '.') {
46 n
= n
* 10 + *s
++ - '0';
52 n
= readunit(*s
&& strchr(SCHAR
, *s
) ? *s
++ : defunit
, n
);
54 return n
/ (mag
> 0 ? mag
: 1);
57 static int evaljmp(char **s
, int c
)
66 static int evalisnum(char **s
)
68 return **s
== '.' || isdigit(**s
);
71 static int evalexpr(char **s
);
72 static int evalatom(char **s
);
74 static int evalatom(char **s
)
84 return abspos
+ evalatom(s
);
85 if (!evaljmp(s
, '(')) {
93 static int evalexpr(char **s
)
95 int ret
= evalatom(s
);
99 else if (!evaljmp(s
, '-'))
101 else if (!evaljmp(s
, '/'))
103 else if (!evaljmp(s
, '*'))
105 else if (!evaljmp(s
, '%'))
107 else if (!evaljmp(s
, '<'))
108 ret
= !evaljmp(s
, '=') ? ret
<= evalatom(s
) : ret
< evalatom(s
);
109 else if (!evaljmp(s
, '>'))
110 ret
= !evaljmp(s
, '=') ? ret
>= evalatom(s
) : ret
> evalatom(s
);
111 else if (!evaljmp(s
, '=') + !evaljmp(s
, '='))
112 ret
= ret
== evalatom(s
);
113 else if (!evaljmp(s
, '&'))
114 ret
= ret
&& evalatom(s
);
115 else if (!evaljmp(s
, ':'))
116 ret
= ret
|| evalatom(s
);
123 /* evaluate *s and update s to point to the last character read */
124 int eval_up(char **s
, int unit
)
130 abspos
= n_lb
- f_hpos();
134 /* evaluate s relative to its previous value */
135 int eval_re(char *s
, int orig
, int unit
)
138 int rel
= 0; /* n should be added to orig */
139 if (*s
== '+' || *s
== '-') {
140 rel
= *s
== '+' ? 1 : -1;
143 n
= eval_up(&s
, unit
);
145 return rel
> 0 ? orig
+ n
: orig
- n
;
150 int eval(char *s
, int unit
)
152 return eval_up(&s
, unit
);