2
Copyright (C) 2003-2004 Douglas Thain and the University of Wisconsin
3
Copyright (C) 2005- The University of Notre Dame
4
This software is distributed under the GNU General Public License.
5
See the file COPYING for details.
9
#include "ftsh_error.h"
10
#include "ast_execute.h"
11
#include "ast_print.h"
20
#include <sys/types.h>
25
static void expr_print_list( FILE *file, struct expr *e, int with_commas );
29
enum expr_type_t type;
32
static struct expr_table table[] = {
50
{".exists.",EXPR_EXISTS},
54
{".isblock.",EXPR_ISBLOCK},
55
{".ischar.",EXPR_ISCHAR},
56
{".isdir.",EXPR_ISDIR},
57
{".isfile.",EXPR_ISFILE},
58
{".islink.",EXPR_ISLINK},
59
{".ispipe.",EXPR_ISPIPE},
60
{".issock.",EXPR_ISSOCK},
64
const char *expr_type_to_string( enum expr_type_t type )
68
for(t=table;t->string;t++) {
69
if(t->type==type) return t->string;
75
static int digits_in_int( int i )
85
struct expr * expr_create( int line, enum expr_type_t type, struct ast_word *literal, struct expr *a, struct expr *b, struct expr *c )
87
struct expr *e = xxmalloc(sizeof(*e));
98
int expr_to_integer( struct expr *e, ftsh_integer_t *ival, time_t stoptime )
103
value = expr_eval(e,stoptime);
106
*ival = strtol(value,&end,10);
108
/* good conversion */
112
ftsh_error(FTSH_ERROR_FAILURE,e->line,"expected integer but got '%s' instead",value);
118
int expr_to_boolean( struct expr *e, ftsh_boolean_t *bval, time_t stoptime )
122
value = expr_eval(e,stoptime);
125
if(!strcmp(value,"true")) {
129
} else if(!strcmp(value,"false")) {
134
ftsh_error(FTSH_ERROR_FAILURE,e->line,"expected 'true' or 'false' but got %s instead",value);
140
static char * integer_to_string( int line, ftsh_integer_t i )
145
sprintf(istr,"%ld",i);
149
ftsh_error(FTSH_ERROR_FAILURE,line,"out of memory");
155
static char * boolean_to_string( int line, ftsh_boolean_t b )
166
ftsh_error(FTSH_ERROR_FAILURE,line,"out of memory");
172
static char * expr_eval_access( struct expr *e, time_t stoptime )
179
path = expr_eval(e->a,stoptime);
196
ftsh_fatal(e->line,"unexpected expression type %d",e->type);
200
ival = access(path,mode);
222
result = xstrdup("false");
229
result = xstrdup("true");
233
ftsh_error(FTSH_ERROR_COMMAND,e->line,"%s %s is %s",expr_type_to_string(e->type),path,result);
235
ftsh_error(FTSH_ERROR_FAILURE,e->line,"%s %s failed: %s",expr_type_to_string(e->type),path,strerror(errno));
241
static char * expr_eval_islink( struct expr *e, time_t stoptime )
248
path = expr_eval(e->a,stoptime);
251
result = readlink(path,buf,sizeof(buf));
254
} else switch(errno) {
261
r = xstrdup("false");
272
static char * expr_eval_filetype( struct expr *e, time_t stoptime )
279
path = expr_eval(e->a,stoptime);
282
ival = stat(path,&buf);
300
result = xstrdup("false");
310
ival = S_ISBLK(buf.st_mode);
313
ival = S_ISCHR(buf.st_mode);
316
ival = S_ISDIR(buf.st_mode);
319
ival = S_ISREG(buf.st_mode);
322
/* We should not get here because of shortcut earlier to avoid the broken S_ISLNK macro. */
324
ival = S_ISLNK(buf.st_mode);
327
ival = S_ISFIFO(buf.st_mode);
330
ival = S_ISSOCK(buf.st_mode);
333
ftsh_fatal(e->line,"unexpected expression type %d",e->type);
338
result = xstrdup("true");
340
result = xstrdup("false");
345
ftsh_error(FTSH_ERROR_COMMAND,e->line,"%s %s is %s",expr_type_to_string(e->type),path,result);
347
ftsh_error(FTSH_ERROR_FAILURE,e->line,"%s %s failed: %s",expr_type_to_string(e->type),path,strerror(errno));
353
static char * expr_eval_range( struct expr *e, time_t stoptime )
355
ftsh_integer_t i, ia, ib;
358
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ) {
363
/* use the step if we have it */
366
if(!expr_to_integer(e->c,&step,stoptime)) return 0;
371
digits = MAX(digits_in_int(ia),digits_in_int(ib));
372
/* add one for a unary - and for a space */
375
/* allocate enough space for the set */
376
r = xxmalloc((ABS((ib-ia)/step)+1)*digits+4);
380
/* fill up the text */
382
for( i=ia; i<=ib; i+=ABS(step) ) {
383
sprintf(&r[strlen(r)],"%ld ",i);
386
for( i=ib; i<=ia; i+=ABS(step) ) {
387
sprintf(&r[strlen(r)],"%ld ",i);
396
static char * expr_eval_fcall( struct expr *e, time_t stoptime )
404
name = ast_word_execute(e->line,e->literal);
407
for(f=e->a;f;f=f->next) argc++;
408
argv = xxmalloc( sizeof(char*)*argc );
409
for(i=0;i<argc;i++) argv[0] = 0;
410
argv[0] = xstrdup(name);
412
for(i=1;i<argc;i++) {
413
argv[i] = expr_eval(f,stoptime);
418
rval = ast_function_execute(e->line,argc,argv,stoptime);
420
for(i=i-1;i>=0;i--) free(argv[i]);
428
char * expr_eval( struct expr *e, time_t stoptime )
430
ftsh_integer_t i, ia, ib;
431
ftsh_boolean_t b, ba, bb;
436
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
438
r = integer_to_string(e->line,i);
442
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
444
r = integer_to_string(e->line,i);
448
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
450
r = integer_to_string(e->line,i);
454
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
456
r = integer_to_string(e->line,i);
460
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
462
r = integer_to_string(e->line,i);
466
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
472
r = integer_to_string(e->line,i);
476
ra = expr_eval(e->a,stoptime);
477
rb = expr_eval(e->b,stoptime);
481
r = boolean_to_string(e->line,b);
484
ra = expr_eval(e->a,stoptime);
485
rb = expr_eval(e->b,stoptime);
489
r = boolean_to_string(e->line,b);
492
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
494
r = boolean_to_string(e->line,b);
498
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
500
r = boolean_to_string(e->line,b);
504
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
506
r = boolean_to_string(e->line,b);
510
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
512
r = boolean_to_string(e->line,b);
516
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
518
r = boolean_to_string(e->line,b);
522
if( expr_to_integer(e->a,&ia,stoptime) && expr_to_integer(e->b,&ib,stoptime) ){
524
r = boolean_to_string(e->line,b);
528
if( expr_to_boolean(e->a,&ba,stoptime) && expr_to_boolean(e->b,&bb,stoptime) ){
530
r = boolean_to_string(e->line,b);
534
if( expr_to_boolean(e->a,&ba,stoptime) && expr_to_boolean(e->b,&bb,stoptime) ){
536
r = boolean_to_string(e->line,b);
540
if(expr_to_boolean(e->a,&b,stoptime)) {
541
r = boolean_to_string(e->line,!b);
548
r = expr_eval_access(e,stoptime);
556
r = expr_eval_filetype(e,stoptime);
559
r = expr_eval_islink(e,stoptime);
562
r = expr_eval(e->a,stoptime);
565
r = expr_eval_range(e,stoptime);
568
r = expr_eval_fcall(e,stoptime);
571
return ast_word_list_execute(e->line,e->literal);
578
void expr_print( FILE *file, struct expr *e )
580
expr_print_list(file,e,0);
583
static void expr_print_list( FILE *file, struct expr *e, int with_commas )
604
expr_print(file,e->a);
605
fprintf(file," %s ",expr_type_to_string(e->type));
606
expr_print(file,e->b);
620
fprintf(file,"%s ",expr_type_to_string(e->type));
621
expr_print(file,e->a);
624
expr_print(file,e->a);
625
fprintf(file," .to. ");
626
expr_print(file,e->b);
628
fprintf(file," .step. ");
629
expr_print(file,e->c);
635
expr_print(file,e->a);
639
ast_word_print(file,e->literal);
641
expr_print_list(file,e->a,1);
645
ast_word_print(file,e->literal);
648
ftsh_fatal(e->line,"unknown expression type %d",e->type);
658
expr_print(file,e->next);
662
int expr_is_list( struct expr *e )
664
if(e->type==EXPR_TO) {
666
} else if(e->type==EXPR_EXPR) {
667
return expr_is_list(e->a);