3 #include <sys/syscalls.h>
9 #include "shell_defs.h"
10 #include "shell_vars.h"
20 struct token_info tokens
[]={
26 {"number",SVO_NUMBER_CAST
},
27 {"string",SVO_STRING_CAST
},
48 static int token_to_id(const char *token
)
52 while((tokens
[cnt
].token
!= NULL
) && (strcmp(tokens
[cnt
].token
,token
) != 0)) cnt
++;
54 return tokens
[cnt
].code
;
57 char *id_to_token(int id
)
63 case SVO_IDENT
:return "ident";
65 case SVO_DQ_STRING
:return "string";
66 case SVO_NUMBER
:return "number";
67 case SVO_END
:return "end";
70 while((tokens
[cnt
].token
!= NULL
) && (tokens
[cnt
].code
!= id
)) cnt
++;
72 if(tokens
[cnt
].token
!= NULL
){
74 return tokens
[cnt
].token
;
83 static bool scan_string(scan_info
*info
,int max_len
)
85 const char **in
=&(info
->scanner
);
87 char *scan
=info
->token
;
88 int len_cnt
= max_len
;
93 while((**in
!= 0) && (**in
!= ch
)){
110 info
->scan_error
= SHE_MISSING_QOUTE
;
120 int parse_line(const char *buf
, char *argv
[], int max_args
, char *redirect_in
, char *redirect_out
)
122 const char *scan
=buf
;
123 const char *type_char
;
125 char out
[SCAN_SIZE
+1];
126 char tmp
[SCAN_SIZE
+1];
137 while((*scan
!= 0) && (isspace(*scan
))) scan
++;
139 if(*scan
== 0) break;
153 while((*scan
!= 0) && (*scan
!= *start
)) scan
++;
159 while((*start
!= 0) && (isspace(*start
))) start
++;
164 while((*scan
!= 0) && (!isspace(*scan
))) scan
++;
169 if(*scan
!= 0) scan
++;
173 memcpy(tmp
,start
,len
);
175 parse_vars_in_string(tmp
,out
,SCAN_SIZE
);
179 memcpy(out
,start
,len
);
187 strcpy(redirect_out
,out
);
191 strcpy(redirect_in
,out
);
195 if(arg_cnt
< max_args
){
197 arg_tmp
= shell_strdup(out
);
198 if(arg_tmp
!= NULL
) argv
[arg_cnt
++] = arg_tmp
;
210 static void scan_ident(const char **in
,char *out
,int max_len
)
213 int len_cnt
= max_len
;
215 while ((**in
!= 0) && (IS_IDENT_CHAR(**in
))){
226 static void scan_number(const char **in
,char *out
,int max_len
)
229 int len_cnt
= max_len
;
231 while ( (**in
!= 0) && (isdigit(**in
)) ){
248 static void scan_comp(const char **in
,char *out
,int max_len
)
250 int num_cnt
= max_len
;
251 char *out_scan
= out
;
272 bool expect(scan_info
*info
,int check
)
274 if(info
->sym_code
== check
){
287 bool scan_info_next_line(scan_info
*info
)
289 if(info
->current
== NULL
) return false;
291 info
->current
= info
->current
->next
;
293 if(info
->current
== NULL
) return false;
297 return set_scan_info_line(info
);
300 bool scan_info_home(scan_info
*info
)
302 info
->current
= info
->data
.list
;
304 return set_scan_info_line(info
);
308 bool init_scan_info_by_file(const char *file_name
,scan_info
*info
)
310 int err
= SHE_NO_ERROR
;
312 err
= read_text_file(file_name
,&(info
->data
));
314 if(err
!= SHE_NO_ERROR
) return err
;
316 info
->scanner
= NULL
;
317 info
->scan_error
= SHE_NO_ERROR
;
319 if(scan_info_home(info
)) err
= SHE_SCAN_ERROR
;
325 bool set_scan_info_line(scan_info
*info
)
328 if(info
->current
== NULL
) return true;
330 strcpy(info
->input_line
,info
->current
->text
);
331 info
->scanner
= (info
->input_line
);
339 // return token type (STY_<> vars)
342 void init_scan_info(const char*in
,scan_info
*info
){
344 strncpy(info
->input_line
,in
,SCAN_SIZE
);
346 info
->input_line
[SCAN_SIZE
] = 0;
347 info
->scanner
=(const char*)info
->input_line
;
348 info
->scan_error
= SHE_NO_ERROR
;
349 info
->current
= NULL
;
356 bool scan(scan_info
*info
)
359 int sym_code
= SVO_NONE
;
360 const char **in
= &(info
->scanner
);
361 char tmp
[SCAN_SIZE
+1];
363 while((**in
!= 0) && (isspace(**in
))) (*in
)++;
367 scan_ident(in
,info
->token
,SCAN_SIZE
);
369 sym_code
= token_to_id(info
->token
);
370 if(sym_code
== SVO_NONE
) sym_code
= SVO_IDENT
;
372 } else if(isdigit(**in
)){
374 scan_number(in
,info
->token
,SCAN_SIZE
);
375 sym_code
= SVO_NUMBER
;
386 scan_comp(in
,info
->token
,SCAN_SIZE
);
391 err
= scan_string(info
,SCAN_SIZE
);
393 if(err
!= SHE_NO_ERROR
){
394 parse_vars_in_string(info
->token
,tmp
,SCAN_SIZE
);
395 strncpy(info
->token
,tmp
,SCAN_SIZE
);
396 info
->token
[SCAN_SIZE
] = 0;
399 sym_code
= SVO_DQ_STRING
;
403 sym_code
= SVO_SQ_STRING
;
404 err
=scan_string(info
,SCAN_SIZE
);
412 info
->token
[0] = **in
;
418 if(sym_code
== SVO_NONE
) sym_code
= token_to_id(info
->token
);
422 info
->sym_code
= sym_code
;
427 void parse_vars_in_string(const char *string
,char *out
,int max_len
)
429 const char *scan
= string
;
430 char buf
[SCAN_SIZE
+ 1];
432 char *out_scan
= out
;
436 int out_max_len
= max_len
;
440 while((*scan
!= 0) && (*scan
!= '\'') && (out_max_len
> 0)){
446 while ((*scan
!= 0) && (IS_IDENT_CHAR(*scan
)) &&(len_cnt
> 0)){
456 value
= get_value_by_name(buf
);
460 text
= shell_value_to_char(value
);
461 can_move
= strlen(text
);
463 if(can_move
> out_max_len
) can_move
= out_max_len
;
465 memcpy(out_scan
,text
,can_move
);
466 out_max_len
-= can_move
;
467 out_scan
+= can_move
;
489 static int launch(int (*cmd
)(int, char **), int argc
, char **argv
, char *r_in
, char *r_out
)
498 if(strcmp(r_in
, "")!= 0) {
499 new_in
= sys_open(r_in
, STREAM_TYPE_ANY
, 0);
501 new_in
= sys_create(r_in
,STREAM_TYPE_FILE
);
511 if(strcmp(r_out
, "")!= 0) {
512 new_out
= sys_open(r_out
, STREAM_TYPE_ANY
, 0);
514 new_out
= sys_create(r_out
,STREAM_TYPE_FILE
);
517 new_out
= sys_dup(1);
525 saved_in
= sys_dup(0);
526 saved_out
= sys_dup(1);
529 sys_dup2(new_out
, 1);
533 retval
= cmd(argc
, argv
);
535 sys_dup2(saved_in
, 0);
536 sys_dup2(saved_out
, 1);
538 sys_close(saved_out
);
549 int shell_parse(const char *buf
, int len
)
552 bool found_command
= false;
555 char redirect_in
[256];
556 char redirect_out
[256];
557 cmd_handler_proc
*handler
= NULL
;
561 // search for the command
562 argc
= parse_line(buf
, argv
, 64, redirect_in
, redirect_out
);
564 if(argc
== 0) return 0;
566 handler
= &cmd_create_proc
;
568 for(i
=0; cmds
[i
].cmd_handler
!= NULL
; i
++) {
569 if(strcmp(cmds
[i
].cmd_text
,argv
[0]) == 0){
570 handler
= cmds
[i
].cmd_handler
;
575 err
= launch(handler
, argc
, argv
, redirect_in
, redirect_out
);
577 for(cnt
= 0;cnt
<argc
;cnt
++) free(argv
[cnt
]);