2 * Copyright IBM Corp 2007
3 * Author: Hans-Joachim Picht <hans@linux.vnet.ibm.com>
5 * The original parser contained in this file was written by
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * Linux for System Hotplug Daemon
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 static enum op_prio op_prio_table
[] =
26 [OP_NEG
] = OP_PRIO_ADD
,
27 [OP_GREATER
] = OP_PRIO_CMP
,
28 [OP_LESSER
] = OP_PRIO_CMP
,
29 [OP_PLUS
] = OP_PRIO_ADD
,
30 [OP_MINUS
] = OP_PRIO_ADD
,
31 [OP_MULT
] = OP_PRIO_MULT
,
32 [OP_DIV
] = OP_PRIO_MULT
,
33 [OP_AND
] = OP_PRIO_AND
,
37 void free_term(struct term
*fn
)
42 case OP_SYMBOL_LOADAVG
:
43 case OP_SYMBOL_RUNABLE
:
75 void print_term(struct term
*fn
)
78 case OP_SYMBOL_LOADAVG
:
81 case OP_SYMBOL_RUNABLE
:
82 printf("runable_proc");
90 case OP_SYMBOL_SWAPRATE
:
93 case OP_SYMBOL_FREEMEM
:
100 printf("%f", fn
->value
);
104 print_term(fn
->left
);
109 print_term(fn
->left
);
121 print_term(fn
->left
);
148 printf("%f", fn
->value
);
150 case OP_SYMBOL_LOADAVG
:
151 case OP_SYMBOL_RUNABLE
:
155 case OP_SYMBOL_SWAPRATE
:
156 case OP_SYMBOL_FREEMEM
:
164 print_term(fn
->right
);
174 struct term
*parse_term(char **p
, enum op_prio prio
)
178 enum operation symop
;
180 { "loadavg", OP_SYMBOL_LOADAVG
},
181 { "runable_proc", OP_SYMBOL_RUNABLE
},
182 { "onumcpus", OP_SYMBOL_CPUS
},
183 { "idle", OP_SYMBOL_IDLE
},
184 { "swaprate", OP_SYMBOL_SWAPRATE
},
185 { "apcr", OP_SYMBOL_APCR
},
186 { "freemem", OP_SYMBOL_FREEMEM
},
188 struct term
*fn
, *new;
192 unsigned int i
, length
;
198 fn
= malloc(sizeof(struct term
));
204 sscanf(s
, "%lf %n", &value
, &length
);
210 fn
->left
= parse_term(&s
, prio
);
211 if (fn
->left
== NULL
)
214 } else if (*s
== '!') {
216 fn
= malloc(sizeof(struct term
));
220 fn
->left
= parse_term(&s
, prio
);
221 if (fn
->left
== NULL
)
223 } else if (isdigit(*s
)) {
226 sscanf(s
, "%lf %n", &value
, &length
);
227 for (i
= 0; i
< length
; i
++)
229 fn
= malloc(sizeof(struct term
));
234 } else if (*s
== '(') {
236 fn
= parse_term(&s
, OP_PRIO_NONE
);
237 if (fn
== NULL
|| *s
!= ')')
241 for (i
= 0; i
< sizeof(sym_names
)/sizeof(sym_names
[0]); i
++)
242 if (strncmp(s
, sym_names
[i
].name
,
243 strlen(sym_names
[i
].name
)) == 0)
245 if (i
>= sizeof(sym_names
)/sizeof(sym_names
[0]))
246 /* Term doesn't make sense. */
248 fn
= malloc(sizeof(struct term
));
251 fn
->op
= sym_names
[i
].symop
;
252 s
+= strlen(sym_names
[i
].name
);
283 if (prio
>= op_prio_table
[op
])
286 new = malloc(sizeof(struct term
));
291 new->right
= parse_term(&s
, op_prio_table
[op
]);
292 if (new->right
== NULL
) {
307 static double eval_double(struct term
*fn
, struct symbols
*symbols
)
314 case OP_SYMBOL_LOADAVG
:
315 return symbols
->loadavg
;
316 case OP_SYMBOL_RUNABLE
:
317 return symbols
->runable_proc
;
319 return symbols
->onumcpus
;
321 return symbols
->idle
;
322 case OP_SYMBOL_FREEMEM
:
323 return symbols
->freemem
;
325 return symbols
->apcr
;
326 case OP_SYMBOL_SWAPRATE
:
327 return symbols
->swaprate
;
331 return -eval_double(fn
->left
, symbols
);
333 return eval_double(fn
->left
, symbols
) +
334 eval_double(fn
->right
, symbols
);
336 return eval_double(fn
->left
, symbols
) -
337 eval_double(fn
->right
, symbols
);
339 a
= eval_double(fn
->left
, symbols
);
340 b
= eval_double(fn
->right
, symbols
);
342 /*return eval_double(fn->left, symbols) *
343 eval_double(fn->right, symbols);*/
345 a
= eval_double(fn
->left
, symbols
);
346 b
= eval_double(fn
->right
, symbols
);
349 /*return eval_double(fn->left, symbols) /
350 eval_double(fn->right, symbols); */
359 fprintf(stderr
, "Invalid term specified: %i\n", fn
->op
);
365 int eval_term(struct term
*fn
, struct symbols
*symbols
)
367 if (fn
== NULL
|| symbols
== NULL
)
371 return !eval_term(fn
->left
, symbols
);
373 return eval_term(fn
->left
, symbols
) == 1 ||
374 eval_term(fn
->right
, symbols
) == 1;
376 return eval_term(fn
->left
, symbols
) == 1 &&
377 eval_term(fn
->right
, symbols
) == 1;
379 return eval_double(fn
->left
, symbols
) >
380 eval_double(fn
->right
, symbols
);
382 return eval_double(fn
->left
, symbols
) <
383 eval_double(fn
->right
, symbols
);
385 return eval_double(fn
, symbols
) != 0.0;