#ifndef SHELL_H
#define SHELL_H

#include "config.h"
#include "shelldefs.h"

/* Stuff for checking mail. */

EXTERN void remember_mail_dates ();
EXTERN void reset_mail_files ();
EXTERN void reset_mail_timer ();
EXTERN int time_to_check_mail ();
EXTERN void check_mail ();

EXTERN int absolute_pathname (char *);

extern char *current_user_name;

#ifdef __cplusplus
#pragma interface
#include "types.h"
#include "gassign.h"
#include "symbol.h"
#include "gfunc.h"  /* For GFunction */
#include "expression.h"

extern struct OArray ArgvArray;

extern void SetArgv(int argc, char** argv);
EXTERN int check_executable_file(char *name);
extern StringC *RemoveQuotes(const StringC *arg);
extern StringC *RemoveQuotes(const char *in_string, int in_length = -1);
extern Vector *GlobList(Root *arg);
extern char * extract_colon_unit (char *string, int *index);
void update_pwd(char *new_directory);

#if 0
class FileNode;
// Use this to simulate Multiple Inheritance
class FileNodeSeq : public GenSeq {
    FileNode& this_file;
  public:
    char *filename() const;
    FileNodeSeq(FileNode& str) : this_file(str) { }
    virtual Assignable * assignable() const;
};
#endif

class FileNode : public CharSeq {
    DECLARE_MEMBERS(FileNode)
  public:
    char *file_name;
//    friend FileNodeSeq;
#if 0
    StringC *_host;
    FileNode(char* fn) { file_name = fn; _host = NULL; ...; }
    StringC * host() { if (_host) return _host; return _host = extract_host; }
#else
    FileNode(char* fn) { file_name = fn; }
    FileNode(const StringC *fn) { file_name = fn->chars(); }
#endif
    int is_directory() const;
    char *filename() const { return file_name; }
    virtual Root *value(); // get contents. what if directory?
    virtual void printon(ostream& outs) const;
    virtual void assign(Root *new_value);
    virtual Root * index(index_t index);
    virtual size_t length();
    virtual GenSeq *sequence() const;
    virtual int sizeof_file() const;
    virtual void open(GenFile*, OpenFlags flags=0);
    virtual void xapply(void* dst, Type* dstType, ArgDesc& args);
    Root * dir_lookup(Root *arg);
    Root * prefix(Root *arg);
};

/* Header for environment manipulation library.
   Copyright (C) 1989, Free Software Foundation.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 1, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* We manipulate environments represented as these structures.  */

struct ProcessEnvironment
{
  /* Number of usable slots allocated in VECTOR.
     VECTOR always has one slot not counted here,
     to hold the terminating zero.  */
  int allocated; // -1 means vector is initial value of environ.
  /* A vector of slots, ALLOCATED + 1 of them.
     The first few slots contain strings "VAR=VALUE"
     and the next one contains zero.
     Then come some unused slots.  */
  char **vector;

  ProcessEnvironment(int size = 10);
  ~ProcessEnvironment();
  void init(); // Copy the environment given to this process into THIS.
  char *get(const char *var);
  void set (const char* var, const char* value);
  void unset (const char* var);
};

// Used to model the Unix environment (as used by getenv).

class EnvironMap : public Environment {
  public:
    ProcessEnvironment env;

    EnvironMap(int size);

    // Return the vector of environment E.
    // This is used to get something to pass to execve.
    char **vector() { return env.vector; }

    virtual Root *lookup_at(const char *name, int nlen = -1);
    virtual void set_at(Root *new_val, const char *name, int nlen = -1);
    virtual void printon(ostream&) const;
    virtual size_t length();
    virtual GenSeq*  keys();
};

//extern struct AssignableSplayMap Environ;
extern struct EnvironMap Environ;

class PipeType : public Type {
  public:
    PipeType();
    virtual void coerceFromRoot(void *dstAddr, Root *value) const;
    virtual void printon(ostream&) const;
};

extern PipeType Pipe;

struct ReadFileFrom : public Expression {
    Expr *filename;
    ReadFileFrom(Expr *filename);
    virtual Expression * traverse(struct TraverseData *data);
    virtual void eval(void* dst, Type* dstType, DisplayEnv *env);
};

#endif /* defined(__cplusplus) */
#endif /*! SHELL_H */
