/*
Numdiff - compare putatively similar files,
ignoring small numeric differences
Copyright (C) 2005-2007 Ivano Primi <ivprimi@libero.it>
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"numdiff.h"
#ifdef _DMALLOC_
#include <dmalloc.h> /* Useful only for the debugging */
#endif
int open_files (const char* file1, const char* file2, FILE** fpp1, FILE** fpp2)
{
/* Open file1 and file2 */
if ( strcmp (file1, file2) == 0 )
{
fputs (_("\n*** Cannot compare a file with itself\n\n"), stderr);
return -1;
}
if ( strcmp (file1, "-") == 0 )
*fpp1 = stdin;
else
{
if ( !(*fpp1 = fopen (file1, "r")) )
{
fprintf (stderr, _("\n*** Cannot open file \"%s\"\n"), file1);
return -1;
}
}
if ( strcmp (file2, "-") == 0 )
*fpp2 = stdin;
else
{
if ( !(*fpp2 = fopen (file2, "r")) )
{
fprintf (stderr, _("\n*** Cannot open file \"%s\"\n"), file2);
return -1;
}
}
return 0;
}
char* read_line (FILE* pf, int* errcode)
{
char buffer[BUFF_SIZE];
char *ptr, *line = NULL;
size_t lline = 0;
while ((ptr = fgets (buffer, BUFF_SIZE,pf)))
{
lline += strlen (buffer);
if (!line)
ptr = (char*) calloc (lline + 1, sizeof(char));
else
ptr = (char*) realloc ((void*)line, (lline + 1) * sizeof(char));
if (!ptr)
{
if ((line))
free ((void*)line);
*errcode = OUT_OF_MEMORY;
return NULL;
}
else
{
line = ptr;
strcat (line, buffer);
}
if (lline > 0 && line[lline-1] == '\n')
break;
}
if (!ptr)
{
if ( (ferror(pf)) )
*errcode = READING_ERROR;
else if (lline > 0)
*errcode = LINE_INTERR;
else
*errcode = EOF_REACHED;
}
else
*errcode = OK;
return line;
}
static
void print_head (const char* str, size_t length)
{
const char* t;
for (t = str; t - str < length; putchar(*t), t++);
}
static
void print_ws (unsigned n)
{
while ((n--))
putchar (' ');
}
static
void writeln (const char* line, int addemptyline)
{
const char *ptr;
for (ptr = line; *ptr != '\0'; putchar(*ptr), ptr++);
if (ptr == line || *(ptr-1) != '\n')
puts (EOF_INDICATOR);
if ((addemptyline))
putchar('\n');
}
/*
This function assumes that at least one between line1 and line2 is
not empty (!NULL).
*/
void print_lines (const char* line1, const char* line2,
unsigned long lineno, int delimiter_only)
{
puts (LINE_SEP);
if (!delimiter_only)
{
if (!line1)
{
printf ("##%-7lu <==\n ==> ", lineno);
writeln (line2, 1);
}
else if (!line2)
{
printf ("##%-7lu <== ", lineno);
writeln (line1, 0);
printf (" ==>\n\n");
}
else
{
printf ("##%-7lu <== ", lineno);
writeln (line1, 0);
printf (" ==> ");
writeln (line2, 1);
}
}
}
/*
This function assumes that at least one between field1 and field2 is
not empty.
*/
void print_fields (const char* field1, const char* field2,
size_t l1, size_t l2,
unsigned long lineno, unsigned long fieldno)
{
fieldno++; /* The field number must start from 1, not from 0 */
if (*field1 == '\0')
{
printf ("##%-7lu #>%-3lu <==\n", lineno, fieldno);
print_ws (6+10);
/* 6 = size("## #: "), 10 = 7+3 */
fputs ("==> ", stdout);
writeln (field2, 0);
}
else if (*field2 == '\0')
{
printf ("##%-7lu #>%-3lu <== ", lineno, fieldno);
writeln (field1, 0);
print_ws (6+10);
/* 6 = size("## #: "), 10 = 7+3 */
puts ("==>");
}
else
{
printf ("##%-7lu #:%-3lu ", lineno, fieldno);
fputs ("<== ", stdout);
print_head (field1, l1);
putchar ('\n');
print_ws (6+10);
/* 6 = size("## #: "), 10 = 7+3 */
fputs ("==> ", stdout);
print_head (field2, l2);
putchar ('\n');
}
}
void print_errors (Real abserr, Real relerr)
{
fputs (_("@ Absolute error = "), stdout);
printno (abserr, DEF_LIM);
fputs (_(", Relative error = "), stdout);
printno (relerr, DEF_LIM);
putchar ('\n');
}
void print_separator (void)
{
putchar ('@');
print_ws (53);
puts ("@@");
}
syntax highlighted by Code2HTML, v. 0.9.1