/*** shell.h ***/

# ifndef SHELL_H
# define SHELL_H

# define ISVAR(a) (isalnum (a) || (a == ':') || (a == '_'))
# define ISWORD(a,q) ((q) ? (a != '"') : (isalnum(a) || (a == '/') || (a == '.') || (a == '_') || (a == '-')))
# define ISNUM(c) (isdigit(c) || (c == '-') || (c == '.'))

/*** typedef structs used by shell functions ***/
typedef struct {			/* basic opihi command structure */
  char     *name;
  Function *func;    
  char     *help;
} Command;

typedef struct {			/* a macro (collection of commands) */
  char   *name;
  char  **line;
  int     Nlines;
} Macro;

typedef struct {			/* a list (macro/loop currently being executed) */
  char **line;
  int    n;
  int    Nlines;
} List;

/*** globals used to track the shell language concepts  ***/
List         *lists;			/* variable to store the list of all lists */
int          Nlists;			/* number of currently available lists */

int 	     interrupt;			/* true if C-C has been pressed */
int 	     auto_break;		/* if true, zero exit status forces macros to escape */
int 	     loop_break;		/* set to true when break is called */
int 	     loop_continue;		/* set to true when continue is called */
int          is_script;                 /* being run within a shell script */

/*** basic opihi shell functions ***/
void          initialize            	PROTO((int argc, char **argv));
void          startup               	PROTO((int argc, char **argv));
char        **multicommand          	PROTO((char *line, int *nlist));
int           command               	PROTO((char *, char **));
char         *expand_vars           	PROTO((char *line));
char         *expand_vectors        	PROTO((char *line));
char         *parse                 	PROTO((char *line));
char        **parse_commands        	PROTO((char *, int *));

int           is_for_loop           	PROTO((char *line));
int           is_if_block           	PROTO((char *line));
int           is_list               	PROTO((char *line));
int           is_loop               	PROTO((char *line));
int           is_macro_create       	PROTO((char *line));

void          InitCommands              PROTO(());
void          AddCommand                PROTO((Command *new));
int           DeleteCommand             PROTO((Command *command));
Command      *MatchCommand              PROTO((char *name, int VERBOSE, int EXACT));
void          sort_commands             PROTO((int *seq));

void          SetCurrentMacroData	PROTO((char *name, int depth));
Macro        *NewMacro			PROTO((char *name));
int           DeleteMacro		PROTO((Macro *macro));
Macro        *MatchMacro		PROTO((char *name, int VERBOSE, int EXACT));
void          InitMacros                PROTO((void));
char         *GetMacroName              PROTO((void));
int           GetMacroDepth             PROTO((void));

int           exec_loop                 PROTO((Macro *loop));
char         *get_next_listentry    	PROTO((int ThisList));
char         *remove_listentry      	PROTO((int current));
int           ConfigInit            	PROTO((int *argc, char **argv));
char         *VarConfig             	PROTO((char *keyword, char *mode, void *ptr));
FILE         *GetOutfile            	PROTO((void));
void          InitOutfile           	PROTO((void));

int           push_error                PROTO((char *line));
int           print_error               PROTO((void));
void          handle_interrupt      	PROTO((int));
char        **command_completer     	PROTO((const char *, int, int));
char         *command_generator     	PROTO((const char *text, int state));
char        **completion_matches    	PROTO((char *, rl_compentry_func_t *));
void          print_commands            PROTO((FILE *f));
void          InitCommands              PROTO((void));

/* command line parsing */
char         *thisword              	PROTO((char *));
char         *nextword              	PROTO((char *));
char         *lastword              	PROTO((char *, char *));
char         *thisvar               	PROTO((char *));
char         *aftervar              	PROTO((char *));
char         *lastvar               	PROTO((char *, char *));
char         *thiscomm              	PROTO((char *));
char         *nextcomm              	PROTO((char *));

/* macro functions (mapped to commands) */
int 	      macro_create 		PROTO((int, char **)); 
int 	      macro_delete 		PROTO((int, char **)); 
int 	      macro_edit   		PROTO((int, char **));
int 	      macro_exec   		PROTO((int, char **));
int 	      macro_list_f 		PROTO((int, char **));  /* "macro_list" is a readline func */
int 	      macro_read   		PROTO((int, char **));
int 	      macro_write  		PROTO((int, char **));

# endif
