Unix Programming - texting c and c++

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > February 2005 > texting c and c++





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author texting c and c++
Billy Patton

2005-02-23, 6:01 pm

I have had a scheme that I have used for 10+ years to test c code.
I'm now moving into c++ and would like to see if I can upgrade it.

I have the following in the top of my test file:

int nr = 0;
int nf = 0;
int dr = 0; /* dont run this */
int ir = 0;
char t_buf[256];
FILE *t_fp = NULL;
int ncells = 0;

#define exp2fail(x) if(x) { \
nf++; \
fprintf(stderr," not ok %d : file %s , line#
%d\n",nr,__FILE__,__LINE__); \
exit(1); \
} \
else { \
fprintf(stdout," ok %d : file %s , line#
%d\n",nr,__FILE__,__LINE__); \
} \
nr++; ir++;
#define exp2pass(x) if(x) { \
fprintf(stdout," ok %d : file %s , line#
%d\n",nr,__FILE__,__LINE__); \
} \
else { \
nf++; \
fprintf(stderr," not ok %d : file %s , line#
%d\n",nr,__FILE__,__LINE__); \
exit(1); \
} \
nr++; ir++;


Where nf is number_fail
nr is number ran
dr is dont run to stop some test functions
ir number in this function that ran.

Here is an example test function (my skeleton)
void t_void(void)
{
ENTER
ext2fail(0); // boolean that returns a 0
ext2pass(1); // boolean that return a non 0
LEAVE
}


ENTER and LEAVE set some of the variable and print the function name


A real example is :
void t_ExCommand(void)
{
string ex;
vector<string> out;
ENTER
ex = "/bin/ls ./src";
exp2pass(ExCommand(ex,out));
exp2pass(out.size() > 1);
LEAVE
}

int main(int argc,char* argv[])
{
clock_t st, fin;
double dur;

st = clock();
dr = nr = nf = 0;
t_void();
t_ExCommand();
fin = clock();
dur = (double)(fin - st) / CLOCKS_PER_SEC;
fprintf(stderr,"\n\n");
fprintf(stderr,"Number tests ran : %d\n",nr);
fprintf(stderr,"Number tests fail : %d\n",nf);
fprintf(stderr,"In cpu seconds : %e\n\n",dur);
return 0;
}


What I'm wondering about would be a different suntax that mybe would not
require so many parens.

Ex: #1

EXP2PASS ExCommand(ex,out);

I know this is picking for small details and I know I could do

EXP2PASS ExCommand(ex,out) ET

where
#define EX2PASS ...(
#define ET );

My test source alread has over 10k lines. I think that it would make it much
easier to read if it was like exampel #1

Anyone got any idesa how to accomplish this in c or c++ definitions of any
kind?



___ _ ____ ___ __ __
/ _ )(_) / /_ __ / _ \___ _/ /_/ /____ ___
/ _ / / / / // / / ___/ _ `/ __/ __/ _ \/ _ \
/____/_/_/_/\_, / /_/ \_,_/\__/\__/\___/_//_/
/___/
Texas Instruments ASIC Circuit Design Methodology Group
Dallas, Texas, 214-480-4455, b-patton@ti.com
Maurizio Loreti

2005-02-24, 2:58 am

Billy Patton <bpatton@ti.com> writes:

> I have had a scheme that I have used for 10+ years to test c code.
> I'm now moving into c++ and would like to see if I can upgrade it.


I may offer what _I_ use... Sorry for the LONG answer.

-----------------------Begin included file: generr.hh-----------------------
// Author: Maurizio Loreti, aka MLO or (HAM) I3NOO
// Work: university of Padova - Department of Physics
// Via F. Marzolo, 8 - 35131 PADOVA - Italy
// Phone: +39 (049) 827-7216 FAX: +39 (049) 827-7102
// EMail: loreti@pd.infn.it
// WWW: http://www.pd.infn.it/~loreti/mlo.html
//
// -------------------------------------------------------------------
// General error printout routines
// -------------------------------------------------------------------
// $Id: generr.hh,v 1.3 2004/10/27 17:41:32 loreti Exp $
// -------------------------------------------------------------------

#ifndef GENERR_HH_
#define GENERR_HH_

#include <iostream>
#include <stdexcept>
#include <string>

namespace generr {
template <typename T> void valnam(
const char * name,
const T & value,
std::ostream & o = std::cerr
) {
// Prints on the output stream "o" the name of a variable and its
// value. The variable must have a valid "operator <<" defined.

o << " -> " << name << " = " << value << std::endl;
}

// Declares a procedure for the printout of generic error. The
// arguments are: file name; line number; severity level; error
// message; and the output stream.

void errmes(const char *, unsigned int, const char *,
const char *, std::ostream & = std::cerr);
}

// Preprocessor macros to ease the use of the above procedures.

#define VALNAM(x) generr::valnam(#x, x)
#define ERRMES(m) generr::errmes(__FILE__, __LINE__, "Error", m)
#define DBGMES(m) generr::errmes(__FILE__, __LINE__, "Debug", m)

// A class derived from std::exception, that saves for the catcher
// informations about date, time, file name and line that may be
// retrieved and, if needed, printed.

class genex : public std::runtime_error {
private:
char _date[12];
char _time[9];
std::string _file;
unsigned int _line;

void datim();

public:
genex(const char * w, const char * f, unsigned int l)
: std::runtime_error(w), _file(f), _line(l) { datim(); }
~genex() throw() {}

const char * getDate() const { return _date; }
const char * getTime() const { return _time; }
const std::string & getFile() const { return _file; }
const unsigned int getLine() const { return _line; }
};

// Preprocessor macros to ease the use of the above class

#define GENEX(w) throw genex(w, __FILE__, __LINE__)

#endif // GENERR_HH_
-----------------------End included file: generr.hh-----------------------
-----------------------Begin included file: generr.cxx----------------------
// Author: Maurizio Loreti, aka MLO or (HAM) I3NOO
// Work: university of Padova - Department of Physics
// Via F. Marzolo, 8 - 35131 PADOVA - Italy
// Phone: +39 (049) 827-7216 FAX: +39 (049) 827-7102
// EMail: loreti@pd.infn.it
// WWW: http://www.pd.infn.it/~loreti/mlo.html
//
// -------------------------------------------------------------------
// Implementation of the procedure declared in "generr.hh".
// According to the preprocessor symbol "GENERR_DATETIME", the message
// contains:
// GENERR_DATETIME = 1 : current time
// GENERR_DATETIME = 2 : current date and time
// GENERR_DATETIME = none of the above values : nothing
// -------------------------------------------------------------------
// $Id: generr.cxx,v 1.3 2004/10/27 17:41:32 loreti Exp $
// -------------------------------------------------------------------

#include <ctime>
#include "generr.hh"

using namespace std;

namespace {
const char t_fmt[] = "%H:%M:%S";
const char d_fmt[] = "%d-%b-%Y";
const char a_fmt[] = "%d-%b-%Y %H:%M:%S";
}

namespace generr {
void errmes(
const char * fileName,
unsigned int lineNumber,
const char * severity,
const char * message,
ostream & o // Defaults to cerr
) {

#if GENERR_DATETIME == 1 || GENERR_DATETIME == 2
time_t now = time(0);
struct tm * ptm = localtime(&now);
#if GENERR_DATETIME == 1
char fmtNow[] = "HH:MM:SS";
strftime(fmtNow, sizeof(fmtNow), t_fmt, ptm);
#else // == 2
char fmtNow[] = "DD-MMM-YYYY HH:MM:SS";
strftime(fmtNow, sizeof(fmtNow), a_fmt, ptm);
#endif
o << "* " << fmtNow << ' ';
#endif

o << "* " << severity << " in " << fileName << " at "
<< lineNumber << " (" << message << ")" << endl;
}
}

void genex::datim() {
time_t now = time(0);
struct tm * ptm = localtime(&now);
strftime(_date, sizeof(_date), d_fmt, ptm);
strftime(_time, sizeof(_time), t_fmt, ptm);
}
-----------------------End included file: generr.cxx----------------------
-----------------------Begin included file: main.cxx------------------------
#include <fstream>
#include <string>
#include "generr.hh"

using namespace std;

class strange {
private:
string name;
int value;
public:
strange(const char * n, int v) : name(n), value(v) {}
~strange() {}
void out(ostream & o) const {
o << '(' << name << ", " << value << ')'; }
};

ostream & operator << (
ostream & o,
const strange & s
) {
s.out(o);
return o;
}

void procedure() {
GENEX("Self-destructing");
}

void line(
const char * target
) {
cerr << "\n------------------------------ "
<< target << " ------------------------------\n\n";
}

int main() {
string fileName = "abc.dat";
const char myName[] = "Maurizio Loreti";
int i = 42;
double pig = 3.14;
strange ss("foo", 666);

line("Trying ERRMES");

ifstream ifs(fileName.c_str());
if (!ifs) {
ERRMES("couldn't open file");
VALNAM(fileName);
VALNAM(myName);
VALNAM(i);
VALNAM(pig);
VALNAM(ss);
}

line("Trying GENEX");

try {
procedure();
} catch (const genex & g) {
cerr << "\n\t*** Howdy! I am the General Exception Catcher! "
<< "***\n\n\tI am afraid that, in the line " << g.getLine()
<< " of the file \"" << g.getFile()
<< "\",\n\tsome shit happened in the day of the Lord "
<< g.getDate() << ";\n\tand exactly at " << g.getTime()
<< " (local time, of course).\n\n\tThe message I got is:\t\t\""
<< g.what() << "\"\n\n";
}

line("Exiting...");
}
-----------------------End included file: main.cxx------------------------
-----------------------Begin included file: Makefile------------------------
# Author: Maurizio Loreti, aka MLO or (HAM) I3NOO
# Work: university of Padova - Department of Physics
# Via F. Marzolo, 8 - 35131 PADOVA - Italy
# Phone: +39 (049) 827-7216 FAX: +39 (049) 827-7102
# EMail: loreti@pd.infn.it
# WWW: http://www.pd.infn.it/~loreti/mlo.html
#
########################################
##############################
# Makefile for the "generr" example program
########################################
##############################
# $Id: Makefile,v 1.1 2003/10/27 06:55:39 loreti Exp $
########################################
##############################

CXX = g++
CXXFLAGS = -std=c++98 -pedantic -W -Wall -O2

# CXX = KCC
# CXXFLAGS = -O2

CPPFLAGS = -DGENERR_DATETIME=2
LDFLAGS =


..PHONY: all clean


all: main


main: main.cxx generr.cxx generr.hh
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ main.cxx generr.cxx


clean:
rm -f *~ *.o core main
rm -rf ti_files
-----------------------End included file: Makefile------------------------

--
Maurizio Loreti http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy ROT13: ybergv@cq.vasa.vg
Gianni Mariani

2005-02-24, 7:52 am

Billy Patton wrote:
> I have had a scheme that I have used for 10+ years to test c code.
> I'm now moving into c++ and would like to see if I can upgrade it.


There are a number of unit test libraries. 2 come to mind

1) Austria C++ has a unit test framework. (shameless plug)
2) CppUnit
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com