// A. L. Delcher
//
// File: delcher.cc
//
// Last Modified: 23 October 2003
//
// Common generic routines.
#include "delcher.hh"
const int COMMATIZE_BUFF_LEN = 50;
// Length of buffer for creating string with commas
char Clean_Exit_Msg_Line [MAX_ERROR_MSG_LEN];
// String to write error messages to before exiting
int Global_Debug_Flag = 0;
// Used to set different debugging levels
int Verbose = 0;
// Flag to determine level of debugging output
const char * Commatize
(long int n)
// Return a string representing the value of n with commas
// every three digits.
{
static char buff [COMMATIZE_BUFF_LEN];
bool is_negative = false;
int i, ct;
buff [COMMATIZE_BUFF_LEN - 1] = '\0';
if (n == 0)
{
buff [COMMATIZE_BUFF_LEN - 2] = '0';
return buff + 48;
}
i = COMMATIZE_BUFF_LEN - 2;
if (n < 0)
{
is_negative = true;
n *= -1;
}
for (ct = 0; n > 0; ct ++)
{
if (ct == 3)
{
buff [i --] = ',';
ct = 0;
}
buff [i --] = char ('0' + n % 10);
n /= 10;
}
if (is_negative)
buff [i --] = '-';
return buff + i + 1;
}
void Clean_Exit
(const char * msg, const char * src_fname, size_t line_num)
// Write string msg to stderr and also a line indicating
// the error happen in source file src_fname at line line_num
// if they are not NULL and 0 respectively.
// Then exit with an error condition.
{
fprintf (stderr, "%s\n", msg);
if (src_fname != NULL)
fprintf (stderr, " in file %s", src_fname);
if (line_num != 0)
fprintf (stderr, " at line %lu", (long unsigned) (line_num));
fprintf (stderr, " errno = %d\n", errno);
exit (EXIT_FAILURE);
}
FILE * File_Open
(const string & fname, const string & mode, const char * src_fname,
size_t line_num)
// Open fname in mode and return a pointer to its control
// block. If fail, print a message and exit, assuming the call came from
// source file src_fname at line line_num .
{
FILE * fp;
fp = fopen (fname . c_str (), mode . c_str ());
if (fp == NULL)
{
sprintf (Clean_Exit_Msg_Line,
"ERROR: Could not open file %s", fname . c_str ());
Clean_Exit (Clean_Exit_Msg_Line, src_fname, line_num);
}
return fp;
}
char First_Non_Blank
(const char * s)
// Return the first non-white-space character in s .
// If none, return ' ' .
{
const char * p;
for (p = s; * p != '\0'; p ++)
if (! isspace (* p))
return * p;
return ' ';
}
void Make_Lower_Case
(char * s)
// Convert all letters in s to lower-case.
{
char * p;
for (p = s; * p != '\0'; p ++)
* p = tolower (* p);
}
void Make_Upper_Case
(char * s)
// Convert all letters in s to upper-case.
{
char * p;
for (p = s; * p != '\0'; p ++)
* p = toupper (* p);
}
int Int_Power
(int a, int b)
// Return a raised to the power b . Both are assumed
// to be non-negative;
{
int result = 1;
int p = a;
while (b > 0)
{
if (b & 1)
result *= p;
p = p * p;
b >>= 1;
}
return result;
}
const char * Num_Or_Max
(int n, int mx)
// Return a string representation of n or else "max"
// if n >= mx .
{
static char buff [20];
if (n >= mx)
return "max";
sprintf (buff, "%d", n);
return buff;
}
double Percent
(double a, double b)
// Return a / b as a percentage. Return 0.0 if b = 0.0 .
{
if (b == 0.0)
return 0.0;
return 100.0 * (a / b);
}
const char * Printable
(bool b)
// Return a string representing the value of b .
{
if (b)
return "true";
else
return "false";
}
const char * Printable
(char * s)
// Return "none" if s is NULL ; otherwise, return s itself.
{
if (s == NULL)
return "none";
else
return s;
}
double Pseudo_Normal
(void)
// Return a simple approximation to a standard normally distributed value,
// i.e., mean = 0.0 and s.d. = 1.0
{
double sum = 0.0;
int i;
for (i = 0; i < 12; i ++)
sum += drand48 ();
return sum - 6.0;
}
double Ratio
(double a, double b)
// Return a / b , or 0.0 if b = 0.0 .
{
if (b == 0.0)
return 0.0;
return a / b;
}
void Reverse_String
(char * s)
// Reverse the order of characters in string s .
{
int i, j, n;
n = strlen (s);
for (i = 0, j = n - 1; i < j; i ++, j --)
{
char ch;
ch = s [i];
s [i] = s [j];
s [j] = ch;
}
return;
}
void Reverse_String
(string & s)
// Reverse the order of characters in string s .
{
int i, j, n;
n = s . length ();
for (i = 0, j = n - 1; i < j; i ++, j --)
{
char ch;
ch = s [i];
s [i] = s [j];
s [j] = ch;
}
return;
}
void * Safe_calloc
(size_t n, size_t len, const char * src_fname, size_t line_num)
// Allocate and return a pointer to enough memory to hold an
// array with n entries of len bytes each. All memory is
// cleared to 0. If fail, print a message and exit, assuming the
// call came from source file src_fname at line line_num .
{
void * p;
p = calloc (n, len);
if (p == NULL)
{
sprintf (Clean_Exit_Msg_Line,
"ERROR: calloc failed %lu x %lu",
(long unsigned) (n), (long unsigned) (len));
Clean_Exit (Clean_Exit_Msg_Line, src_fname, line_num);
}
return p;
}
void * Safe_malloc
(size_t len, const char * src_fname, size_t line_num)
// Allocate and return a pointer to len bytes of memory.
// If fail, print a message and exit, assuming the call came from
// source file src_fname at line line_num .
{
void * p;
p = malloc (len);
if (p == NULL)
{
sprintf (Clean_Exit_Msg_Line,
"ERROR: malloc failed %lu bytes",
(long unsigned) (len));
Clean_Exit (Clean_Exit_Msg_Line, src_fname, line_num);
}
return p;
}
void * Safe_realloc
(void * q, size_t len, const char * src_fname, size_t line_num)
// Reallocate memory for q to len bytes and return a
// pointer to the new memory. If fail, print a message and exit,
// assuming the call came from source file src_fname at line line_num .
{
void * p;
p = realloc (q, len);
if (p == NULL)
{
sprintf (Clean_Exit_Msg_Line,
"ERROR: realloc failed %lu bytes",
(long unsigned) (len));
Clean_Exit (Clean_Exit_Msg_Line, src_fname, line_num);
}
return p;
}
char * Strip_Trailing
(char * s, char ch)
// Remove all occurrences of ch at the end of s by writing
// '\0's over them. Return s so this can be used as a function.
{
int i, len;
len = strlen (s);
for (i = len - 1; i >= 0 && s [i] == ch; i --)
s [i] = '\0';
return s;
}