Exemplo n.º 1
0
/*! \brief Load a local configuration file.
 * \par Function Description
 * Attempts to load the configuration file with basename \a rcname
 * corresponding to \a path, reporting errors via \a err.  If \a path
 * is a directory, looks for a file named \a rcname in that
 * directory. Otherwise, looks for a file named \a rcname in the same
 * directory as \a path. If \a path is NULL, looks in the current
 * directory. If \a rcname is NULL, the default value of "gafrc" is
 * used.
 *
 * \param toplevel  The current #TOPLEVEL structure.
 * \param rcname    The basename of the configuration file to load, or NULL.
 * \param path      The path to load a configuration file for, or NULL.
 * \param err       Return location for errors, or NULL.
 * \return TRUE on success, FALSE on failure.
 */
gboolean
g_rc_parse_local (TOPLEVEL *toplevel, const gchar *rcname, const gchar *path,
                  GError **err)
{
  gchar *dir = NULL;
  gchar *rcfile = NULL;
  gboolean status;
  g_return_val_if_fail ((toplevel != NULL), FALSE);

  /* Default to gafrc */
  rcname = (rcname != NULL) ? rcname : "gafrc";
  /* Default to cwd */
  path = (path != NULL) ? path : ".";

  /* If path isn't a directory, get the dirname. */
  if (g_file_test (path, G_FILE_TEST_IS_DIR)) {
    dir = g_strdup (path);
  } else {
    dir = g_path_get_dirname (path);
  }

  rcfile = g_build_filename (dir, rcname, NULL);
  status = g_rc_parse_file (toplevel, rcfile, err);

  g_free (dir);
  g_free (rcfile);
  return status;
}
Exemplo n.º 2
0
/*! \brief General RC file parsing function.
 * \par Function Description
 * Attempt to load system, user and local (current working directory)
 * configuration files, first with the default "gafrc" basename and
 * then with the basename \a rcname, if \a rcname is not NULL.
 * Additionally, attempt to load configuration from \a rcfile if \a
 * rcfile is not NULL.
 *
 * If an error occurs, calls \a handler with the provided \a user_data
 * and a GError.
 *
 * \see g_rc_parse().
 *
 * \param toplevel  The current #TOPLEVEL structure.
 * \param rcname    Config file basename, or NULL.
 * \param rcfile    Specific config file path, or NULL.
 * \param handler   Handler function for config parse errors.
 * \param user_data Data to be passed to \a handler.
 */
void
g_rc_parse_handler (TOPLEVEL *toplevel,
                    const gchar *rcname, const gchar *rcfile,
                    ConfigParseErrorFunc handler, void *user_data)
{
  GError *err = NULL;

#ifdef HANDLER_DISPATCH
#  error HANDLER_DISPATCH already defined
#endif
#define HANDLER_DISPATCH \
  do { if (err == NULL) break;  handler (&err, user_data);        \
       g_error_free (err); err = NULL; } while (0)

  /* Load configuration files in order. */
  /* First gafrc files. */
  g_rc_parse_system (toplevel, NULL, &err); HANDLER_DISPATCH;
  g_rc_parse_user (toplevel, NULL, &err); HANDLER_DISPATCH;
  g_rc_parse_local (toplevel, NULL, NULL, &err); HANDLER_DISPATCH;
  /* Next application-specific rcname. */
  if (rcname != NULL) {
    g_rc_parse_system (toplevel, rcname, &err); HANDLER_DISPATCH;
    g_rc_parse_user (toplevel, rcname, &err); HANDLER_DISPATCH;
    g_rc_parse_local (toplevel, rcname, NULL, &err); HANDLER_DISPATCH;
  }
  /* Finally, optional additional config file. */
  if (rcfile != NULL) {
    g_rc_parse_file (toplevel, rcfile, &err); HANDLER_DISPATCH;
  }

#undef HANDLER_DISPATCH
}
Exemplo n.º 3
0
/*! \brief Opens the schematic file with fine-grained control over behaviour.
 *  \par Function Description
 *  Opens the schematic file and carries out a number of actions
 *  depending on the \a flags set.  If #F_OPEN_RC is set, executes
 *  configuration files found in the target directory.  If
 *  #F_OPEN_CHECK_BACKUP is set, warns user if a backup is found for
 *  the file being loaded, and possibly prompts user for whether to
 *  load the backup instead.  If #F_OPEN_RESTORE_CWD is set, does not
 *  change the working directory to that of the file being loaded.
 *
 *  \param [in,out] toplevel  The TOPLEVEL object to load the schematic into.
 *  \param [in]     filename   A character string containing the file name
 *                             to open.
 *  \param [in]     flags      Combination of #FOpenFlags values.
 *  \param [in,out] err  #GError structure for error reporting, or
 *                       NULL to disable error reporting
 *
 *  \return 0 on failure, 1 on success.
 */
int f_open_flags(TOPLEVEL *toplevel, PAGE *page,
                 const gchar *filename,
                 const gint flags, GError **err)
{
  int opened=FALSE;
  char *full_filename = NULL;
  char *full_rcfilename = NULL;
  char *file_directory = NULL;
  char *saved_cwd = NULL;
  char *backup_filename = NULL;
  char load_backup_file = 0;
  GError *tmp_err = NULL;

  /* has the head been freed yet? */
  /* probably not hack PAGE */

  set_window(toplevel, page,
             toplevel->init_left, toplevel->init_right,
             toplevel->init_top,  toplevel->init_bottom);


  /* Cache the cwd so we can restore it later. */
  if (flags & F_OPEN_RESTORE_CWD) {
    saved_cwd = g_get_current_dir();
  }

  /* get full, absolute path to file */
  full_filename = f_normalize_filename (filename, &tmp_err);
  if (full_filename == NULL) {
    g_set_error (err, G_FILE_ERROR, tmp_err->code,
                 _("Cannot find file %s: %s"),
                 filename, tmp_err->message);
    g_error_free(tmp_err);
    return 0;
  }

  /* write full, absolute filename into page->page_filename */
  g_free(page->page_filename);
  page->page_filename = g_strdup(full_filename);

  /* Before we open the page, let's load the corresponding gafrc. */
  /* First cd into file's directory. */
  file_directory = g_dirname (full_filename);

  if (file_directory) { 
    if (chdir (file_directory)) {
      /* Error occurred with chdir */
#warning FIXME: What do we do?
    }
  }

  /* Now open RC and process file */
  if (flags & F_OPEN_RC) {
    full_rcfilename = g_build_filename (file_directory, "gafrc", NULL);
    g_rc_parse_file (toplevel, full_rcfilename, &tmp_err);
    if (tmp_err != NULL) {
      /* Config files are allowed to be missing or skipped; check for
       * this. */
      if (!g_error_matches (tmp_err, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
          !g_error_matches (tmp_err, EDA_ERROR, EDA_ERROR_RC_TWICE)) {
        s_log_message ("%s\n", tmp_err->message);
      }
      g_error_free (tmp_err);
      tmp_err = NULL;
    }
  }

  g_free (file_directory);

  if (flags & F_OPEN_CHECK_BACKUP) {
    /* Check if there is a newer autosave backup file */
    GString *message;
    gboolean active_backup = f_has_active_autosave (full_filename, &tmp_err);
    backup_filename = f_get_autosave_filename (full_filename);

    if (tmp_err != NULL) g_warning ("%s\n", tmp_err->message);
    if (active_backup) {
      message = g_string_new ("");
      g_string_append_printf(message, _("\nWARNING: Found an autosave backup file:\n  %s.\n\n"), backup_filename);
      if (tmp_err != NULL) {
        g_string_append(message, _("I could not guess if it is newer, so you have to do it manually.\n"));
      } else {
        g_string_append(message, _("The backup copy is newer than the schematic, so it seems you should load it instead of the original file.\n"));
      }
      g_string_append (message, _("Gschem usually makes backup copies automatically, and this situation happens when it crashed or it was forced to exit abruptly.\n"));
      if (toplevel->load_newer_backup_func == NULL) {
        g_warning ("%s", message->str);
        g_warning (_("\nRun gschem and correct the situation.\n\n"));
      } else {
        /* Ask the user if load the backup or the original file */
        if (toplevel->load_newer_backup_func
            (toplevel->load_newer_backup_data, message)) {
          /* Load the backup file */
          load_backup_file = 1;
        }
      }
      g_string_free (message, TRUE);
    }
    if (tmp_err != NULL) g_error_free (tmp_err);
  }

  /* Now that we have set the current directory and read
   * the RC file, it's time to read in the file. */
  if (load_backup_file == 1) {
    /* Load the backup file */
    s_page_append_list (toplevel, page,
                        o_read (toplevel, NULL, backup_filename, &tmp_err));
  } else {
    /* Load the original file */
    s_page_append_list (toplevel, page,
                        o_read (toplevel, NULL, full_filename, &tmp_err));
  }

  if (tmp_err == NULL)
    opened = TRUE;
  else
    g_propagate_error (err, tmp_err);

  if (load_backup_file == 0) {
    /* If it's not the backup file */
    page->CHANGED=0; /* added 4/7/98 */
  } else {
    /* We are loading the backup file, so gschem should ask
       the user if save it or not when closing the page. */
    page->CHANGED=1;
  }

  g_free(full_filename);
  g_free(full_rcfilename);
  g_free (backup_filename);

  /* Reset the directory to the value it had when f_open was
   * called. */
  if (flags & F_OPEN_RESTORE_CWD) {
    if (chdir (saved_cwd)) {
      /* Error occurred with chdir */
#warning FIXME: What do we do?
    }
    g_free(saved_cwd);
  }

  return opened;
}