Logo Search packages:      
Sourcecode: fhist version File versions

prune.c

/*
 *    fhist - file history and comparison tools
 *    Copyright (C) 1991-1994, 1998, 2000, 2002 Peter Miller;
 *    All rights reserved.
 *
 *    Derived from a work
 *    Copyright (C) 1990 David I. Bell.
 *
 *    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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 *
 * MANIFEST: functions to prune away old edits from the edit history file.
 */

#include <ac/stdio.h>
#include <ac/string.h>

#include <breaks.h>
#include <compare.h>
#include <error_intl.h>
#include <fcheck.h>
#include <fhist.h>
#include <fileio.h>
#include <prune.h>
#include <str.h>
#include <subroutine.h>


/*
 * Prune old edits from the history file to save on disk space.
 * This removes all edits up until the specified edit number.
 *
 * The history (.e) file is binary, because we need to seek in it.
 * The source (.s) file is text, because we don't need to seek in it.
 * The input files are text, by definition.
 * The output files are text, by definition.
 */

void
prunehistory(char *editname)
{
    FILE            *fp;            /* input history file */
    FILE            *ofp;           /* output history file */
    POS             *pp;            /* current entry in position table */
    long            lastprunededit; /* last edit number to be pruned */
    long            firstkeepedit;  /* first edit number to keep */
    long            prunecount;           /* number of edits being pruned */
    long            copypos;        /* starting position to copy from */
    long            newtablepos;    /* position of new position table */
    long            edit;           /* current edit number */
    long            shift;          /* amount to shift data up by */
    char            tempname[1024]; /* temporary name of new edit file */

    strcpy(tempname, sc.basename);
    strcat(tempname, EXT_NEW);
    fp = openhistoryfile(OHF_READ);
    firstkeepedit = findeditnumber(fp, editname);
    lastprunededit = firstkeepedit - 1;
    prunecount = firstkeepedit - sc.firstedit;
    if (prunecount <= 0)
    {
      fclose_and_check(fp, sc.historyname);
      if (fc.verbosity)
      {
          sub_context_ty  *scp;

          scp = sub_context_new();
          sub_var_set_charstar(scp, "Module", sc.modulename);
          error_intl(scp, i18n("no edits pruned from module \"$module\""));
          sub_context_delete(scp);
      }
      return;
    }
    if (!sc.forceupdateflag)
    {
      sub_context_ty    *scp;
      string_ty   *s;

      scp = sub_context_new();
      sub_var_set_charstar(scp, "Module", sc.modulename);
      sub_var_set_long(scp, "Number1", sc.firstedit);
      sub_var_set_long(scp, "Number2", sc.lastedit);
      s =
          subst_intl
          (
                  scp,
            i18n
            (
                "the edit history for module \"$module\" currently has "
                "edits $number1 to $number2."
            )
          );
      printf("%s\n", s->str_text);
      str_free(s);

      sub_var_set_long(scp, "Number1", sc.firstedit);
      if (sc.firstedit == lastprunededit)
      {
          s =
                  subst_intl
                  (
                scp,
                i18n("do you wish to irretrievably discard edit $number1?")
                  );
      }
      else
      {
          sub_var_set_long(scp, "Number2", sc.lastedit);
          s =
                  subst_intl
                  (
                scp,
         i18n("do you wish to irretrievably discard edit $number1 to $number2?")
            );
      }
      sub_context_delete(scp);
      printf("%s ", s->str_text);
      str_free(s);

      if (queryuser())
          return;
    }
    pp = readpostable(fp);
    pp++;               /* ignore unused entry */

    /*
     * This will be the new history file,
     * so create it binary.
     */
    ofp = fopen_and_check(tempname, "w+b");
    fprintf(ofp, HEADERFORMAT, T_HEADER, 0L, 0L, 0L, 0L);
    copypos = pp[sc.lastedit - firstkeepedit].p_pos;
    seekf(fp, copypos, sc.historyname);
    copyfx(fp, ofp, sc.tablepos - copypos, sc.historyname, tempname);
    fclose_and_check(fp, sc.historyname);
    newtablepos = ftell(ofp);
    shift = sc.tablepos - newtablepos;
    for (edit = sc.lastedit; edit >= firstkeepedit; edit--, pp++)
    {
      fprintf(ofp, (pp->p_names ? "%c %ld %ld %s\n" : "%c %ld %ld\n"),
          T_POSITION, edit, pp->p_pos - shift, pp->p_names);
    }
    fprintf(ofp, "%c %ld\n", T_EOF, ftell(ofp));
    seekf(ofp, 0L, tempname);
    fprintf(ofp, HEADERFORMAT, T_HEADER, firstkeepedit, sc.lastedit,
      0L, newtablepos);
    fflush_and_check(ofp, tempname);
    fclose_and_check(ofp, tempname);
    breaksoff();
    if (renamefiles(EXT_HISTORY))
    {
      sub_context_ty    *scp;

      scp = sub_context_new();
      sub_errno_set(scp);
      sub_var_set_charstar(scp, "File_Name", sc.historyname);
      fatal_intl
      (
          scp,
          i18n("rename failed for edit history file \"$filename\": $errno")
      );
    }
    if (fc.verbosity)
    {
      sub_context_ty    *scp;

      scp = sub_context_new();
      sub_var_set_charstar(scp, "Module", sc.modulename);
      sub_var_set_long(scp, "Number", prunecount);
      error_intl(scp, i18n("pruned $number edits from module \"$module\""));
      sub_context_delete(scp);
    }
    breakson();
}

Generated by  Doxygen 1.6.0   Back to index