/* -*-Mode: C++;-*-
* PRCS - The Project Revision Control System
* Copyright (C) 1997 Josh MacDonald
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: quick.cc 1.7.1.2.2.8.1.1 Sun, 03 Feb 2002 13:39:38 -0800 jmacd $
*/
#include "prcs.h"
#include "projdesc.h"
#include "fileent.h"
#include "sexp.h"
#include "quick.h"
#include "system.h"
#include "misc.h"
#define prj_lex_val prjtext
#define prj_lex_len prjleng
EXTERN int prjleng;
EXTERN const char* prjtext;
EXTERN int prj_lex_this_index;
EXTERN int prj_lex_cur_index;
EXTERN int prj_lineno;
QuickElim::QuickElim() :quick_table(new QuickElimTable) { }
QuickElim::~QuickElim() { delete quick_table; }
NprQuickElimPtrError read_quick_elim(const char* filename)
{
QuickElim* quick_elim = new QuickElim;
Return_if_fail(quick_elim->init_from_file(filename));
return quick_elim;
}
static long string_to_posint(const char* string)
{
char c;
int val = 0;
while((c = *string++) != 0) {
if(c < '0' || c > '9')
return -1;
val *= 10;
val += (c - '0');
}
return val;
}
bool QuickElim::unchanged(const FileEntry* fe) const
{
QuickElimEntry **lookup, *qe;
if((lookup = quick_table->lookup(fe->working_path() +
cmd_root_project_path_len)) != NULL) {
qe = *lookup;
if(qe->length != fe->stat_length())
return false;
if(qe->mtime != fe->stat_mtime())
return false;
if(strcmp(qe->desc_name, fe->descriptor_name()) != 0)
return false;
if(strcmp(qe->version_num, fe->descriptor_version_number()) != 0)
return false;
return true;
}
return false;
}
void QuickElim::update(const FileEntry* fe)
{
QuickElimEntry **lookup, *qe;
if(option_report_actions)
return;
if((lookup = quick_table->lookup(fe->working_path() +
cmd_root_project_path_len)) != NULL) {
qe = *lookup;
} else {
qe = new QuickElimEntry;
qe->name.assign (fe->working_path());
quick_table->insert (qe->name + cmd_root_project_path_len, qe);
}
qe->length = fe->stat_length();
qe->mtime = fe->stat_mtime();
qe->desc_name.assign(fe->descriptor_name());
qe->version_num.assign(fe->descriptor_version_number());
}
PrVoidError QuickElim::update_file(const char* filename) const
{
ofstream os;
if(option_report_actions)
return NoError;
os.open(filename);
os << ";; This file is automatically generated, editing may cause PRCS to do\n";
os << ";; REALLY bad things.\n";
os << "(Created-By-Prcs-Version " << prcs_version_number[0] << " "
<< prcs_version_number[1] << " " << prcs_version_number[2] << ")\n";
foreach (qe_ptr, quick_table, QuickElimTable::HashIterator) {
QuickElimEntry *qe = (*qe_ptr).y();
os << "(";
print_protected (qe->name, os);
os << " " << qe->length << " " << qe->mtime << " ";
print_protected (qe->desc_name, os);
os << " ";
print_protected (qe->version_num, os);
os << ")\n";
}
os.close();
if(os.fail())
pthrow prcserror << "Failed writing auxiliary file "
<< squote(filename) << ", ignoring" << dotendl;
return NoError;
}
static NprVoidError read_qe_lists(QuickElimTable *table)
{
PrjTokenType tok = (PrjTokenType)prjlex();
while (true) {
if ( tok != PrjOpen)
return NonFatalError;
if ( (PrjTokenType)prjlex() != PrjName)
return NonFatalError;
QuickElimEntry* qe = new QuickElimEntry;
correct_path(prj_lex_val, &qe->name);
if (table->isdefined(qe->name)) {
delete qe;
return NonFatalError;
}
if ( (PrjTokenType)prjlex() != PrjName)
return NonFatalError;
qe->length = string_to_posint(prj_lex_val);
if ( (PrjTokenType)prjlex() != PrjName)
return NonFatalError;
qe->mtime = string_to_posint(prj_lex_val);
if ( (PrjTokenType)prjlex() != PrjName)
return NonFatalError;
correct_path(prj_lex_val, &qe->desc_name);
if ( (PrjTokenType)prjlex() != PrjName)
return NonFatalError;
correct_path(prj_lex_val, &qe->version_num);
if ( (PrjTokenType)prjlex() != PrjClose)
return NonFatalError;
tok = (PrjTokenType)prjlex();
table->insert(qe->name, qe);
if (tok == PrjEof)
return NoError;
}
}
NprVoidError QuickElim::init_from_file(const char* file)
{
If_fail(prj_input << Err_fopen(file, "r")) {
if(errno != ENOENT)
prcswarning << "Error opening auxiliary file " << squote(file) << dotendl;
return NonFatalError;
}
if ( (PrjTokenType)prjlex() != PrjOpen ||
(PrjTokenType)prjlex() != PrjName ||
strcmp ("Created-By-Prcs-Version", prj_lex_val) != 0 ||
(PrjTokenType)prjlex() != PrjName ||
(PrjTokenType)prjlex() != PrjName ||
(PrjTokenType)prjlex() != PrjName ||
(PrjTokenType)prjlex() != PrjClose)
goto error;
If_fail (read_qe_lists(quick_table))
goto error;
prj_input = NULL;
return NoError;
error:
prj_input = NULL;
prcswarning << "Error parsing auxiliary file " << squote(file) << ", removing" << dotendl;
If_fail(Err_unlink(file))
prcswarning << "Unlink failed on auxiliary file " << squote(file) << perror;
return NoError;
}
syntax highlighted by Code2HTML, v. 0.9.1