//
// cook - file construction tool
// Copyright (C) 1995, 1999, 2003-2006, 2008 Peter Miller
//
// 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 3 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, see
// .
//
#include
#include
#include
#include
#include
#include
struct ident_ty
{
FINGERPRINT_BASE_CLASS
fingerprint_ty *combined;
fingerprint_ty *crc32;
};
static void
ident_constructor(fingerprint_ty *p)
{
ident_ty *f;
f = (ident_ty *)p;
f->combined = fingerprint_new(&fp_combined);
f->crc32 = fingerprint_new(&fp_crc32);
}
static void
ident_destructor(fingerprint_ty *p)
{
ident_ty *f;
f = (ident_ty *)p;
fingerprint_delete(f->combined);
fingerprint_delete(f->crc32);
}
static void
ident_addn(fingerprint_ty *p, unsigned char *s, size_t n)
{
ident_ty *f;
f = (ident_ty *)p;
fingerprint_addn(f->combined, s, n);
}
static int
ident_hash(fingerprint_ty *p, unsigned char *h)
{
ident_ty *f;
size_t nbytes;
unsigned char t[1024];
f = (ident_ty *)p;
nbytes = fingerprint_hash(f->combined, t);
fingerprint_addn(f->crc32, t, nbytes);
nbytes = fingerprint_hash(f->crc32, h);
return(nbytes);
}
static void
ident_sum(fingerprint_ty *p, char *obuf, size_t obuf_len)
{
unsigned char h[1024];
unsigned long x;
int nbytes;
static char digits[] = "0123456789";
char *cp;
nbytes = ident_hash(p, h);
assert(nbytes == 4);
x = h[0] | (h[1] << 8) | (h[2] << 16) | (h[3] << 24);
snprintf(obuf, obuf_len, "%8.8lx", x);
//
// some older stdio implementations don't grok the above format
// string, so hunt down and kill any spaces.
//
for (cp = obuf; *cp; ++cp)
if (*cp == ' ')
*cp = '0';
//
// This forces the first character to be a letter, so
// the result is a valid identifier in most computer
// languages. The strchr makes it not ASCII specific.
//
cp = strchr(digits, *obuf);
if (cp)
*obuf = "ghijklmnop"[cp - digits];
}
fingerprint_methods_ty fp_ident =
{
sizeof(ident_ty),
"identifier",
ident_constructor,
ident_destructor,
ident_addn,
ident_hash,
ident_sum
};