Logo Search packages:      
Sourcecode: bazaar version File versions

cmdutils.c

/* cmdutils.c: 
 *
 ****************************************************************
 * Copyright (C) 2004 Tom Lord, Canonical Ltd.
 * 
 * See the file "COPYING" for further information about
 * the copyright and warranty status of this work.
 */


#include "hackerlab/bugs/panic.h"
#include "hackerlab/vu/safe.h"
#include "hackerlab/vu/vu.h"
#include "hackerlab/os/errno.h"
#include "hackerlab/os/errno-to-string.h"
#include "hackerlab/char/str.h"
#include "commands/cmdutils.h"
#include "commands/diff.h"
#include "libarch/libraries.h"
#include "libarch/project-tree.h"
#include "libarch/patch-logs.h"
#include "libarch/pfs.h"
#include "libarch/local-cache.h"
#include "libfsutils/dir-as-cwd.h"
#include "libarch/local-cache.h"
#include "libarch/changeset-report.h"
#include "libarch/project-tree.h"
#include "libarch/make-changeset.h"
#include "libarch/inode-sig.h"
#include "libarch/arch.h"


/* __STDC__ prototypes for static functions */
static t_uchar * missing_string (enum arch_valid_package_name_types type);
static t_uchar * name_string (enum arch_valid_package_name_types type);
static enum arch_parse_package_name_type valid_to_parse (enum arch_valid_package_name_types type);



/* Gather a fully-qualified revision name from the current tree
 * and input (e.g. patch-10)
 */
t_uchar *
arch_fqrvsn_from_tree_and_input (t_uchar *cmd,
                                 t_uchar * string,
                                 t_uchar * dir)
{
  t_uchar * ret = 0;
  arch_project_tree_t tree;
  
  if (arch_valid_package_name (string, arch_req_archive, arch_req_patch_level, 0))
    return str_save (0, string);

  arch_project_tree_init (&tree, dir);
  if (!tree.root)
    {
      safe_printfmt (2, "%s: not in a project tree\n  dir: %s\n", cmd, directory_as_cwd (dir));
      exit (2);
    }

  if (!tree.fqversion)
    {
      safe_printfmt (2, "%s: no tree-version set\n  tree: %s\n", cmd, tree.root);
      exit (2);
    }

  if (arch_valid_package_name (string, arch_maybe_archive, arch_req_patch_level, 0))
    {
      ret = arch_fully_qualify (tree.archive, string);
    }
  else if (arch_valid_package_name (string, arch_maybe_archive, arch_req_version, 0))
    {
      t_uchar * archive = arch_parse_package_name (arch_ret_archive, tree.archive, string);
      t_uchar * version = arch_parse_package_name (arch_ret_package_version, 0, string);
      t_uchar * patch_level = arch_highest_patch_level (tree.root, archive, version);
      t_uchar * revision = str_alloc_cat_many (0, version, "--", patch_level, str_end);

      ret = arch_fully_qualify (archive, revision);

      lim_free (0, archive);
      lim_free (0, version);
      lim_free (0, patch_level);
      lim_free (0, revision);
    }
  else 
    {
      ret = str_alloc_cat_many (0, tree.fqversion, "--", string, str_end); 
      if (!arch_valid_package_name (ret, arch_req_archive, arch_req_patch_level, 0))
        {
          safe_printfmt (2, "%s: invalid revision or patch name (%s)\n", cmd, string);
          exit (2);
        }
    }
  arch_project_tree_finalise (&tree);
  return ret;
}


int
arch_category_exists (struct arch_archive *arch, t_uchar * package)
{
  t_uchar * category = 0;
  rel_table categories = 0;
  int x;
  
  category = arch_parse_package_name (arch_ret_category, 0, package);
  categories = arch_archive_categories (arch);
  for (x = 0; x < rel_n_records (categories); ++x)
    {
      if (!str_cmp (category, categories[x][0]))
      {
        lim_free (0, category);
        rel_free_table (categories);
        return 1;
      }
    }
  return 0;
}


int 
arch_package_exists (struct arch_archive * arch, t_uchar * package)
{
  t_uchar * category = 0;
  t_uchar * branch = 0;
  rel_table categories = 0;
  rel_table branches = 0;
  int x;
  int found_it = 0;

  category = arch_parse_package_name (arch_ret_category, 0, package);
  branch = arch_parse_package_name (arch_ret_package, 0, package);

  categories = arch_archive_categories (arch);
  for (x = 0; x < rel_n_records (categories); ++x)
    {
      if (!str_cmp (category, categories[x][0]))
        break;
    }

  if (x < rel_n_records (categories))
    {
      branches = arch_archive_branches (arch, category);

      for (x = 0; x < rel_n_records (branches); ++x)
        {
          if (!str_cmp (branch, branches[x][0]))
            {
              found_it = 1;
              break;
            }
        }
    }

  lim_free (0, category);
  lim_free (0, branch);
  rel_free_table (categories);
  rel_free_table (branches);
  return found_it;
}

int 
arch_version_exists (struct arch_archive * arch, t_uchar * version_spec)
{
  t_uchar * branch = 0;
  t_uchar * version = 0;
  rel_table versions = 0;
  int x;
  int found_it = 0;

  branch = arch_parse_package_name (arch_ret_package, 0, version_spec);
  version = arch_parse_package_name (arch_ret_package_version, 0, version_spec);
  versions = arch_archive_versions (arch, branch);

  for (x = 0; x < rel_n_records (versions); ++x)
    {
      if (!str_cmp (version, versions[x][0]))
        {
          found_it = 1;
          break;
        }
    }
  lim_free (0, branch);
  lim_free (0, version);
  rel_free_table (versions);
  return found_it;
}

/* Checks whether the specified item (and all its components) exist
 */
void
arch_check_for (struct arch_archive * arch,
                enum arch_valid_package_name_types type,
                t_uchar * package)
{
  t_uchar * spec = arch_parse_package_name (arch_ret_non_archive, "", package);
  int missing = -1;
  /* note fall-through behavior */
  switch (type)
    {
      case arch_req_patch_level:
        if (arch_revision_exists (arch, spec))
          break;
        else
          missing = arch_req_patch_level;

      default:
        if (!arch_category_exists (arch, spec))
          {
            missing=arch_req_category;
            break;
          }
        if (type == arch_req_category)
          break;

        if (!arch_package_exists (arch, spec))
          {
            missing = arch_req_package;
            break;
          }
        if (type == arch_req_package)
          break;

        if (!arch_version_exists (arch, spec))
          missing = arch_req_version;
    };
  if (missing != -1)
    {
      arch_print_missing (arch, missing, type, spec);
      exit (2);
    }
  lim_free (0, spec);
}

void
arch_print_missing (struct arch_archive * arch,
                    enum arch_valid_package_name_types type,
                    enum arch_valid_package_name_types supplied_type,
                    t_uchar * spec)
{
  t_uchar * name = missing_string (type);
  t_uchar * supplied_name = name_string (supplied_type);
  t_uchar * portion = arch_parse_package_name (valid_to_parse(type), arch->official_name, spec);
  t_uchar * nonarch = arch_parse_package_name (arch_ret_non_archive, "", spec);
  safe_printfmt (2, "No such %s (%s)\n", name, portion);
  safe_printfmt (2, "  name: %s\n  location: %s\n  %s: %s\n", arch->name, arch->location, supplied_name, nonarch);
  lim_free (0, portion);
  lim_free (0, nonarch);
}

static t_uchar * 
missing_string (enum arch_valid_package_name_types type)
{
  switch (type)
    {
      case arch_req_category:
        return "category";
        break;

      case arch_req_package:
        return "package";
        break;

      case arch_req_version:
        return "version";
        break;

      case arch_req_patch_level:
        return "patchlevel";
        break;
      
      default:
        panic ("missing_string: bad argument.");
        return 0;
    };
}

static t_uchar * 
name_string (enum arch_valid_package_name_types type)
{
  switch (type)
    {
      case arch_req_category:
        return "category";
        break;

      case arch_req_package:
        return "package";
        break;

      case arch_req_version:
        return "package-version";
        break;

      case arch_req_patch_level:
        return "revision";
        break;
      
      default:
        panic ("name_string: bad argument.");
        return 0;
    };
}


static enum arch_parse_package_name_type
valid_to_parse (enum arch_valid_package_name_types type)
{
  switch (type)
  {
    case arch_req_category:
      return arch_ret_category;
      break;
    case arch_req_package:
      return arch_ret_package;
      break;
    case arch_req_version:
      return arch_ret_version;
      break;
    case arch_req_patch_level:
      return arch_ret_patch_level;
      break;
    default:
      panic ("valid_to_parse: bad argument.");
      return 0;  
  };
}



void
arch_check_library_for_revision (t_uchar * archive,
                                 t_uchar * revision)
{
  t_uchar * loc = arch_library_find (0, archive, revision, 0);
  if (loc)
     {
   lim_free (0, loc);
    }
  else
    {
      safe_printfmt (2, "Could not find revision in any library:\n%s/%s\n", archive, revision);
      exit (2);
    }
}

t_uchar * 
safe_tree_version (t_uchar * cmd_name)
{
  arch_project_tree_t tree;
  arch_project_tree_init (&tree, ".");
  t_uchar * tree_version = 0;

  if (!tree.root)
    {
      safe_printfmt (2, "%s: not in a project tree\n  dir: %s\n", cmd_name, directory_as_cwd ("."));
      exit (2);
    }
  if (!tree.fqversion)
    {
      safe_printfmt (2, "%s: no tree-version set\n  tree: %s\n", cmd_name, tree.root);
      exit (2);
    }
  tree_version = tree.fqversion;
  tree.fqversion = NULL;
  arch_project_tree_finalise (&tree);
  return tree_version;
}

static t_uchar *
arch_determine_fqrevision_safe_latest_revision (struct arch_archive *arch, t_uchar *version_spec, t_uchar const *cmd_name)
{
    t_uchar * version;
    t_uchar * revision;
    arch_check_for (arch, arch_req_version, version_spec);
    version = arch_parse_package_name (arch_ret_package_version, 0, version_spec);
    version_spec = arch_archive_latest_revision (arch, version, 2);
    
    if (!version_spec)
      {
      safe_printfmt (1, "%s: version has no revisions (%s/%s)\n", cmd_name, arch->official_name, version);
      exit (1);
      }
    revision = arch_fully_qualify ((t_uchar  *)arch->name /*deliberately not official_name */, version_spec);
    
    lim_free (0, version);
    lim_free (0, version_spec);
    return revision;
}

static t_uchar *
arch_determine_fqrevision_common (struct arch_archive ** arch,
                         t_uchar * default_archive,
                         t_uchar * revision_spec,
                         t_uchar * cmd_name)
{
  t_uchar * archive = 0;
  t_uchar * new_revision_spec = 0;
  if (!arch_valid_package_name (revision_spec, arch_maybe_archive, arch_req_version, 1))
    {
      if (!arch_valid_patch_level_name (revision_spec))
        {
          safe_printfmt (2, "%s: illegal revision spec (%s)\n", cmd_name, revision_spec);
          exit (1);
        }
      else
        {
        /* given a patch-level */
          t_uchar * tree_version = safe_tree_version (cmd_name);
          new_revision_spec = str_alloc_cat_many (0, tree_version, "--", revision_spec, str_end);
        }
    }
  else new_revision_spec = str_save (0, revision_spec);

  archive = arch_parse_package_name (arch_ret_archive, default_archive, new_revision_spec);

  *arch = arch_archive_connect (archive, 0);
  
  lim_free (0, archive);
  return new_revision_spec;
}

t_uchar *
arch_determine_fqrevision (struct arch_archive ** arch,
                         t_uchar * default_archive,
                         t_uchar * revision_spec,
                         t_uchar * cmd_name)
{
  t_uchar * revision = 0;
  t_uchar * new_revision_spec = arch_determine_fqrevision_common (arch, default_archive, revision_spec, cmd_name);
  if (arch_valid_package_name (new_revision_spec, arch_maybe_archive, arch_req_patch_level, 0))
    {
      arch_check_for (*arch, arch_req_patch_level, new_revision_spec);
      revision = str_save (0, new_revision_spec);
    }
  else
    {
      revision = arch_determine_fqrevision_safe_latest_revision (*arch, new_revision_spec, cmd_name);
    }
  lim_free (0, new_revision_spec);
  return revision;
}

t_uchar *
arch_determine_fqrevision_next (struct arch_archive ** arch,
                         t_uchar * default_archive,
                         t_uchar * revision_spec,
                         t_uchar * cmd_name)
{
  t_uchar * fqrevision_next;
  t_uchar * current;
  t_uchar * new_revision_spec = arch_determine_fqrevision_common (arch, default_archive, revision_spec, cmd_name);
  if (arch_valid_package_name (new_revision_spec, arch_maybe_archive, arch_req_patch_level, 0))
    current = arch_fully_qualify ((*arch)->name, new_revision_spec);
  else
    current = arch_determine_fqrevision_safe_latest_revision (*arch, new_revision_spec, cmd_name);
  
    {
      t_uchar * revision = arch_parse_package_name (arch_ret_non_archive, "", current);
      t_uchar * spec = arch_parse_package_name (arch_ret_package_version, "", current);
      t_uchar * patchlevel = arch_parse_package_name (arch_ret_patch_level, "", current);
      if (arch_revision_exists (*arch, revision))
      {
        t_uchar * revision_next = arch_next_revision (spec,patchlevel,0,0,cmd_name);
        fqrevision_next = arch_fully_qualify ((*arch)->name, revision_next);
        lim_free (0, revision);
        lim_free (0, revision_next);
      }
      else
        fqrevision_next = str_save(0, current);
      lim_free (0, spec);
      lim_free (0, patchlevel);
    }
  lim_free (0, current);
  lim_free (0, new_revision_spec);
  return fqrevision_next;
}
/*
 * using the local tree if any, the default archive, and the revision spec,
 * determine the specified revision.
 * Leaves arch connected to the archive within which this revision should be 
 * found
 */
t_uchar *
arch_determine_revision (struct arch_archive ** arch,
                         t_uchar * default_archive,
                         t_uchar * revision_spec,
                         t_uchar * cmd_name)
{
    t_uchar * fqrevision = arch_determine_fqrevision (arch, default_archive, revision_spec, cmd_name);
    t_uchar * revision = arch_parse_package_name (arch_ret_non_archive, 0, fqrevision);
    lim_free (0, fqrevision);
    return revision;
    
}

/* as arch_determine_revision, but return the patch level above the one requested
 * If the one requested doesn't exist, it will be returned.
 * in a present branch, permit it
 */
t_uchar *
arch_determine_revision_next (struct arch_archive ** arch,
                         t_uchar * default_archive,
                         t_uchar * revision_spec,
                         t_uchar * cmd_name)
{
    t_uchar * fqrevision = arch_determine_fqrevision_next (arch, default_archive, revision_spec, cmd_name);
    t_uchar * revision = arch_parse_package_name (arch_ret_non_archive, 0, fqrevision);
    lim_free (0, fqrevision);
    return revision;
    
}

/* check that a directory is accessible and optionally writable */
void 
arch_check_directory (t_uchar *path, int check_write)
{
  int errn;
  int mode = R_OK+X_OK;
  struct stat statb;
  if (check_write) mode+=W_OK;
  if (vu_stat (&errn, path, &statb) == -1)
    {
       if (errn == ENOENT)
         safe_printfmt (2, "Specified directory does not exist\nPath: %s\n", path);
       else
         safe_printfmt (2, "Error encountered accessing directory (%s)\nPath: %s\n", errno_to_string (errn), path);
       
       exit(2);
    }
  if (!S_ISDIR(statb.st_mode))
    {
      safe_printfmt (2, "Specified path is not a directory\nPath: %s\n", path);
      exit (2);
    }
  if (access (path, mode) == -1)
    {
      safe_printfmt (2, "Error accessing specified directory (%s)\nDirectory: %s\n", errno_to_string (errno), path);
      exit (2);
    }
}

void 
arch_check_uri (t_uchar * uri)
{
  /* hackish, I know - should be a any_of search RBC20041202 */
  if (!str_chr_index (uri, '\n') && 
      !str_chr_index (uri, '\r') && 
      arch_valid_uri (uri))
    return;

  safe_printfmt (2, "URL invalid or unsupported: %s\n", uri);
  exit (2);
}


/**
 * Check whether the revision exists, using local data first, before
 * trying the archive
 * archive: the archive containg the revision
 * revision: the unqualified revision
 */
extern void
arch_check_revision_local (t_uchar * archive,
                           t_uchar * revision)
{
  struct arch_archive * arch = 0;
  t_uchar * loc = arch_library_find (0, archive, revision, 0);
  if (loc)
    {
      lim_free (0, loc);
      return;
    }
  arch = arch_archive_connect (archive, 0);
  arch_check_for (arch, arch_req_patch_level, revision);
  arch_archive_close (arch);
}


/**
 * Check the archive to make sure it's suitable for normal use, and not just
 * for mirroring.
 */
extern void arch_check_arch (struct arch_archive *arch)
{
  if (str_cmp (arch->name, arch->official_name) != 0)
  {
    safe_printfmt (2, "This archive can only be used as a mirror source or target, because it is \nregistered with the wrong name.  To use it for other purposes, you should\nregister it using the official name.\n");
    safe_printfmt (2, "name: %s\nofficial name: %s\nlocation: %s\n", arch->name, arch->official_name, arch->location);
    exit (2);
  }
}

t_uchar *
arch_project_tree_revision (t_uchar const * name, t_uchar const * tree_root)
{
    t_uchar * result;
    arch_project_tree_t tree;

    arch_project_tree_init (&tree, tree_root);
    
    if (!tree.fqversion)
      {
        safe_printfmt (2, "%s: no tree-version set\n  tree: %s\n",
                       name, tree_root);
        exit (2);
      }
    
    result = tree.fqrevision;
    tree.fqrevision=NULL;
    
    arch_project_tree_finalise (&tree);

    return result;
}

void
arch_cmd_fail (t_uchar const *name, char const * format, ...)
{
  va_list ap;

  safe_printfmt (2, "%s :", name);
  va_start (ap, format);
  safe_printfmt_va_list (2, format, ap);
  va_end (ap);
  safe_flush (2);
  exit (2);
}


t_uchar * 
arch_archive_last_level (struct arch_archive * arch, t_uchar *version)
{
  t_uchar * last_level = 0;
  rel_table revisions = arch_archive_revisions (arch, version, 0);

  if (revisions)
    {
      last_level = str_save (0, revisions[rel_n_records (revisions) - 1][0]);
    }
  rel_free_table (revisions);
  return last_level;
}

t_uchar * 
arch_next_revision (t_uchar * version, t_uchar * last_level, int seal, int fix, t_uchar * argv0)
{
  enum arch_patch_level_type last_level_type;
  enum arch_patch_level_type desired_level_type;
  t_ulong last_n;
  t_ulong desired_n;
  t_uchar * desired_level = 0;
  t_uchar * revision = 0; 

  last_level_type = arch_analyze_patch_level (&last_n, last_level);

  switch (last_level_type)
    {
    default:
      panic ("NOT IMPLEMENTED YET");
      panic ("internal error");
      break;

    case arch_is_base0_level:
      {
      if (seal)
        {
          desired_level_type = arch_is_version_level;
          desired_n = 0;
        }
      else if (fix)
        {
          safe_printfmt (2, "%s: can not --fix before --seal\n", argv0);
          exit (2);
        }
      else
        {
          desired_level_type = arch_is_patch_level;
          desired_n = 1;
        }
      break;
      }

    case arch_is_patch_level:
      {
      if (seal)
        {
          desired_level_type = arch_is_version_level;
          desired_n = 0;
        }
      else if (fix)
        {
          safe_printfmt (2, "%s: can not --fix before --seal\n", argv0);
          exit (2);
        }
      else
        {
          desired_level_type = arch_is_patch_level;
          desired_n = last_n + 1;
        }
      break;
      }

    case arch_is_version_level:
      {
      if (seal)
        {
          safe_printfmt (2, "%s: version already sealed\n", argv0);
          exit (2);
        }
      else if (fix)
        {
          desired_level_type = arch_is_versionfix_level;
          desired_n = 1;
        }
      else
        {
          safe_printfmt (2, "%s: cannot commit to sealed version without --fix\n",
                     argv0);
          exit (2);
        }
      break;
      }

    case arch_is_versionfix_level:
      {
      if (seal)
        {
          safe_printfmt (2, "%s: version already sealed\n", argv0);
          exit (2);
        }
      else if (fix)
        {
          desired_level_type = arch_is_versionfix_level;
          desired_n = last_n + 1;
        }
      else
        {
          safe_printfmt (2, "%s: cannot commit to sealed version without --fix\n",
                     argv0);
          exit (2);
        }
      break;
      }
    }
  desired_level = arch_form_patch_level (desired_level_type, desired_n);
  revision = str_alloc_cat_many (0, version, "--", desired_level, str_end);
  lim_free (0, desired_level);

  return revision;
}

t_uchar *
arch_version_spec_to_fq_version(t_uchar * version_spec)
{
  t_uchar * archive;
  t_uchar * version;
  t_uchar * fqversion;
  archive = arch_parse_package_name (arch_ret_archive, NULL, version_spec);
  version = arch_parse_package_name (arch_ret_package_version, 0, version_spec);
  fqversion = arch_fully_qualify (archive, version);
  return fqversion;
}

void
arch_assert_in_tree(t_uchar * program_name, t_uchar * dir)
{
  t_uchar * tree_root;
  tree_root = arch_tree_root (0, dir, 0);

  if (!tree_root)
    {
      safe_printfmt (2, "%s: not in project tree (%s)\n", program_name, dir);
      exit (1);
    }
}

/* Does arch_tree_root(dir) have any uncommited changes? */
int
arch_any_local_changes (t_uchar * program_name, t_uchar * dir)
{
  arch_project_tree_t tree;
  t_uchar * orig_tree = 0;
  struct arch_make_changeset_report make_report = {0, };
  struct arch_changeset_report report = {0, };
  assoc_table inode_shortcut = 0;
  t_uchar * output = 0;
  rel_table limits = 0;
  int result = 0;

  arch_project_tree_init (&tree, dir);
  output = arch_diff_default_output_dir (tree.root, NULL);

  orig_tree = arch_find_or_make_local_copy (1, tree.root, 0, 0, tree.archive, tree.revision);
  /* Is this neccessary? -rjw 20050109 */
  if (!orig_tree)
    {
      safe_printfmt (2, "%s: no local copies to compare to (%s/%s)\n  consider `add-pristine --help'\n",
                 program_name, tree.archive, tree.revision);
      exit (2);
    }

  arch_read_inode_sig_ids (0, &inode_shortcut, tree.root, tree.archive, tree.revision);
  arch_make_changeset (&make_report, orig_tree, tree.root, output, arch_unspecified_id_tagging, arch_inventory_unrecognized, limits, inode_shortcut, 0, arch_escape_classes);
  arch_evaluate_changeset (&report, output);
  result = arch_any_changes (&report);
  arch_project_tree_finalise (&tree);
  return result;
}

extern t_uchar *
arch_interpret_delta_path (t_uchar ** arch, t_uchar ** rev, t_uchar * scratch_dir, t_uchar * default_archive, t_uchar * spec, t_uchar * cache_dir)
{
  t_uchar * answer = 0;

  if (arch_valid_package_name (spec, arch_maybe_archive, arch_req_package, 1))
    {
      t_uchar * archive = 0;
      t_uchar * revision = 0;
      t_uchar * maybe_revision = 0;
      t_uchar * fqrn = 0;
      struct arch_archive *arch_struct = 0;

      archive = arch_parse_package_name (arch_ret_archive, default_archive, spec);
      maybe_revision = arch_parse_package_name (arch_ret_non_archive,
                                                default_archive,
                                                spec);
      
      arch_struct = arch_archive_connect (archive, 0);

      /* Here, we check to see if a revision is specified. If so, then
       * we use that. If not, then lets hunt for the lastest one, because
       * we may have been givine just a package or a version
       */
      if (arch_valid_package_name (maybe_revision,
                                   arch_no_archive,
                                   arch_req_patch_level,
                                   0))
        {
          fqrn = str_save (0, maybe_revision);
        }
      else
        {
          fqrn = arch_archive_latest_revision(arch_struct, maybe_revision, 1);
        }

      revision = arch_parse_package_name(arch_ret_non_archive,
                                         default_archive,
                                         fqrn);

      safe_printfmt (1, "* finding or making %s\n", revision);
      answer = arch_find_or_make_tmp_local_copy (1, scratch_dir, 0, cache_dir, arch_struct, archive, revision);
      arch_archive_close (arch_struct);

      if (arch)
        *arch = archive;
      else
        lim_free (0, archive);

      if (rev)
        *rev = revision;
      else
        lim_free (0, revision);
      lim_free (0, maybe_revision);
      lim_free (0, fqrn);
    }
  else if (arch_valid_patch_level_name (spec))
    {
      t_uchar * archive = 0;
      t_uchar * revision = 0;
      t_uchar * fqvsn = 0;
      t_uchar * tree_version = 0;
      t_uchar * tree_root = 0;
      
      tree_root = arch_tree_root (0, ".", 0);

      if (!tree_root)
        {
          safe_printfmt (2, "tla delta: not in a project tree\n  dir: %s\n", directory_as_cwd ("."));
          exit (2);
        }

      fqvsn = arch_tree_version (tree_root);
      if (!fqvsn)
        {
          safe_printfmt (2, "tla delta: no tree-version set\n  tree: %s\n", tree_root);
          exit (2);
        }
      
      archive = arch_parse_package_name (arch_ret_archive, 0, fqvsn);
      tree_version = arch_parse_package_name (arch_ret_non_archive, 0, fqvsn);
      revision = str_alloc_cat_many (0, tree_version, "--", spec, str_end);

      safe_printfmt (1, "* finding or making %s\n", spec);
      safe_flush (1);

      answer = arch_find_or_make_tmp_local_copy (1, scratch_dir, 0, cache_dir, 0, archive, revision);

      if (arch)
        *arch = archive;
      else
        lim_free (0, archive);

      if (rev)
        *rev = revision;
      else
        lim_free (0, revision);

      lim_free (0, fqvsn);
      lim_free (0, tree_version);
      lim_free (0, tree_root);
    }
  else
    {
      arch_check_directory (spec, 0);
      answer = directory_as_cwd (spec);
    }

  return answer;
}

/* tag: Aaron Bentley Tue Dec 23 10:46:00 2003 (cmdutils.c)
 */

Generated by  Doxygen 1.6.0   Back to index