Autoconf, Automake, and Libtool: Interpreting Commands from a File

| ## 20.3 Interpreting Commands from a File For all practical purposes, any interpreter is pretty useless if it only works interactively. I have added a ``source'` built-in command to ``sic_builtin.c'` which takes lines of input from a file and evaluates them using ``sic_repl.c'` in much the same way as lines typed at the prompt are evaluated otherwise. Here is the built-in handler:
    /* List of built in functions. */
    #define builtin_functions               \
            BUILTIN(exit,           0, 1)   \
            BUILTIN(load,           1, 1)   \
            BUILTIN(source,         1, -1)  \
            BUILTIN(unload,         1, -1)

    BUILTIN_DECLARATION (source)
    {
      int status = SIC_OKAY;
      int i;

      for (i = 1; status == SIC_OKAY && argv[i]; ++i)
        status = source (sic, argv[i]);

      return status;
    }
And the `source` function from ``sic_repl.c'`:
    int
    source (Sic *sic, const char *path)
    {
      FILE *stream;
      int result = SIC_OKAY;
      int save_interactive = is_interactive;

      SIC_ASSERT (sic && path);

      is_interactive = 0;

      if ((stream = fopen (path, "rt")) == NULL)
        {
          sic_result_clear (sic);
          sic_result_append (sic, "cannot source \"", path, "\": ",
                             strerror (errno), NULL);
          result = SIC_ERROR;
        }
      else
        result =  evalstream (sic, stream);

      is_interactive = save_interactive;

      return result;
    }
The reason for separating the `source` function in this way, is that it makes it easy for the startup sequence in `main` to evaluate a startup file. In traditional Unix fashion, the startup file is named ``.sicrc'`, and is evaluated if it is present in the user's home directory:
    static int
    evalsicrc (Sic *sic)
    {
      int result = SIC_OKAY;
      char *home = getenv ("HOME");
      char *sicrcpath, *separator = "";
      int len;

      if (!home)
        home = "";

      len = strlen (home);
      if (len && home[len -1] != '/')
        separator = "/";

      len += strlen (separator) + strlen (SICRCFILE) + 1;

      sicrcpath = XMALLOC (char, len);
      sprintf (sicrcpath, "%s%s%s", home, separator, SICRCFILE);

      if (access (sicrcpath, R_OK) == 0)
        result = source (sic, sicrcpath);

      return result;
    }

This document was generated by Gary V. Vaughan on February, 8 2006 using texi2html