Complete Configuration sync. While testing, I discovered what I think is a race condition: getStr("SIP.SMSC") returned another config key ("GSM.MS.TA.Damping") which I assume is a race condition in the config cache. However, I've been unable to replicate the issue and I think it may resolve itself quickly (as these things are successfully cached)

git-svn-id: http://wush.net/svn/range/software/public/CommonLibs/trunk@5656 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
Kurtis Heimerl 2013-05-31 21:47:42 +00:00
parent e6a48a3690
commit 59515c11f0
31 changed files with 2689 additions and 1510 deletions

View File

@ -29,6 +29,7 @@
#include "BitVector.h"
#include <iostream>
#include <stdio.h>
#include <sstream>
using namespace std;
@ -274,9 +275,6 @@ void BitVector::unmap(const unsigned *map, size_t mapSize, BitVector& dest) cons
ostream& operator<<(ostream& os, const BitVector& hv)
{
for (size_t i=0; i<hv.size(); i++) {
@ -527,6 +525,22 @@ void SoftVector::decode(ViterbiR2O4 &decoder, BitVector& target) const
// (pat) Added 6-22-2012
float SoftVector::getEnergy(float *plow) const
{
const SoftVector &vec = *this;
int len = vec.size();
float avg = 0; float low = 1;
for (int i = 0; i < len; i++) {
float bit = vec[i];
float energy = 2*((bit < 0.5) ? (0.5-bit) : (bit-0.5));
if (energy < low) low = energy;
avg += energy/len;
}
if (plow) { *plow = low; }
return avg;
}
ostream& operator<<(ostream& os, const SoftVector& sv)
{
@ -578,6 +592,14 @@ void BitVector::hex(ostream& os) const
os << std::dec;
}
std::string BitVector::hexstr() const
{
std::ostringstream ss;
hex(ss);
return ss.str();
}
bool BitVector::unhex(const char* src)
{
// Assumes MSB-first packing.

View File

@ -314,6 +314,9 @@ class BitVector : public Vector<char> {
void fillFieldReversed(size_t writeIndex, uint64_t value, unsigned length);
void writeField(size_t& writeIndex, uint64_t value, unsigned length);
void writeFieldReversed(size_t& writeIndex, uint64_t value, unsigned length);
void write0(size_t& writeIndex) { writeField(writeIndex,0,1); }
void write1(size_t& writeIndex) { writeField(writeIndex,1,1); }
//@}
/** Sum of bits. */
@ -333,11 +336,26 @@ class BitVector : public Vector<char> {
/** Make a hexdump string. */
void hex(std::ostream&) const;
std::string hexstr() const;
/** Unpack from a hexdump string.
* @returns true on success, false on error. */
bool unhex(const char*);
void set(BitVector other) // That's right. No ampersand.
{
clear();
mData=other.mData;
mStart=other.mStart;
mEnd=other.mEnd;
other.mData=NULL;
}
void settfb(int i, int j) const
{
mStart[i] = j;
}
};
@ -412,6 +430,11 @@ class SoftVector: public Vector<float> {
/** Decode soft symbols with the GSM rate-1/2 Viterbi decoder. */
void decode(ViterbiR2O4 &decoder, BitVector& target) const;
// (pat) How good is the SoftVector in the sense of the bits being solid?
// Result of 1 is perfect and 0 means all the bits were 0.5
// If plow is non-NULL, also return the lowest energy bit.
float getEnergy(float *low=0) const;
/** Fill with "unknown" values. */
void unknown() { fill(0.5F); }

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*
* Copyright 2009, 2010 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
* Copyright 2011, 2012 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
@ -32,10 +33,14 @@
#include <assert.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <regex.h>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <Threads.h>
@ -44,6 +49,7 @@
/** A class for configuration file errors. */
class ConfigurationTableError {};
extern char gCmdName[]; // Gotta be global, gotta be char*, gotta love it.
/** An exception thrown when a given config key isn't found. */
class ConfigurationTableKeyNotFound : public ConfigurationTableError {
@ -56,7 +62,7 @@ class ConfigurationTableKeyNotFound : public ConfigurationTableError {
ConfigurationTableKeyNotFound(const std::string& wKey)
:mKey(wKey)
{ std::cerr << "cannot find configuration value " << mKey << std::endl; }
{ }
const std::string& key() const { return mKey; }
@ -94,6 +100,8 @@ class ConfigurationRecord {
long number() const { return mNumber; }
bool defined() const { return mDefined; }
float floatNumber() const;
};
@ -161,8 +169,10 @@ class HashString : public std::string {
};
typedef std::map<std::string, ConfigurationRecord> ConfigurationRecordMap;
typedef std::map<HashString, ConfigurationRecord> ConfigurationMap;
class ConfigurationKey;
typedef std::map<std::string, ConfigurationKey> ConfigurationKeyMap;
/**
A class for maintaining a configuration key-value table,
@ -176,20 +186,37 @@ class ConfigurationTable {
sqlite3* mDB; ///< database connection
ConfigurationMap mCache; ///< cache of recently access configuration values
mutable Mutex mLock; ///< control for multithreaded access to the cache
std::vector<std::string> (*mCrossCheck)(const std::string&); ///< cross check callback pointer
public:
ConfigurationKeyMap mSchema;///< definition of configuration default values and validation logic
ConfigurationTable(const char* filename = ":memory:");
ConfigurationTable(const char* filename = ":memory:", const char *wCmdName = 0, ConfigurationKeyMap wSchema = ConfigurationKeyMap());
/** Generate an up-to-date example sql file for new installs. */
std::string getDefaultSQL(const std::string& program, const std::string& version);
/** Generate an up-to-date TeX snippet. */
std::string getTeX(const std::string& program, const std::string& version);
/** Return true if the key is used in the table. */
bool defines(const std::string& key);
/** Return true if this key is identified as static. */
bool isStatic(const std::string& key) const;
/** Return true if the application's schema knows about this key. */
bool keyDefinedInSchema(const std::string& name);
/** Return true if this key is identified as required (!optional). */
bool isRequired(const std::string& key) const;
/** Return true if the provided value validates correctly against the defined schema. */
bool isValidValue(const std::string& name, const std::string& val);
/** Return true if the provided value validates correctly against the defined schema. */
bool isValidValue(const std::string& name, const int val) { std::stringstream ss; ss << val; return isValidValue(name, ss.str()); }
/** Return a map of all similar keys in the defined schema. */
ConfigurationKeyMap getSimilarKeys(const std::string& snippet);
/** Return true if this key is identified as static. */
bool isStatic(const std::string& key);
/**
Get a string parameter from the table.
@ -199,11 +226,10 @@ class ConfigurationTable {
/**
Get a string parameter from the table.
Define the parameter to the default value if not found.
Get a boolean from the table.
Return false if NULL or 0, true otherwise.
*/
std::string getStr(const std::string& key, const char* defaultValue);
bool getBool(const std::string& key);
/**
Get a numeric parameter from the table.
@ -212,10 +238,15 @@ class ConfigurationTable {
long getNum(const std::string& key);
/**
Get a numeric parameter from the table.
Define the parameter to the default value if not found.
Get a vector of strings from the table.
*/
long getNum(const std::string& key, long defaultValue);
std::vector<std::string> getVectorOfStrings(const std::string& key);
/**
Get a float from the table.
Throw ConfigurationTableKeyNotFound if not found.
*/
float getFloat(const std::string& key);
/**
Get a numeric vector from the table.
@ -236,19 +267,28 @@ class ConfigurationTable {
bool set(const std::string& key);
/**
Remove a key from the table.
Will not remove static or required values.
@param key The key of the item to be deleted.
Remove an entry from the table.
Will not alter required values.
@param key The key of the item to be removed.
@return true if anything was actually removed.
*/
bool unset(const std::string& key);
bool remove(const std::string& key);
/** Search the table, dumping to a stream. */
void find(const std::string& pattern, std::ostream&) const;
/** Return all key/value pairs stored in the ConfigurationTable */
ConfigurationRecordMap getAllPairs() const;
/** Define the callback to purge the cache whenever the database changes. */
void setUpdateHook(void(*)(void *,int ,char const *,char const *,sqlite3_int64));
/** Define the callback for cross checking. */
void setCrossCheckHook(std::vector<std::string> (*wCrossCheck)(const std::string&));
/** Execute the application specific value cross checking logic. */
std::vector<std::string> crossCheck(const std::string& key);
/** purege cache if it exceeds a certain age */
void checkCacheAge();
@ -268,6 +308,113 @@ class ConfigurationTable {
};
typedef std::map<HashString, std::string> HashStringMap;
class SimpleKeyValue {
protected:
HashStringMap mMap;
public:
/** Take a C string "A=B" and set map["A"]="B". */
void addItem(const char*);
/** Take a C string "A=B C=D E=F ..." and add all of the pairs to the map. */
void addItems(const char*s);
/** Return a reference to the string at map["key"]. */
const char* get(const char*) const;
};
class ConfigurationKey {
public:
enum VisibilityLevel
{
CUSTOMER,
CUSTOMERSITE,
CUSTOMERTUNE,
CUSTOMERWARN,
DEVELOPER,
FACTORY
};
enum Type
{
BOOLEAN,
CHOICE_OPT,
CHOICE,
CIDR_OPT,
CIDR,
FILEPATH_OPT,
FILEPATH,
IPADDRESS_OPT,
IPADDRESS,
IPANDPORT,
MIPADDRESS_OPT,
MIPADDRESS,
PORT_OPT,
PORT,
REGEX_OPT,
REGEX,
STRING_OPT,
STRING,
VALRANGE
};
private:
std::string mName;
std::string mDefaultValue;
std::string mUnits;
VisibilityLevel mVisibility;
Type mType;
std::string mValidValues;
bool mIsStatic;
std::string mDescription;
public:
ConfigurationKey(const std::string& wName, const std::string& wDefaultValue, const std::string& wUnits, const VisibilityLevel wVisibility, const Type wType, const std::string& wValidValues, bool wIsStatic, const std::string& wDescription):
mName(wName),
mDefaultValue(wDefaultValue),
mUnits(wUnits),
mVisibility(wVisibility),
mType(wType),
mValidValues(wValidValues),
mIsStatic(wIsStatic),
mDescription(wDescription)
{ }
ConfigurationKey()
{ }
const std::string& getName() const { return mName; }
const std::string& getDefaultValue() const { return mDefaultValue; }
void updateDefaultValue(const std::string& newValue) { mDefaultValue = newValue; }
void updateDefaultValue(const int newValue) { std::stringstream ss; ss << newValue; updateDefaultValue(ss.str()); }
const std::string& getUnits() const { return mUnits; }
const VisibilityLevel& getVisibility() const { return mVisibility; }
const Type& getType() const { return mType; }
const std::string& getValidValues() const { return mValidValues; }
bool isStatic() const { return mIsStatic; }
const std::string& getDescription() const { return mDescription; }
static bool isValidIP(const std::string& ip);
static void getMinMaxStepping(const ConfigurationKey &key, std::string &min, std::string &max, std::string &stepping);
template<class T> static bool isInValRange(const ConfigurationKey &key, const std::string& val, const bool isInteger);
static const std::string visibilityLevelToString(const VisibilityLevel& visibility);
static const std::string typeToString(const ConfigurationKey::Type& type);
static void printKey(const ConfigurationKey &key, const std::string& currentValue, std::ostream& os);
static void printDescription(const ConfigurationKey &key, std::ostream& os);
static const std::string getARFCNsString();
};
#endif

View File

@ -28,10 +28,12 @@
#include "Configuration.h"
#include <iostream>
#include <string>
using namespace std;
ConfigurationTable gConfig("exampleconfig.db");
ConfigurationKeyMap getConfigurationKeys();
ConfigurationTable gConfig("exampleconfig.db","test", getConfigurationKeys());
void purgeConfig(void*,int,char const*, char const*, sqlite3_int64)
{
@ -56,14 +58,92 @@ int main(int argc, char *argv[])
cout << "table[" << keys[i] << "]=" << gConfig.getNum(keys[i]) << endl;
}
gConfig.unset("key1");
for (int i=0; i<5; i++) {
cout << "defined table[" << keys[i] << "]=" << gConfig.defines(keys[i]) << endl;
}
gConfig.set("key5","100 200 300 400");
gConfig.set("key5","100 200 300 400 ");
std::vector<unsigned> vect = gConfig.getVector("key5");
cout << "vect length " << vect.size() << ": ";
for (unsigned i=0; i<vect.size(); i++) cout << " " << vect[i];
cout << endl;
std::vector<string> svect = gConfig.getVectorOfStrings("key5");
cout << "vect length " << svect.size() << ": ";
for (unsigned i=0; i<svect.size(); i++) cout << " " << svect[i] << ":";
cout << endl;
cout << "bool " << gConfig.getBool("booltest") << endl;
gConfig.set("booltest",1);
cout << "bool " << gConfig.getBool("booltest") << endl;
gConfig.set("booltest",0);
cout << "bool " << gConfig.getBool("booltest") << endl;
gConfig.getStr("newstring");
gConfig.getNum("numnumber");
SimpleKeyValue pairs;
pairs.addItems(" a=1 b=34 dd=143 ");
cout<< pairs.get("a") << endl;
cout<< pairs.get("b") << endl;
cout<< pairs.get("dd") << endl;
gConfig.set("fkey","123.456");
float fval = gConfig.getFloat("fkey");
cout << "fkey " << fval << endl;
cout << "search fkey:" << endl;
gConfig.find("fkey",cout);
cout << "search fkey:" << endl;
gConfig.find("fkey",cout);
gConfig.remove("fkey");
cout << "search fkey:" << endl;
gConfig.find("fkey",cout);
try {
gConfig.getNum("supposedtoabort");
} catch (ConfigurationTableKeyNotFound) {
cout << "ConfigurationTableKeyNotFound exception successfully caught." << endl;
}
}
ConfigurationKeyMap getConfigurationKeys()
{
ConfigurationKeyMap map;
ConfigurationKey *tmp;
tmp = new ConfigurationKey("booltest","0",
"",
ConfigurationKey::DEVELOPER,
ConfigurationKey::BOOLEAN,
"",
false,
""
);
map[tmp->getName()] = *tmp;
free(tmp);
tmp = new ConfigurationKey("numnumber","42",
"",
ConfigurationKey::DEVELOPER,
ConfigurationKey::VALRANGE,
"0-100",
false,
""
);
map[tmp->getName()] = *tmp;
free(tmp);
tmp = new ConfigurationKey("newstring","new string value",
"",
ConfigurationKey::DEVELOPER,
ConfigurationKey::STRING,
"",
false,
""
);
map[tmp->getName()] = *tmp;
free(tmp);
return map;
}

View File

@ -42,15 +42,21 @@
/** Pointer FIFO for interthread operations. */
template <class T> class InterthreadQueue {
// (pat) The elements in the queue are type T*, and
// the Fifo class implements the underlying queue.
// The default is class PointerFIFO, which does not place any restrictions on the type of T,
// and is implemented by allocating auxilliary structures for the queue,
// or SingleLinkedList, which implements the queue using an internal pointer in type T,
// which must implement the functional interface of class SingleLinkListNode,
// namely: functions T*next() and void setNext(T*).
template <class T, class Fifo=PointerFIFO> class InterthreadQueue {
protected:
PointerFIFO mQ;
Fifo mQ;
mutable Mutex mLock;
mutable Signal mWriteSignal;
public:
/** Delete contents. */
@ -78,6 +84,12 @@ template <class T> class InterthreadQueue {
return mQ.size();
}
size_t totalSize() const // pat added
{
ScopedLock lock(mLock);
return mQ.totalSize();
}
/**
Blocking read.
@return Pointer to object (will not be NULL).
@ -93,6 +105,13 @@ template <class T> class InterthreadQueue {
return retVal;
}
/** Non-blocking peek at the first element; returns NULL if empty. */
T* front()
{
ScopedLock lock(mLock);
return (T*) mQ.front();
}
/**
Blocking read with a timeout.
@param timeout The read timeout in ms.
@ -127,7 +146,132 @@ template <class T> class InterthreadQueue {
mWriteSignal.signal();
}
/** Non-block write to the front of the queue. */
void write_front(T* val) // pat added
{
ScopedLock lock(mLock);
mQ.push_front(val);
mWriteSignal.signal();
}
};
// (pat) Identical to above but with the threading problem fixed.
template <class T, class Fifo=PointerFIFO> class InterthreadQueue2 {
protected:
Fifo mQ;
mutable Mutex mLock;
mutable Signal mWriteSignal;
public:
/** Delete contents. */
void clear()
{
ScopedLock lock(mLock);
while (mQ.size()>0) delete (T*)mQ.get();
}
/** Empty the queue, but don't delete. */
void flushNoDelete()
{
ScopedLock lock(mLock);
while (mQ.size()>0) mQ.get();
}
~InterthreadQueue2()
{ clear(); }
size_t size() const
{
ScopedLock lock(mLock);
return mQ.size();
}
size_t totalSize() const // pat added
{
ScopedLock lock(mLock);
return mQ.totalSize();
}
/**
Blocking read.
@return Pointer to object (will not be NULL).
*/
T* read()
{
ScopedLock lock(mLock);
T* retVal = (T*)mQ.get();
while (retVal==NULL) {
mWriteSignal.wait(mLock);
retVal = (T*)mQ.get();
}
return retVal;
}
/** Non-blocking peek at the first element; returns NULL if empty. */
T* front()
{
ScopedLock lock(mLock);
return (T*) mQ.front();
}
/**
Blocking read with a timeout.
@param timeout The read timeout in ms.
@return Pointer to object or NULL on timeout.
*/
T* read(unsigned timeout)
{
if (timeout==0) return readNoBlock();
Timeval waitTime(timeout);
ScopedLock lock(mLock);
while ((mQ.size()==0) && (!waitTime.passed()))
mWriteSignal.wait(mLock,waitTime.remaining());
T* retVal = (T*)mQ.get();
return retVal;
}
/**
Non-blocking read.
@return Pointer to object or NULL if FIFO is empty.
*/
T* readNoBlock()
{
ScopedLock lock(mLock);
return (T*)mQ.get();
}
/** Non-blocking write. */
void write(T* val)
{
// (pat) The Mutex mLock must be released before signaling the mWriteSignal condition.
// This is an implicit requirement of pthread_cond_wait() called from signal().
// If you do not do that, the InterthreadQueue read() function cannot start
// because the mutex is still locked by the thread calling the write(),
// so the read() thread yields its immediate execution opportunity.
// This recurs (and the InterthreadQueue fills up with data)
// until the read thread's accumulated temporary priority causes it to
// get a second pre-emptive activation over the writing thread,
// resulting in bursts of activity by the read thread.
{ ScopedLock lock(mLock);
mQ.put(val);
}
mWriteSignal.signal();
}
/** Non-block write to the front of the queue. */
void write_front(T* val) // pat added
{
// (pat) See comments above.
{ ScopedLock lock(mLock);
mQ.push_front(val);
}
mWriteSignal.signal();
}
};
@ -214,12 +358,17 @@ template <class T> class InterthreadQueueWithWait {
/** Non-blocking write. */
void write(T* val)
{
// (pat) 8-14: Taking out the threading problem fix temporarily for David to use in the field.
ScopedLock lock(mLock);
mQ.put(val);
mWriteSignal.signal();
}
/** Wait until the queue falls below a low water mark. */
// (pat) This function suffers from the same problem as documented
// at InterthreadQueue.write(), but I am not fixing it because I cannot test it.
// The caller of this function will eventually get to run, just not immediately
// after the mReadSignal condition is fulfilled.
void wait(size_t sz=0)
{
ScopedLock lock(mLock);
@ -484,6 +633,7 @@ template <class T, class C = std::vector<T*>, class Cmp = PointerCompare<T> > cl
/** Non-blocking write. */
void write(T* val)
{
// (pat) 8-14: Taking out the threading problem fix temporarily for David to use in the field.
ScopedLock lock(mLock);
mQ.push(val);
mWriteSignal.signal();

View File

@ -82,7 +82,8 @@ void* mapReader(void*)
for (int i=0; i<20; i++) {
int *p = gMap.read(i);
COUT("map read " << *p);
delete p;
// InterthreadMap will delete the pointers
// delete p;
}
return NULL;
}

View File

@ -29,7 +29,17 @@
#include "LinkedLists.h"
void PointerFIFO::push_front(void* val) // by pat
{
// Pat added this routine for completeness, but never used or tested.
// The first person to use this routine should remove this assert.
ListNode *node = allocate();
node->data(val);
node->next(mHead);
mHead = node;
if (!mTail) mTail=node;
mSize++;
}
void PointerFIFO::put(void* val)
{
@ -58,7 +68,6 @@ void* PointerFIFO::get()
}
ListNode *PointerFIFO::allocate()
{
if (mFreeList==NULL) return new ListNode;
@ -72,6 +81,3 @@ void PointerFIFO::release(ListNode* wNode)
wNode->next(mFreeList);
mFreeList = wNode;
}

View File

@ -1,6 +1,8 @@
/*
* Copyright 2008 Free Software Foundation, Inc.
*
* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
@ -28,6 +30,7 @@
#define LINKEDLISTS_H
#include <stdlib.h>
#include <assert.h>
@ -54,7 +57,7 @@ class ListNode {
/** A fast FIFO for pointer-based storage. */
class PointerFIFO {
private:
protected:
ListNode* mHead; ///< points to next item out
ListNode* mTail; ///< points to last item in
@ -69,9 +72,12 @@ class PointerFIFO {
{}
unsigned size() const { return mSize; }
unsigned totalSize() const { return 0; } // Not used in this version.
/** Put an item into the FIFO. */
/** Put an item into the FIFO at the back of the queue. */
void put(void* val);
/** Push an item on the front of the FIFO. */
void push_front(void*val); // pat added.
/**
Take an item from the FIFO.
@ -79,6 +85,9 @@ class PointerFIFO {
*/
void* get();
/** Peek at front item without removal. */
void *front() { return mHead ? mHead->data() : 0; } // pat added
private:
@ -90,6 +99,74 @@ class PointerFIFO {
};
// This is the default type for SingleLinkList Node element;
// You can derive your class directly from this, but then you must add type casts
// all over the place.
class SingleLinkListNode
{ public:
SingleLinkListNode *mNext;
SingleLinkListNode *next() {return mNext;}
void setNext(SingleLinkListNode *item) {mNext=item;}
SingleLinkListNode() : mNext(0) {}
virtual unsigned size() { return 0; }
};
// A single-linked lists of elements with internal pointers.
// The methods must match those from SingleLinkListNode.
// This class also assumes the Node has a size() method, and accumulates
// the total size of elements in the list in totalSize().
template<class Node=SingleLinkListNode>
class SingleLinkList
{
Node *mHead, *mTail;
unsigned mSize; // Number of elements in list.
unsigned mTotalSize; // Total of size() method of elements in list.
public:
SingleLinkList() : mHead(0), mTail(0), mSize(0), mTotalSize(0) {}
unsigned size() const { return mSize; }
unsigned totalSize() const { return mTotalSize; }
Node *pop_back() { assert(0); } // Not efficient with this type of list.
Node *pop_front()
{
if (!mHead) return NULL;
Node *result = mHead;
mHead = mHead->next();
if (mTail == result) { mTail = NULL; assert(mHead == NULL); }
result->setNext(NULL); // be neat
mSize--;
mTotalSize -= result->size();
return result;
}
void push_front(Node *item)
{
item->setNext(mHead);
mHead = item;
if (!mTail) { mTail = item; }
mSize++;
mTotalSize += item->size();
}
void push_back(Node *item)
{
item->setNext(NULL);
if (mTail) { mTail->setNext(item); }
mTail = item;
if (!mHead) mHead = item;
mSize++;
mTotalSize += item->size();
}
Node *front() { return mHead; }
Node *back() { return mTail; }
// Interface to InterthreadQueue so it can used SingleLinkList as the Fifo.
void put(void *val) { push_back((Node*)val); }
void *get() { return pop_front(); }
};

View File

@ -37,7 +37,7 @@ void printAlarms()
{
std::ostream_iterator<std::string> output( std::cout, "\n" );
std::list<std::string> alarms = gGetLoggerAlarms();
std::cout << "#alarms = " << alarms.size() << std::endl;
std::cout << "# alarms = " << alarms.size() << std::endl;
std::copy( alarms.begin(), alarms.end(), output );
}
@ -55,7 +55,6 @@ int main(int argc, char *argv[])
LOG(DEBUG) << " testing the logger.";
std::cout << "\n\n\n";
std::cout << "testing Alarms\n";
LOG(ALERT) << " testing the logger alarm.";
std::cout << "you should see three lines:" << std::endl;
printAlarms();
std::cout << "----------- generating 20 alarms ----------" << std::endl;

View File

@ -1,6 +1,7 @@
/*
* Copyright 2009, 2010 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
* Copyright 2011, 2012 Range Networks, Inc.
*
*
* This software is distributed under the terms of the GNU Affero Public License.
@ -28,9 +29,11 @@
#include <cstdio>
#include <fstream>
#include <string>
#include <stdarg.h>
#include "Configuration.h"
#include "Logger.h"
#include "Threads.h" // pat added
using namespace std;
@ -48,36 +51,71 @@ void addAlarm(const string&);
// (pat) If Log messages are printed before the classes in this module are inited
// (which happens when static classes have constructors that do work)
// the OpenBTS just crashes.
// Prevent that by setting sLoggerInited to true when this module is inited.
static bool sLoggerInited = 0;
static struct CheckLoggerInitStatus {
CheckLoggerInitStatus() { sLoggerInited = 1; }
} sCheckloggerInitStatus;
/** Names of the logging levels. */
const char *levelNames[] = {
"EMERG", "ALERT", "CRIT", "ERR", "WARNING", "NOTICE", "INFO", "DEBUG"
};
int numLevels = 8;
bool gLogToConsole = 0;
FILE *gLogToFile = NULL;
Mutex gLogToLock;
/** Given a string, return the corresponding level name. */
int lookupLevel(const string& name)
int levelStringToInt(const string& name)
{
// Reverse search, since the numerically larger levels are more common.
for (int i=numLevels-1; i>=0; i--) {
if (name == levelNames[i]) return i;
}
// This should never be called with a bogus name.
LOG(ERR) << "undefined logging level " << name << "defaulting to ERR";
return LOG_ERR;
// Common substitutions.
if (name=="INFORMATION") return 6;
if (name=="WARN") return 4;
if (name=="ERROR") return 3;
if (name=="CRITICAL") return 2;
if (name=="EMERGENCY") return 0;
// Unknown level.
return -1;
}
/** Given a string, return the corresponding level name. */
int lookupLevel(const string& key)
{
string val = gConfig.getStr(key);
int level = levelStringToInt(val);
if (level == -1) {
string defaultLevel = gConfig.mSchema["Log.Level"].getDefaultValue();
level = levelStringToInt(defaultLevel);
_LOG(CRIT) << "undefined logging level (" << key << " = \"" << val << "\") defaulting to \"" << defaultLevel << ".\" Valid levels are: EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO or DEBUG";
gConfig.set(key, defaultLevel);
}
return level;
}
int getLoggingLevel(const char* filename)
{
// Default level?
if (!filename) return lookupLevel(gConfig.getStr("Log.Level"));
if (!filename) return lookupLevel("Log.Level");
// This can afford to be inefficient since it is not called that often.
const string keyName = string("Log.Level.") + string(filename);
if (gConfig.defines(keyName)) return lookupLevel(gConfig.getStr(keyName));
return lookupLevel(gConfig.getStr("Log.Level"));
if (gConfig.defines(keyName)) return lookupLevel(keyName);
return lookupLevel("Log.Level");
}
@ -112,6 +150,7 @@ int gGetLoggingLevel(const char* filename)
}
// Look it up in the config table and cache it.
// FIXME: Figure out why unlock and lock below fix the config table deadlock.
// (pat) Probably because getLoggingLevel may call LOG recursively via lookupLevel().
sLogCacheLock.unlock();
int level = getLoggingLevel(filename);
sLogCacheLock.lock();
@ -154,12 +193,30 @@ Log::~Log()
// Anything at or above LOG_CRIT is an "alarm".
// Save alarms in the local list and echo them to stderr.
if (mPriority <= LOG_CRIT) {
addAlarm(mStream.str().c_str());
if (sLoggerInited) addAlarm(mStream.str().c_str());
cerr << mStream.str() << endl;
}
// Current logging level was already checked by the macro.
// So just log.
syslog(mPriority, "%s", mStream.str().c_str());
// pat added for easy debugging.
if (gLogToConsole||gLogToFile) {
int mlen = mStream.str().size();
int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
gLogToLock.lock();
if (gLogToConsole) {
// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
// so just use std::cout.
std::cout << mStream.str();
if (neednl) std::cout<<"\n";
}
if (gLogToFile) {
fputs(mStream.str().c_str(),gLogToFile);
if (neednl) {fputc('\n',gLogToFile);}
fflush(gLogToFile);
}
gLogToLock.unlock();
}
}
@ -181,18 +238,26 @@ ostringstream& Log::get()
void gLogInit(const char* name, const char* level, int facility)
{
// Set the level.
// Set the level if one has been specified.
if (level) {
gConfig.set("Log.Level",level);
} else {
if (!gConfig.defines("Log.Level")) {
gConfig.set("Log.Level","WARNING");
}
}
// Define other logging parameters in the global config.
if (!gConfig.defines("Log.Alarms.Max")) {
gConfig.set("Log.Alarms.Max",DEFAULT_MAX_ALARMS);
// Pat added, tired of the syslog facility.
// Both the transceiver and OpenBTS use this same facility, but only OpenBTS/OpenNodeB may use this log file:
string str = gConfig.getStr("Log.File");
if (gLogToFile==0 && str.length() && 0==strncmp(gCmdName,"Open",4)) {
const char *fn = str.c_str();
if (fn && *fn && strlen(fn)>3) { // strlen because a garbage char is getting in sometimes.
gLogToFile = fopen(fn,"w"); // New log file each time we start.
if (gLogToFile) {
time_t now;
time(&now);
fprintf(gLogToFile,"Starting at %s",ctime(&now));
fflush(gLogToFile);
std::cout << "Logging to file: " << fn << "\n";
}
}
}
// Open the log connection.
@ -200,6 +265,13 @@ void gLogInit(const char* name, const char* level, int facility)
}
void gLogEarly(int level, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsyslog(level | LOG_USER, fmt, args);
va_end(args);
}
// vim: ts=4 sw=4

View File

@ -23,6 +23,11 @@
*/
// (pat) WARNING is stupidly defined in /usr/local/include/osipparser2/osip_const.h.
// This must be outside the #ifndef LOGGER_H to fix it as long as Logger.h included after the above file.
#ifdef WARNING
#undef WARNING
#endif
#ifndef LOGGER_H
#define LOGGER_H
@ -34,21 +39,42 @@
#include <list>
#include <map>
#include <string>
#include "Threads.h"
#define _LOG(level) \
Log(LOG_##level).get() << pthread_self() \
<< " " __FILE__ ":" << __LINE__ << ":" << __FUNCTION__ << ": "
<< timestr() << " " __FILE__ ":" << __LINE__ << ":" << __FUNCTION__ << ": "
#define IS_LOG_LEVEL(wLevel) (gGetLoggingLevel(__FILE__)>=LOG_##wLevel)
#ifdef NDEBUG
#define LOG(wLevel) \
if (LOG_##wLevel!=LOG_DEBUG && gGetLoggingLevel(__FILE__)>=LOG_##wLevel) _LOG(wLevel)
if (LOG_##wLevel!=LOG_DEBUG && IS_LOG_LEVEL(wLevel)) _LOG(wLevel)
#else
#define LOG(wLevel) \
if (gGetLoggingLevel(__FILE__)>=LOG_##wLevel) _LOG(wLevel)
if (IS_LOG_LEVEL(wLevel)) _LOG(wLevel)
#endif
// pat: And for your edification here are the 'levels' as defined in syslog.h:
// LOG_EMERG 0 system is unusable
// LOG_ALERT 1 action must be taken immediately
// LOG_CRIT 2 critical conditions
// LOG_ERR 3 error conditions
// LOG_WARNING 4 warning conditions
// LOG_NOTICE 5 normal, but significant, condition
// LOG_INFO 6 informational message
// LOG_DEBUG 7 debug-level message
// (pat) added - print out a var and its name.
// Use like this: int descriptive_name; LOG(INFO)<<LOGVAR(descriptive_name);
#define LOGVAR2(name,val) " " << name << "=" << (val)
#define LOGVAR(var) (" " #var "=") << var
#define LOGHEX(var) (" " #var "=0x") << hex << ((unsigned)var) << dec
#define LOGHEX2(name,val) " " << name << "=0x" << hex << ((unsigned)(val)) << dec
// These are kind of cheesy, but you can use for bitvector
#define LOGBV2(name,val) " " << name << "=(" << val<<" size:"<<val.size()<<")"
#define LOGBV(bv) LOGBV2(#bv,bv)
#define LOGVARRANGE(name,cur,lo,hi) " "<<name <<"=("<<(cur) << " range:"<<(lo) << " to "<<(hi) <<")"
#define OBJLOG(wLevel) \
LOG(wLevel) << "obj: " << this << ' '
@ -56,8 +82,8 @@
#define LOG_ASSERT(x) { if (!(x)) LOG(EMERG) << "assertion " #x " failed"; } assert(x);
#define DEFAULT_MAX_ALARMS 10
#include "Threads.h" // must be after defines above, if these files are to be allowed to use LOG()
#include "Utils.h"
/**
A C++ stream-based thread-safe logger.
@ -73,7 +99,7 @@ class Log {
protected:
std::ostringstream mStream; ///< This is where we buffer up the log entry.
int mPriority; ///< Priority of current repot.
int mPriority; ///< Priority of current report.
bool mDummyInit;
public:
@ -84,12 +110,13 @@ class Log {
Log(const char* name, const char* level=NULL, int facility=LOG_USER);
// Most of the work is in the desctructor.
// Most of the work is in the destructor.
/** The destructor actually generates the log entry. */
~Log();
std::ostringstream& get();
};
extern bool gLogToConsole; // Pat added for easy debugging.
@ -102,6 +129,8 @@ std::list<std::string> gGetLoggerAlarms(); ///< Get a copy of the recent alarm
void gLogInit(const char* name, const char* level=NULL, int facility=LOG_USER);
/** Get the logging level associated with a given file. */
int gGetLoggingLevel(const char *filename=NULL);
/** Allow early logging when still in constructors */
void gLogEarly(int level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
//@}

659
Makefile
View File

@ -1,659 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# CommonLibs/Makefile. Generated from Makefile.in by configure.
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
#
# Copyright 2008, 2009 Free Software Foundation, Inc.
#
# This software is distributed under the terms of the GNU Public License.
# See the COPYING file in the main directory for details.
#
# 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 <http://www.gnu.org/licenses/>.
#
#
# Copyright 2008 Free Software Foundation, Inc.
#
# This software is distributed under the terms of the GNU Public License.
# See the COPYING file in the main directory for details.
#
# 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 <http://www.gnu.org/licenses/>.
#
SOURCES = $(libcommon_la_SOURCES) $(BitVectorTest_SOURCES) $(ConfigurationTest_SOURCES) $(F16Test_SOURCES) $(InterthreadTest_SOURCES) $(LogTest_SOURCES) $(RegexpTest_SOURCES) $(SocketsTest_SOURCES) $(TimevalTest_SOURCES) $(VectorTest_SOURCES)
srcdir = .
top_srcdir = ..
pkgdatadir = $(datadir)/openbts
pkglibdir = $(libdir)/openbts
pkgincludedir = $(includedir)/openbts
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = /opt/local/bin/ginstall -c
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = i686-apple-darwin10.8.0
host_triplet = i686-apple-darwin10.8.0
target_triplet = i686-apple-darwin10.8.0
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/Makefile.common
noinst_PROGRAMS = BitVectorTest$(EXEEXT) InterthreadTest$(EXEEXT) \
SocketsTest$(EXEEXT) TimevalTest$(EXEEXT) RegexpTest$(EXEEXT) \
VectorTest$(EXEEXT) ConfigurationTest$(EXEEXT) \
LogTest$(EXEEXT) F16Test$(EXEEXT)
subdir = CommonLibs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libcommon_la_LIBADD =
am_libcommon_la_OBJECTS = BitVector.lo LinkedLists.lo Sockets.lo \
Threads.lo Timeval.lo Logger.lo Configuration.lo
libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
am_BitVectorTest_OBJECTS = BitVectorTest.$(OBJEXT)
BitVectorTest_OBJECTS = $(am_BitVectorTest_OBJECTS)
BitVectorTest_DEPENDENCIES = libcommon.la
am_ConfigurationTest_OBJECTS = ConfigurationTest.$(OBJEXT)
ConfigurationTest_OBJECTS = $(am_ConfigurationTest_OBJECTS)
am__DEPENDENCIES_1 = $(top_builddir)/sqlite/libsqlite.la
ConfigurationTest_DEPENDENCIES = libcommon.la $(am__DEPENDENCIES_1)
am_F16Test_OBJECTS = F16Test.$(OBJEXT)
F16Test_OBJECTS = $(am_F16Test_OBJECTS)
F16Test_LDADD = $(LDADD)
am_InterthreadTest_OBJECTS = InterthreadTest.$(OBJEXT)
InterthreadTest_OBJECTS = $(am_InterthreadTest_OBJECTS)
InterthreadTest_DEPENDENCIES = libcommon.la
am_LogTest_OBJECTS = LogTest.$(OBJEXT)
LogTest_OBJECTS = $(am_LogTest_OBJECTS)
LogTest_DEPENDENCIES = libcommon.la $(am__DEPENDENCIES_1)
am_RegexpTest_OBJECTS = RegexpTest.$(OBJEXT)
RegexpTest_OBJECTS = $(am_RegexpTest_OBJECTS)
RegexpTest_DEPENDENCIES = libcommon.la
am_SocketsTest_OBJECTS = SocketsTest.$(OBJEXT)
SocketsTest_OBJECTS = $(am_SocketsTest_OBJECTS)
SocketsTest_DEPENDENCIES = libcommon.la
am_TimevalTest_OBJECTS = TimevalTest.$(OBJEXT)
TimevalTest_OBJECTS = $(am_TimevalTest_OBJECTS)
TimevalTest_DEPENDENCIES = libcommon.la
am_VectorTest_OBJECTS = VectorTest.$(OBJEXT)
VectorTest_OBJECTS = $(am_VectorTest_OBJECTS)
VectorTest_DEPENDENCIES = libcommon.la
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libcommon_la_SOURCES) $(BitVectorTest_SOURCES) \
$(ConfigurationTest_SOURCES) $(F16Test_SOURCES) \
$(InterthreadTest_SOURCES) $(LogTest_SOURCES) \
$(RegexpTest_SOURCES) $(SocketsTest_SOURCES) \
$(TimevalTest_SOURCES) $(VectorTest_SOURCES)
DIST_SOURCES = $(libcommon_la_SOURCES) $(BitVectorTest_SOURCES) \
$(ConfigurationTest_SOURCES) $(F16Test_SOURCES) \
$(InterthreadTest_SOURCES) $(LogTest_SOURCES) \
$(RegexpTest_SOURCES) $(SocketsTest_SOURCES) \
$(TimevalTest_SOURCES) $(VectorTest_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/missing --run aclocal-1.9
AMDEP_FALSE = #
AMDEP_TRUE =
AMTAR = ${SHELL} /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/missing --run tar
AR = ar
AS = as
AUTOCONF = ${SHELL} /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/missing --run autoconf
AUTOHEADER = ${SHELL} /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/missing --run autoheader
AUTOMAKE = ${SHELL} /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/missing --run automake-1.9
AWK = gawk
CC = gcc
CCAS = gcc
CCASFLAGS = -g -O2
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS =
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = dlltool
ECHO = /bin/echo
ECHO_C = \c
ECHO_N =
ECHO_T =
EGREP = /usr/bin/grep -E
EXEEXT =
F77 = gfortran
FFLAGS = -g -O2
GREP = /usr/bin/grep
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
LDFLAGS =
LIBOBJS =
LIBS =
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LN_S = ln -s
LTLIBOBJS =
MAKEINFO = ${SHELL} /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/missing --run makeinfo
OBJDUMP = objdump
OBJEXT = o
ORTP_CFLAGS = -D_REENTRANT -DORTP_INET6 -I/usr/local/include
ORTP_LIBS = -L/usr/local/lib -lortp -lpthread -lssl -lcrypto
OSIP_CFLAGS = -DOSIP_MT -I/usr/local/include
OSIP_LIBS = -L/usr/local/lib -losipparser2 -losip2
PACKAGE = openbts
PACKAGE_BUGREPORT =
PACKAGE_NAME = openbts
PACKAGE_STRING = openbts P2.8TRUNK
PACKAGE_TARNAME = openbts
PACKAGE_VERSION = P2.8TRUNK
PATH_SEPARATOR = :
PKG_CONFIG = /sw/bin/pkg-config
RANLIB = ranlib
RM_PROG = /bin/rm
SET_MAKE =
SHELL = /bin/sh
STRIP = strip
USRP_CFLAGS = @USRP_CFLAGS@
USRP_LIBS = @USRP_LIBS@
VERSION = P2.8TRUNK
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_F77 = gfortran
am__fastdepCC_FALSE = #
am__fastdepCC_TRUE =
am__fastdepCXX_FALSE = #
am__fastdepCXX_TRUE =
am__include = include
am__leading_dot = .
am__quote =
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build = i686-apple-darwin10.8.0
build_alias =
build_cpu = i686
build_os = darwin10.8.0
build_vendor = apple
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = i686-apple-darwin10.8.0
host_alias =
host_cpu = i686
host_os = darwin10.8.0
host_vendor = apple
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = /Users/dburgess/OpenBTSProject/range/software/private/openbts/trunk-public-staging/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = $(install_sh) -d
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
sysconfdir = ${prefix}/etc
target = i686-apple-darwin10.8.0
target_alias =
target_cpu = i686
target_os = darwin10.8.0
target_vendor = apple
COMMON_INCLUDEDIR = $(top_srcdir)/CommonLibs
CONTROL_INCLUDEDIR = $(top_srcdir)/Control
GSM_INCLUDEDIR = $(top_srcdir)/GSM
SIP_INCLUDEDIR = $(top_srcdir)/SIP
SMS_INCLUDEDIR = $(top_srcdir)/SMS
TRX_INCLUDEDIR = $(top_srcdir)/TRXManager
GLOBALS_INCLUDEDIR = $(top_srcdir)/Globals
CLI_INCLUDEDIR = $(top_srcdir)/CLI
SQLITE_INCLUDEDIR = $(top_srcdir)/sqlite
HLR_INCLUDEDIR = $(top_srcdir)/HLR
STD_DEFINES_AND_INCLUDES = \
-I$(COMMON_INCLUDEDIR) \
-I$(CONTROL_INCLUDEDIR) \
-I$(GSM_INCLUDEDIR) \
-I$(SIP_INCLUDEDIR) \
-I$(SMS_INCLUDEDIR) \
-I$(TRX_INCLUDEDIR) \
-I$(GLOBALS_INCLUDEDIR) \
-I$(CLI_INCLUDEDIR) \
-I$(HLR_INCLUDEDIR) \
-I$(SQLITE_INCLUDEDIR)
COMMON_LA = $(top_builddir)/CommonLibs/libcommon.la
GSM_LA = $(top_builddir)/GSM/libGSM.la
SIP_LA = $(top_builddir)/SIP/libSIP.la
SMS_LA = $(top_builddir)/SMS/libSMS.la
TRX_LA = $(top_builddir)/TRXManager/libtrxmanager.la
CONTROL_LA = $(top_builddir)/Control/libcontrol.la
GLOBALS_LA = $(top_builddir)/Globals/libglobals.la
CLI_LA = $(top_builddir)/CLI/libcli.la
HLR_LA = $(top_builddir)/HLR/libHLR.la
SQLITE_LA = $(top_builddir)/sqlite/libsqlite.la
MOSTLYCLEANFILES = *~ testSource testDestination
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
AM_CXXFLAGS = -Wall -O3 -g -lpthread
EXTRA_DIST = \
example.config \
README.common
noinst_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = \
BitVector.cpp \
LinkedLists.cpp \
Sockets.cpp \
Threads.cpp \
Timeval.cpp \
Logger.cpp \
Configuration.cpp
noinst_HEADERS = \
BitVector.h \
Interthread.h \
LinkedLists.h \
Sockets.h \
Threads.h \
Timeval.h \
Regexp.h \
Vector.h \
Configuration.h \
F16.h \
Logger.h
BitVectorTest_SOURCES = BitVectorTest.cpp
BitVectorTest_LDADD = libcommon.la
InterthreadTest_SOURCES = InterthreadTest.cpp
InterthreadTest_LDADD = libcommon.la
InterthreadTest_LDFLAGS = -lpthread
SocketsTest_SOURCES = SocketsTest.cpp
SocketsTest_LDADD = libcommon.la
SocketsTest_LDFLAGS = -lpthread
TimevalTest_SOURCES = TimevalTest.cpp
TimevalTest_LDADD = libcommon.la
VectorTest_SOURCES = VectorTest.cpp
VectorTest_LDADD = libcommon.la
RegexpTest_SOURCES = RegexpTest.cpp
RegexpTest_LDADD = libcommon.la
ConfigurationTest_SOURCES = ConfigurationTest.cpp
ConfigurationTest_LDADD = libcommon.la $(SQLITE_LA)
LogTest_SOURCES = LogTest.cpp
LogTest_LDADD = libcommon.la $(SQLITE_LA)
F16Test_SOURCES = F16Test.cpp
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.common $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu CommonLibs/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu CommonLibs/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES)
$(CXXLINK) $(libcommon_la_LDFLAGS) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
BitVectorTest$(EXEEXT): $(BitVectorTest_OBJECTS) $(BitVectorTest_DEPENDENCIES)
@rm -f BitVectorTest$(EXEEXT)
$(CXXLINK) $(BitVectorTest_LDFLAGS) $(BitVectorTest_OBJECTS) $(BitVectorTest_LDADD) $(LIBS)
ConfigurationTest$(EXEEXT): $(ConfigurationTest_OBJECTS) $(ConfigurationTest_DEPENDENCIES)
@rm -f ConfigurationTest$(EXEEXT)
$(CXXLINK) $(ConfigurationTest_LDFLAGS) $(ConfigurationTest_OBJECTS) $(ConfigurationTest_LDADD) $(LIBS)
F16Test$(EXEEXT): $(F16Test_OBJECTS) $(F16Test_DEPENDENCIES)
@rm -f F16Test$(EXEEXT)
$(CXXLINK) $(F16Test_LDFLAGS) $(F16Test_OBJECTS) $(F16Test_LDADD) $(LIBS)
InterthreadTest$(EXEEXT): $(InterthreadTest_OBJECTS) $(InterthreadTest_DEPENDENCIES)
@rm -f InterthreadTest$(EXEEXT)
$(CXXLINK) $(InterthreadTest_LDFLAGS) $(InterthreadTest_OBJECTS) $(InterthreadTest_LDADD) $(LIBS)
LogTest$(EXEEXT): $(LogTest_OBJECTS) $(LogTest_DEPENDENCIES)
@rm -f LogTest$(EXEEXT)
$(CXXLINK) $(LogTest_LDFLAGS) $(LogTest_OBJECTS) $(LogTest_LDADD) $(LIBS)
RegexpTest$(EXEEXT): $(RegexpTest_OBJECTS) $(RegexpTest_DEPENDENCIES)
@rm -f RegexpTest$(EXEEXT)
$(CXXLINK) $(RegexpTest_LDFLAGS) $(RegexpTest_OBJECTS) $(RegexpTest_LDADD) $(LIBS)
SocketsTest$(EXEEXT): $(SocketsTest_OBJECTS) $(SocketsTest_DEPENDENCIES)
@rm -f SocketsTest$(EXEEXT)
$(CXXLINK) $(SocketsTest_LDFLAGS) $(SocketsTest_OBJECTS) $(SocketsTest_LDADD) $(LIBS)
TimevalTest$(EXEEXT): $(TimevalTest_OBJECTS) $(TimevalTest_DEPENDENCIES)
@rm -f TimevalTest$(EXEEXT)
$(CXXLINK) $(TimevalTest_LDFLAGS) $(TimevalTest_OBJECTS) $(TimevalTest_LDADD) $(LIBS)
VectorTest$(EXEEXT): $(VectorTest_OBJECTS) $(VectorTest_DEPENDENCIES)
@rm -f VectorTest$(EXEEXT)
$(CXXLINK) $(VectorTest_LDFLAGS) $(VectorTest_OBJECTS) $(VectorTest_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/BitVector.Plo
include ./$(DEPDIR)/BitVectorTest.Po
include ./$(DEPDIR)/Configuration.Plo
include ./$(DEPDIR)/ConfigurationTest.Po
include ./$(DEPDIR)/F16Test.Po
include ./$(DEPDIR)/InterthreadTest.Po
include ./$(DEPDIR)/LinkedLists.Plo
include ./$(DEPDIR)/LogTest.Po
include ./$(DEPDIR)/Logger.Plo
include ./$(DEPDIR)/RegexpTest.Po
include ./$(DEPDIR)/Sockets.Plo
include ./$(DEPDIR)/SocketsTest.Po
include ./$(DEPDIR)/Threads.Plo
include ./$(DEPDIR)/Timeval.Plo
include ./$(DEPDIR)/TimevalTest.Po
include ./$(DEPDIR)/VectorTest.Po
.cpp.o:
if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
# source='$<' object='$@' libtool=yes \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
ctags distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,5 +1,6 @@
#
# Copyright 2008, 2009 Free Software Foundation, Inc.
# Copyright 2011, 2012 Range Networks, Inc.
#
# This software is distributed under the terms of the GNU Public License.
# See the COPYING file in the main directory for details.
@ -21,7 +22,7 @@
include $(top_srcdir)/Makefile.common
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
AM_CXXFLAGS = -Wall -O3 -g -lpthread
AM_CXXFLAGS = -Wall -O3 -g -ldl -lpthread
EXTRA_DIST = \
example.config \
@ -35,8 +36,12 @@ libcommon_la_SOURCES = \
Sockets.cpp \
Threads.cpp \
Timeval.cpp \
Reporting.cpp \
Logger.cpp \
Configuration.cpp
Configuration.cpp \
sqlite3util.cpp \
URLEncode.cpp \
Utils.cpp
noinst_PROGRAMS = \
BitVectorTest \
@ -47,8 +52,11 @@ noinst_PROGRAMS = \
VectorTest \
ConfigurationTest \
LogTest \
URLEncodeTest \
F16Test
# ReportingTest
noinst_HEADERS = \
BitVector.h \
Interthread.h \
@ -59,11 +67,18 @@ noinst_HEADERS = \
Regexp.h \
Vector.h \
Configuration.h \
Reporting.h \
F16.h \
Logger.h
URLEncode.h \
Utils.h \
Logger.h \
sqlite3util.h
URLEncodeTest_SOURCES = URLEncodeTest.cpp
URLEncodeTest_LDADD = libcommon.la
BitVectorTest_SOURCES = BitVectorTest.cpp
BitVectorTest_LDADD = libcommon.la
BitVectorTest_LDADD = libcommon.la $(SQLITE_LA)
InterthreadTest_SOURCES = InterthreadTest.cpp
InterthreadTest_LDADD = libcommon.la
@ -77,7 +92,7 @@ TimevalTest_SOURCES = TimevalTest.cpp
TimevalTest_LDADD = libcommon.la
VectorTest_SOURCES = VectorTest.cpp
VectorTest_LDADD = libcommon.la
VectorTest_LDADD = libcommon.la $(SQLITE_LA)
RegexpTest_SOURCES = RegexpTest.cpp
RegexpTest_LDADD = libcommon.la
@ -85,6 +100,9 @@ RegexpTest_LDADD = libcommon.la
ConfigurationTest_SOURCES = ConfigurationTest.cpp
ConfigurationTest_LDADD = libcommon.la $(SQLITE_LA)
# ReportingTest_SOURCES = ReportingTest.cpp
# ReportingTest_LDADD = libcommon.la $(SQLITE_LA)
LogTest_SOURCES = LogTest.cpp
LogTest_LDADD = libcommon.la $(SQLITE_LA)

View File

@ -1,659 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#
# Copyright 2008, 2009 Free Software Foundation, Inc.
#
# This software is distributed under the terms of the GNU Public License.
# See the COPYING file in the main directory for details.
#
# 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 <http://www.gnu.org/licenses/>.
#
#
# Copyright 2008 Free Software Foundation, Inc.
#
# This software is distributed under the terms of the GNU Public License.
# See the COPYING file in the main directory for details.
#
# 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 <http://www.gnu.org/licenses/>.
#
SOURCES = $(libcommon_la_SOURCES) $(BitVectorTest_SOURCES) $(ConfigurationTest_SOURCES) $(F16Test_SOURCES) $(InterthreadTest_SOURCES) $(LogTest_SOURCES) $(RegexpTest_SOURCES) $(SocketsTest_SOURCES) $(TimevalTest_SOURCES) $(VectorTest_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/Makefile.common
noinst_PROGRAMS = BitVectorTest$(EXEEXT) InterthreadTest$(EXEEXT) \
SocketsTest$(EXEEXT) TimevalTest$(EXEEXT) RegexpTest$(EXEEXT) \
VectorTest$(EXEEXT) ConfigurationTest$(EXEEXT) \
LogTest$(EXEEXT) F16Test$(EXEEXT)
subdir = CommonLibs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libcommon_la_LIBADD =
am_libcommon_la_OBJECTS = BitVector.lo LinkedLists.lo Sockets.lo \
Threads.lo Timeval.lo Logger.lo Configuration.lo
libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
am_BitVectorTest_OBJECTS = BitVectorTest.$(OBJEXT)
BitVectorTest_OBJECTS = $(am_BitVectorTest_OBJECTS)
BitVectorTest_DEPENDENCIES = libcommon.la
am_ConfigurationTest_OBJECTS = ConfigurationTest.$(OBJEXT)
ConfigurationTest_OBJECTS = $(am_ConfigurationTest_OBJECTS)
am__DEPENDENCIES_1 = $(top_builddir)/sqlite/libsqlite.la
ConfigurationTest_DEPENDENCIES = libcommon.la $(am__DEPENDENCIES_1)
am_F16Test_OBJECTS = F16Test.$(OBJEXT)
F16Test_OBJECTS = $(am_F16Test_OBJECTS)
F16Test_LDADD = $(LDADD)
am_InterthreadTest_OBJECTS = InterthreadTest.$(OBJEXT)
InterthreadTest_OBJECTS = $(am_InterthreadTest_OBJECTS)
InterthreadTest_DEPENDENCIES = libcommon.la
am_LogTest_OBJECTS = LogTest.$(OBJEXT)
LogTest_OBJECTS = $(am_LogTest_OBJECTS)
LogTest_DEPENDENCIES = libcommon.la $(am__DEPENDENCIES_1)
am_RegexpTest_OBJECTS = RegexpTest.$(OBJEXT)
RegexpTest_OBJECTS = $(am_RegexpTest_OBJECTS)
RegexpTest_DEPENDENCIES = libcommon.la
am_SocketsTest_OBJECTS = SocketsTest.$(OBJEXT)
SocketsTest_OBJECTS = $(am_SocketsTest_OBJECTS)
SocketsTest_DEPENDENCIES = libcommon.la
am_TimevalTest_OBJECTS = TimevalTest.$(OBJEXT)
TimevalTest_OBJECTS = $(am_TimevalTest_OBJECTS)
TimevalTest_DEPENDENCIES = libcommon.la
am_VectorTest_OBJECTS = VectorTest.$(OBJEXT)
VectorTest_OBJECTS = $(am_VectorTest_OBJECTS)
VectorTest_DEPENDENCIES = libcommon.la
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libcommon_la_SOURCES) $(BitVectorTest_SOURCES) \
$(ConfigurationTest_SOURCES) $(F16Test_SOURCES) \
$(InterthreadTest_SOURCES) $(LogTest_SOURCES) \
$(RegexpTest_SOURCES) $(SocketsTest_SOURCES) \
$(TimevalTest_SOURCES) $(VectorTest_SOURCES)
DIST_SOURCES = $(libcommon_la_SOURCES) $(BitVectorTest_SOURCES) \
$(ConfigurationTest_SOURCES) $(F16Test_SOURCES) \
$(InterthreadTest_SOURCES) $(LogTest_SOURCES) \
$(RegexpTest_SOURCES) $(SocketsTest_SOURCES) \
$(TimevalTest_SOURCES) $(VectorTest_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
ORTP_CFLAGS = @ORTP_CFLAGS@
ORTP_LIBS = @ORTP_LIBS@
OSIP_CFLAGS = @OSIP_CFLAGS@
OSIP_LIBS = @OSIP_LIBS@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RM_PROG = @RM_PROG@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USRP_CFLAGS = @USRP_CFLAGS@
USRP_LIBS = @USRP_LIBS@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
COMMON_INCLUDEDIR = $(top_srcdir)/CommonLibs
CONTROL_INCLUDEDIR = $(top_srcdir)/Control
GSM_INCLUDEDIR = $(top_srcdir)/GSM
SIP_INCLUDEDIR = $(top_srcdir)/SIP
SMS_INCLUDEDIR = $(top_srcdir)/SMS
TRX_INCLUDEDIR = $(top_srcdir)/TRXManager
GLOBALS_INCLUDEDIR = $(top_srcdir)/Globals
CLI_INCLUDEDIR = $(top_srcdir)/CLI
SQLITE_INCLUDEDIR = $(top_srcdir)/sqlite
HLR_INCLUDEDIR = $(top_srcdir)/HLR
STD_DEFINES_AND_INCLUDES = \
-I$(COMMON_INCLUDEDIR) \
-I$(CONTROL_INCLUDEDIR) \
-I$(GSM_INCLUDEDIR) \
-I$(SIP_INCLUDEDIR) \
-I$(SMS_INCLUDEDIR) \
-I$(TRX_INCLUDEDIR) \
-I$(GLOBALS_INCLUDEDIR) \
-I$(CLI_INCLUDEDIR) \
-I$(HLR_INCLUDEDIR) \
-I$(SQLITE_INCLUDEDIR)
COMMON_LA = $(top_builddir)/CommonLibs/libcommon.la
GSM_LA = $(top_builddir)/GSM/libGSM.la
SIP_LA = $(top_builddir)/SIP/libSIP.la
SMS_LA = $(top_builddir)/SMS/libSMS.la
TRX_LA = $(top_builddir)/TRXManager/libtrxmanager.la
CONTROL_LA = $(top_builddir)/Control/libcontrol.la
GLOBALS_LA = $(top_builddir)/Globals/libglobals.la
CLI_LA = $(top_builddir)/CLI/libcli.la
HLR_LA = $(top_builddir)/HLR/libHLR.la
SQLITE_LA = $(top_builddir)/sqlite/libsqlite.la
MOSTLYCLEANFILES = *~ testSource testDestination
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
AM_CXXFLAGS = -Wall -O3 -g -lpthread
EXTRA_DIST = \
example.config \
README.common
noinst_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = \
BitVector.cpp \
LinkedLists.cpp \
Sockets.cpp \
Threads.cpp \
Timeval.cpp \
Logger.cpp \
Configuration.cpp
noinst_HEADERS = \
BitVector.h \
Interthread.h \
LinkedLists.h \
Sockets.h \
Threads.h \
Timeval.h \
Regexp.h \
Vector.h \
Configuration.h \
F16.h \
Logger.h
BitVectorTest_SOURCES = BitVectorTest.cpp
BitVectorTest_LDADD = libcommon.la
InterthreadTest_SOURCES = InterthreadTest.cpp
InterthreadTest_LDADD = libcommon.la
InterthreadTest_LDFLAGS = -lpthread
SocketsTest_SOURCES = SocketsTest.cpp
SocketsTest_LDADD = libcommon.la
SocketsTest_LDFLAGS = -lpthread
TimevalTest_SOURCES = TimevalTest.cpp
TimevalTest_LDADD = libcommon.la
VectorTest_SOURCES = VectorTest.cpp
VectorTest_LDADD = libcommon.la
RegexpTest_SOURCES = RegexpTest.cpp
RegexpTest_LDADD = libcommon.la
ConfigurationTest_SOURCES = ConfigurationTest.cpp
ConfigurationTest_LDADD = libcommon.la $(SQLITE_LA)
LogTest_SOURCES = LogTest.cpp
LogTest_LDADD = libcommon.la $(SQLITE_LA)
F16Test_SOURCES = F16Test.cpp
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.common $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu CommonLibs/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu CommonLibs/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES)
$(CXXLINK) $(libcommon_la_LDFLAGS) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
BitVectorTest$(EXEEXT): $(BitVectorTest_OBJECTS) $(BitVectorTest_DEPENDENCIES)
@rm -f BitVectorTest$(EXEEXT)
$(CXXLINK) $(BitVectorTest_LDFLAGS) $(BitVectorTest_OBJECTS) $(BitVectorTest_LDADD) $(LIBS)
ConfigurationTest$(EXEEXT): $(ConfigurationTest_OBJECTS) $(ConfigurationTest_DEPENDENCIES)
@rm -f ConfigurationTest$(EXEEXT)
$(CXXLINK) $(ConfigurationTest_LDFLAGS) $(ConfigurationTest_OBJECTS) $(ConfigurationTest_LDADD) $(LIBS)
F16Test$(EXEEXT): $(F16Test_OBJECTS) $(F16Test_DEPENDENCIES)
@rm -f F16Test$(EXEEXT)
$(CXXLINK) $(F16Test_LDFLAGS) $(F16Test_OBJECTS) $(F16Test_LDADD) $(LIBS)
InterthreadTest$(EXEEXT): $(InterthreadTest_OBJECTS) $(InterthreadTest_DEPENDENCIES)
@rm -f InterthreadTest$(EXEEXT)
$(CXXLINK) $(InterthreadTest_LDFLAGS) $(InterthreadTest_OBJECTS) $(InterthreadTest_LDADD) $(LIBS)
LogTest$(EXEEXT): $(LogTest_OBJECTS) $(LogTest_DEPENDENCIES)
@rm -f LogTest$(EXEEXT)
$(CXXLINK) $(LogTest_LDFLAGS) $(LogTest_OBJECTS) $(LogTest_LDADD) $(LIBS)
RegexpTest$(EXEEXT): $(RegexpTest_OBJECTS) $(RegexpTest_DEPENDENCIES)
@rm -f RegexpTest$(EXEEXT)
$(CXXLINK) $(RegexpTest_LDFLAGS) $(RegexpTest_OBJECTS) $(RegexpTest_LDADD) $(LIBS)
SocketsTest$(EXEEXT): $(SocketsTest_OBJECTS) $(SocketsTest_DEPENDENCIES)
@rm -f SocketsTest$(EXEEXT)
$(CXXLINK) $(SocketsTest_LDFLAGS) $(SocketsTest_OBJECTS) $(SocketsTest_LDADD) $(LIBS)
TimevalTest$(EXEEXT): $(TimevalTest_OBJECTS) $(TimevalTest_DEPENDENCIES)
@rm -f TimevalTest$(EXEEXT)
$(CXXLINK) $(TimevalTest_LDFLAGS) $(TimevalTest_OBJECTS) $(TimevalTest_LDADD) $(LIBS)
VectorTest$(EXEEXT): $(VectorTest_OBJECTS) $(VectorTest_DEPENDENCIES)
@rm -f VectorTest$(EXEEXT)
$(CXXLINK) $(VectorTest_LDFLAGS) $(VectorTest_OBJECTS) $(VectorTest_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitVector.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitVectorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Configuration.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigurationTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/F16Test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InterthreadTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LinkedLists.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RegexpTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sockets.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketsTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Threads.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Timeval.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimevalTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VectorTest.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
ctags distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

111
MemoryLeak.h Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright 2011 Range Networks, Inc.
* All Rights Reserved.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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.
*/
#ifndef _MEMORYLEAK_
#define _MEMORYLEAK_ 1
#include <map>
#include "ScalarTypes.h"
#include "Logger.h"
namespace Utils {
struct MemStats {
// Enumerates the classes that are checked.
// Redundancies are ok, for example, we check BitVector and also
// several descendants of BitVector.
enum MemoryNames {
mZeroIsUnused,
mVector,
mVectorData,
mBitVector,
mByteVector,
mByteVectorData,
mRLCRawBlock,
mRLCUplinkDataBlock,
mRLCMessage,
mRLCMsgPacketDownlinkDummyControlBlock, // Redundant with RLCMessage
mTBF,
mLlcEngine,
mSgsnDownlinkMsg,
mRachInfo,
mPdpPdu,
mFECDispatchInfo,
mL3Frame,
msignalVector,
mSoftVector,
mScramblingCode,
mURlcDownSdu,
mURlcPdu,
// Must be last:
mMax,
};
int mMemTotal[mMax]; // In elements, not bytes.
int mMemNow[mMax];
const char *mMemName[mMax];
MemStats();
void memChkNew(MemoryNames memIndex, const char *id);
void memChkDel(MemoryNames memIndex, const char *id);
void text(std::ostream &os);
// We would prefer to use an unordered_map, but that requires special compile switches.
// What a super great language.
typedef std::map<std::string,Int_z> MemMapType;
MemMapType mMemMap;
};
extern struct MemStats gMemStats;
extern int gMemLeakDebug;
// This is a memory leak detector.
// Use by putting RN_MEMCHKNEW and RN_MEMCHKDEL in class constructors/destructors,
// or use the DEFINE_MEMORY_LEAK_DETECTOR class and add the defined class
// as an ancestor to the class to be memory leak checked.
struct MemLabel {
std::string mccKey;
virtual ~MemLabel() {
Int_z &tmp = Utils::gMemStats.mMemMap[mccKey]; tmp = tmp - 1;
}
};
#if RN_DISABLE_MEMORY_LEAK_TEST
#define RN_MEMCHKNEW(type)
#define RN_MEMCHKDEL(type)
#define RN_MEMLOG(type,ptr)
#define DEFINE_MEMORY_LEAK_DETECTOR_CLASS(subClass,checkerClass) \
struct checkerClass {};
#else
#define RN_MEMCHKNEW(type) { Utils::gMemStats.memChkNew(Utils::MemStats::m##type,#type); }
#define RN_MEMCHKDEL(type) { Utils::gMemStats.memChkDel(Utils::MemStats::m##type,#type); }
#define RN_MEMLOG(type,ptr) { \
static std::string key = format("%s_%s:%d",#type,__FILE__,__LINE__); \
(ptr)->/* MemCheck##type:: */ mccKey = key; \
Utils::gMemStats.mMemMap[key]++; \
}
// TODO: The above assumes that checkclass is MemCheck ## subClass
#define DEFINE_MEMORY_LEAK_DETECTOR_CLASS(subClass,checkerClass) \
struct checkerClass : public virtual Utils::MemLabel { \
checkerClass() { RN_MEMCHKNEW(subClass); } \
virtual ~checkerClass() { \
RN_MEMCHKDEL(subClass); \
} \
};
#endif
} // namespace Utils
#endif

145
Reporting.cpp Normal file
View File

@ -0,0 +1,145 @@
/**@file Module for performance-reporting mechanisms. */
/*
* Copyright 2012 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Reporting.h"
#include "Logger.h"
#include <stdio.h>
#include <string.h>
static const char* createReportingTable = {
"CREATE TABLE IF NOT EXISTS REPORTING ("
"NAME TEXT UNIQUE NOT NULL, "
"VALUE INTEGER DEFAULT 0, "
"CLEAREDTIME INTEGER NOT NULL, "
"UPDATETIME INTEGER DEFAULT 0 "
")"
};
ReportingTable::ReportingTable(const char* filename)
{
gLogEarly(LOG_INFO | mFacility, "opening reporting table from path %s", filename);
// Connect to the database.
int rc = sqlite3_open(filename,&mDB);
if (rc) {
gLogEarly(LOG_EMERG | mFacility, "cannot open reporting database at %s, error message: %s", filename, sqlite3_errmsg(mDB));
sqlite3_close(mDB);
mDB = NULL;
return;
}
// Create the table, if needed.
if (!sqlite3_command(mDB,createReportingTable)) {
gLogEarly(LOG_EMERG | mFacility, "cannot create reporting table in database at %s, error message: %s", filename, sqlite3_errmsg(mDB));
}
}
bool ReportingTable::create(const char* paramName)
{
char cmd[200];
sprintf(cmd,"INSERT OR IGNORE INTO REPORTING (NAME,CLEAREDTIME) VALUES (\"%s\",%ld)", paramName, time(NULL));
if (!sqlite3_command(mDB,cmd)) {
gLogEarly(LOG_CRIT|mFacility, "cannot create reporting parameter %s, error message: %s", paramName, sqlite3_errmsg(mDB));
return false;
}
return true;
}
bool ReportingTable::incr(const char* paramName)
{
char cmd[200];
sprintf(cmd,"UPDATE REPORTING SET VALUE=VALUE+1, UPDATETIME=%ld WHERE NAME=\"%s\"", time(NULL), paramName);
if (!sqlite3_command(mDB,cmd)) {
gLogEarly(LOG_CRIT|mFacility, "cannot increment reporting parameter %s, error message: %s", paramName, sqlite3_errmsg(mDB));
return false;
}
return true;
}
bool ReportingTable::max(const char* paramName, unsigned newVal)
{
char cmd[200];
sprintf(cmd,"UPDATE REPORTING SET VALUE=MAX(VALUE,%u), UPDATETIME=%ld WHERE NAME=\"%s\"", newVal, time(NULL), paramName);
if (!sqlite3_command(mDB,cmd)) {
gLogEarly(LOG_CRIT|mFacility, "cannot maximize reporting parameter %s, error message: %s", paramName, sqlite3_errmsg(mDB));
return false;
}
return true;
}
bool ReportingTable::clear(const char* paramName)
{
char cmd[200];
sprintf(cmd,"UPDATE REPORTING SET VALUE=0, UPDATETIME=0, CLEAREDTIME=%ld WHERE NAME=\"%s\"", time(NULL), paramName);
if (!sqlite3_command(mDB,cmd)) {
gLogEarly(LOG_CRIT|mFacility, "cannot clear reporting parameter %s, error message: %s", paramName, sqlite3_errmsg(mDB));
return false;
}
return true;
}
bool ReportingTable::create(const char* baseName, unsigned minIndex, unsigned maxIndex)
{
size_t sz = strlen(baseName);
for (unsigned i = minIndex; i<=maxIndex; i++) {
char name[sz+10];
sprintf(name,"%s.%u",baseName,i);
if (!create(name)) return false;
}
return true;
}
bool ReportingTable::incr(const char* baseName, unsigned index)
{
char name[strlen(baseName)+10];
sprintf(name,"%s.%u",baseName,index);
return incr(name);
}
bool ReportingTable::max(const char* baseName, unsigned index, unsigned newVal)
{
char name[strlen(baseName)+10];
sprintf(name,"%s.%u",baseName,index);
return max(name,newVal);
}
bool ReportingTable::clear(const char* baseName, unsigned index)
{
char name[strlen(baseName)+10];
sprintf(name,"%s.%u",baseName,index);
return clear(name);
}

86
Reporting.h Normal file
View File

@ -0,0 +1,86 @@
/**@file Module for performance-reporting mechanisms. */
/*
* Copyright 2012 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REPORTING_H
#define REPORTING_H
#include <sqlite3util.h>
#include <ostream>
/**
Collect performance statistics into a database.
Parameters are counters or max/min trackers, all integer.
*/
class ReportingTable {
private:
sqlite3* mDB; ///< database connection
int mFacility; ///< rsyslogd facility
public:
/**
Open the database connection;
create the table if it does not exist yet.
*/
ReportingTable(const char* filename);
/** Create a new parameter. */
bool create(const char* paramName);
/** Create an indexed parameter set. */
bool create(const char* baseBame, unsigned minIndex, unsigned maxIndex);
/** Increment a counter. */
bool incr(const char* paramName);
/** Increment an indexed counter. */
bool incr(const char* baseName, unsigned index);
/** Take a max of a parameter. */
bool max(const char* paramName, unsigned newVal);
/** Take a max of an indexed parameter. */
bool max(const char* paramName, unsigned index, unsigned newVal);
/** Clear a value. */
bool clear(const char* paramName);
/** Clear an indexed value. */
bool clear(const char* paramName, unsigned index);
/** Dump the database to a stream. */
void dump(std::ostream&) const;
};
#endif
// vim: ts=4 sw=4

136
ScalarTypes.h Normal file
View File

@ -0,0 +1,136 @@
/*
* Copyright 2011 Range Networks, Inc.
* All Rights Reserved.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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.
*/
#ifndef SCALARTYPES_H
#define SCALARTYPES_H
#include <iostream> // For size_t
#include <stdint.h>
//#include "GSMCommon.h" // Was included for Z100Timer
// We dont bother to define *= /= etc.; you'll have to convert: a*=b; to: a=a*b;
#define _INITIALIZED_SCALAR_BASE_FUNCS(Classname,Basetype,Init) \
Classname() : value(Init) {} \
Classname(Basetype wvalue) { value = wvalue; } /* Can set from basetype. */ \
operator Basetype(void) const { return value; } /* Converts from basetype. */ \
Basetype operator=(Basetype wvalue) { return value = wvalue; } \
Basetype* operator&() { return &value; }
#define _INITIALIZED_SCALAR_ARITH_FUNCS(Basetype) \
Basetype operator++() { return ++value; } \
Basetype operator++(int) { return value++; } \
Basetype operator--() { return --value; } \
Basetype operator--(int) { return value--; } \
Basetype operator+=(Basetype wvalue) { return value = value + wvalue; } \
Basetype operator-=(Basetype wvalue) { return value = value - wvalue; }
#define _INITIALIZED_SCALAR_FUNCS(Classname,Basetype,Init) \
_INITIALIZED_SCALAR_BASE_FUNCS(Classname,Basetype,Init) \
_INITIALIZED_SCALAR_ARITH_FUNCS(Basetype)
#define _DECLARE_SCALAR_TYPE(Classname_i,Classname_z,Basetype) \
template <Basetype Init> \
struct Classname_i { \
Basetype value; \
_INITIALIZED_SCALAR_FUNCS(Classname_i,Basetype,Init) \
}; \
typedef Classname_i<0> Classname_z;
// Usage:
// Where 'classname' is one of the types listed below, then:
// classname_z specifies a zero initialized type;
// classname_i<value> initializes the type to the specified value.
// We also define Float_z.
_DECLARE_SCALAR_TYPE(Int_i, Int_z, int)
_DECLARE_SCALAR_TYPE(Char_i, Char_z, signed char)
_DECLARE_SCALAR_TYPE(Int16_i, Int16_z, int16_t)
_DECLARE_SCALAR_TYPE(Int32_i, Int32_z, int32_t)
_DECLARE_SCALAR_TYPE(UInt_i, UInt_z, unsigned)
_DECLARE_SCALAR_TYPE(UChar_i, UChar_z, unsigned char)
_DECLARE_SCALAR_TYPE(UInt16_i, UInt16_z, uint16_t)
_DECLARE_SCALAR_TYPE(UInt32_i, UInt32_z, uint32_t)
_DECLARE_SCALAR_TYPE(Size_t_i, Size_t_z, size_t)
// Bool is special because it cannot accept some arithmetic funcs
//_DECLARE_SCALAR_TYPE(Bool_i, Bool_z, bool)
template <bool Init>
struct Bool_i {
bool value;
_INITIALIZED_SCALAR_BASE_FUNCS(Bool_i,bool,Init)
};
typedef Bool_i<0> Bool_z;
// float is special, because C++ does not permit the template initalization:
struct Float_z {
float value;
_INITIALIZED_SCALAR_FUNCS(Float_z,float,0)
};
struct Double_z {
double value;
_INITIALIZED_SCALAR_FUNCS(Double_z,double,0)
};
class ItemWithValueAndWidth {
public:
virtual unsigned getValue() const = 0;
virtual unsigned getWidth() const = 0;
};
// A Range Networks Field with a specified width.
// See RLCMessages.h for examples.
template <int Width=32, unsigned Init=0>
class Field_i : public ItemWithValueAndWidth
{
public:
unsigned value;
_INITIALIZED_SCALAR_FUNCS(Field_i,unsigned,Init)
unsigned getWidth() const { return Width; }
unsigned getValue() const { return value; }
};
// Synonym for Field_i, but no way to do it.
template <int Width, unsigned Init=0>
class Field_z : public ItemWithValueAndWidth
{
public:
unsigned value;
_INITIALIZED_SCALAR_FUNCS(Field_z,unsigned,Init)
unsigned getWidth() const { return Width; }
unsigned getValue() const { return value; }
};
// This is an uninitialized field.
template <int Width=32, unsigned Init=0>
class Field : public ItemWithValueAndWidth
{
public:
unsigned value;
_INITIALIZED_SCALAR_FUNCS(Field,unsigned,Init)
unsigned getWidth() const { return Width; }
unsigned getValue() const { return value; }
};
// A Z100Timer with an initial value specified.
//template <int Init>
//class Z100Timer_i : public GSM::Z100Timer {
// public:
// Z100Timer_i() : GSM::Z100Timer(Init) {}
//};
#endif

View File

@ -25,6 +25,7 @@
#include <config.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
@ -64,13 +65,40 @@ bool resolveAddress(struct sockaddr_in *address, const char *host, unsigned shor
assert(address);
assert(host);
// FIXME -- Need to ignore leading/trailing spaces in hostname.
struct hostent *hp = gethostbyname(host);
if (hp==NULL) {
CERR("WARNING -- gethostbyname() failed for " << host << ", " << hstrerror(h_errno));
struct hostent *hp;
int h_errno_local;
#ifdef HAVE_GETHOSTBYNAME2_R
struct hostent hostData;
char tmpBuffer[2048];
// There are different flavors of gethostbyname_r(), but
// latest Linux use the following form:
if (gethostbyname2_r(host, AF_INET, &hostData, tmpBuffer, sizeof(tmpBuffer), &hp, &h_errno_local)!=0) {
CERR("WARNING -- gethostbyname2_r() failed for " << host << ", " << hstrerror(h_errno_local));
return false;
}
address->sin_family = AF_INET;
bcopy(hp->h_addr, &(address->sin_addr), hp->h_length);
#else
static Mutex sGethostbynameMutex;
// gethostbyname() is NOT thread-safe, so we should use a mutex here.
// Ideally it should be a global mutex for all non thread-safe socket
// operations and it should protect access to variables such as
// global h_errno.
sGethostbynameMutex.lock();
hp = gethostbyname(host);
h_errno_local = h_errno;
sGethostbynameMutex.unlock();
#endif
if (hp==NULL) {
CERR("WARNING -- gethostbyname() failed for " << host << ", " << hstrerror(h_errno_local));
return false;
}
if (hp->h_addrtype != AF_INET) {
CERR("WARNING -- gethostbyname() resolved " << host << " to something other then AF_INET");
return false;
}
address->sin_family = hp->h_addrtype;
assert(sizeof(address->sin_addr) == hp->h_length);
memcpy(&(address->sin_addr), hp->h_addr_list[0], hp->h_length);
address->sin_port = htons(port);
return true;
}
@ -79,7 +107,7 @@ bool resolveAddress(struct sockaddr_in *address, const char *host, unsigned shor
DatagramSocket::DatagramSocket()
{
bzero(mDestination,sizeof(mDestination));
memset(mDestination, 0, sizeof(mDestination));
}
@ -179,6 +207,7 @@ int DatagramSocket::read(char* buffer)
int DatagramSocket::read(char* buffer, unsigned timeout)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(mSocketFD,&fds);
struct timeval tv;
tv.tv_sec = timeout/1000;
@ -189,7 +218,8 @@ int DatagramSocket::read(char* buffer, unsigned timeout)
throw SocketError();
}
if (sel==0) return -1;
return read(buffer);
if (FD_ISSET(mSocketFD,&fds)) return read(buffer);
return -1;
}
@ -229,6 +259,11 @@ void UDPSocket::open(unsigned short localPort)
throw SocketError();
}
// pat added: This lets the socket be reused immediately, which is needed if OpenBTS crashes.
int on = 1;
setsockopt(mSocketFD, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
// bind
struct sockaddr_in address;
size_t length = sizeof(address);

View File

@ -107,8 +107,9 @@ void Thread::start(void *(*task)(void*), void *arg)
{
assert(mThread==((pthread_t)0));
bool res;
res = pthread_attr_init(&mAttrib);
assert(!res);
// (pat) Moved initialization to constructor to avoid crash in destructor.
//res = pthread_attr_init(&mAttrib);
//assert(!res);
res = pthread_attr_setstacksize(&mAttrib, mStackSize);
assert(!res);
res = pthread_create(&mThread, &mAttrib, task, arg);

View File

@ -29,6 +29,7 @@
#include <pthread.h>
#include <iostream>
#include <assert.h>
#include <unistd.h>
class Mutex;
@ -80,6 +81,8 @@ class Mutex {
void lock() { pthread_mutex_lock(&mMutex); }
bool trylock() { return pthread_mutex_trylock(&mMutex)==0; }
void unlock() { pthread_mutex_unlock(&mMutex); }
friend class Signal;
@ -152,12 +155,16 @@ class Thread {
public:
/** Create a thread in a non-running state. */
Thread(size_t wStackSize = (65536*4)):mThread((pthread_t)0) { mStackSize=wStackSize;}
Thread(size_t wStackSize = (65536*4)):mThread((pthread_t)0) {
pthread_attr_init(&mAttrib); // (pat) moved this here.
mStackSize=wStackSize;
}
/**
Destroy the Thread.
It should be stopped and joined.
*/
// (pat) If the Thread is destroyed without being started, then mAttrib is undefined. Oops.
~Thread() { pthread_attr_destroy(&mAttrib); }
@ -165,7 +172,7 @@ class Thread {
void start(void *(*task)(void*), void *arg);
/** Join a thread that will stop on its own. */
void join() { int s = pthread_join(mThread,NULL); assert(!s); }
void join() { int s = pthread_join(mThread,NULL); assert(!s); mThread = 0; }
};

View File

@ -71,8 +71,8 @@ double Timeval::seconds() const
long Timeval::delta(const Timeval& other) const
{
// 2^31 milliseconds is just over 4 years.
long deltaS = other.sec() - sec();
long deltaUs = other.usec() - usec();
int32_t deltaS = other.sec() - sec();
int32_t deltaUs = other.usec() - usec();
return 1000*deltaS + deltaUs/1000;
}

View File

@ -29,6 +29,7 @@
#include <stdint.h>
#include "sys/time.h"
#include <iostream>
#include <unistd.h>

View File

@ -1,27 +1,4 @@
/*
* Copyright 2011 Free Software Foundation, Inc.
*
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Copyright 2011, Range Networks, Inc. */
#include <URLEncode.h>
#include <string>
@ -35,7 +12,7 @@ string URLEncode(const string &c)
{
static const char *digits = "01234567890ABCDEF";
string retVal="";
for (int i=0; i<c.length(); i++)
for (size_t i=0; i<c.length(); i++)
{
const char ch = c[i];
if (isalnum(ch) || strchr("-_.!~'()",ch)) {

211
Utils.cpp Normal file
View File

@ -0,0 +1,211 @@
/*
* Copyright 2011 Range Networks, Inc.
* All Rights Reserved.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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.
*/
#include <unistd.h> // For usleep
#include <sys/time.h> // For gettimeofday
#include <stdio.h> // For vsnprintf
#include <ostream> // For ostream
#include <sstream> // For ostringstream
#include <string.h> // For strcpy
//#include "GSMCommon.h"
#include "Utils.h"
#include "MemoryLeak.h"
namespace Utils {
MemStats gMemStats;
int gMemLeakDebug = 0;
MemStats::MemStats()
{
memset(mMemNow,0,sizeof(mMemNow));
memset(mMemTotal,0,sizeof(mMemTotal));
memset(mMemName,0,sizeof(mMemName));
}
void MemStats::text(std::ostream &os)
{
os << "Structs current total:\n";
for (int i = 0; i < mMax; i++) {
os << "\t" << (mMemName[i] ? mMemName[i] : "unknown") << " " << mMemNow[i] << " " << mMemTotal[i] << "\n";
}
}
void MemStats::memChkNew(MemoryNames memIndex, const char *id)
{
/*std::cout << "new " #type "\n";*/
mMemNow[memIndex]++;
mMemTotal[memIndex]++;
mMemName[memIndex] = id;
}
void MemStats::memChkDel(MemoryNames memIndex, const char *id)
{
/*std::cout << "del " #type "\n";*/
mMemNow[memIndex]--;
if (mMemNow[memIndex] < 0) {
LOG(ERR) << "Memory underflow on type "<<id;
if (gMemLeakDebug) assert(0);
mMemNow[memIndex] += 100; // Prevent another message for a while.
}
}
std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
{
return os << ss.str();
}
std::ostream &osprintf(std::ostream &os, const char *fmt, ...)
{
va_list ap;
char buf[300];
va_start(ap,fmt);
int n = vsnprintf(buf,300,fmt,ap);
va_end(ap);
if (n >= (300-4)) { strcpy(&buf[(300-4)],"..."); }
os << buf;
return os;
}
std::string format(const char *fmt, ...)
{
va_list ap;
char buf[300];
va_start(ap,fmt);
int n = vsnprintf(buf,300,fmt,ap);
va_end(ap);
if (n >= (300-4)) { strcpy(&buf[(300-4)],"..."); }
return std::string(buf);
}
// Return time in seconds with high resolution.
// Note: In the past I found this to be a surprisingly expensive system call in linux.
double timef()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_usec / 1000000.0 + tv.tv_sec;
}
const std::string timestr()
{
struct timeval tv;
struct tm tm;
gettimeofday(&tv,NULL);
localtime_r(&tv.tv_sec,&tm);
unsigned tenths = tv.tv_usec / 100000; // Rounding down is ok.
return format(" %02d:%02d:%02d.%1d",tm.tm_hour,tm.tm_min,tm.tm_sec,tenths);
}
// High resolution sleep for the specified time.
// Return FALSE if time is already past.
void sleepf(double howlong)
{
if (howlong <= 0.00001) return; // Less than 10 usecs, forget it.
usleep((useconds_t) (1000000.0 * howlong));
}
//bool sleepuntil(double untilwhen)
//{
//double now = timef();
//double howlong = untilwhen - now; // Fractional time in seconds.
// We are not worrying about overflow because all times should be in the near future.
//if (howlong <= 0.00001) return false; // Less than 10 usecs, forget it.
//sleepf(sleeptime);
//}
std::string Text2Str::str() const
{
std::ostringstream ss;
text(ss);
return ss.str();
}
std::ostream& operator<<(std::ostream& os, const Text2Str *val)
{
std::ostringstream ss;
if (val) {
val->text(ss);
os << ss.str();
} else {
os << "(null)";
}
return os;
}
// Greatest Common Denominator.
// This is by Doug Brown.
int gcd(int x, int y)
{
if (x > y) {
return x % y == 0 ? y : gcd(y, x % y);
} else {
return y % x == 0 ? x : gcd(x, y % x);
}
}
// Split a C string into an argc,argv array in place; the input string is modified.
// Returns argc, and places results in argv, up to maxargc elements.
// The final argv receives the rest of the input string from maxargc on,
// even if it contains additional splitchars.
// The correct idiom for use is to make a copy of your string, like this:
// char *copy = strcpy((char*)alloca(the_string.length()+1),the_string.c_str());
// char *argv[2];
// int argc = cstrSplit(copy,argv,2,NULL);
// If you want to detect the error of too many arguments, add 1 to argv, like this:
// char *argv[3];
// int argc = cstrSplit(copy,argv,3,NULL);
// if (argc == 3) { error("too many arguments"; }
int cstrSplit(char *in, char **pargv,int maxargc, const char *splitchars)
{
if (splitchars == NULL) { splitchars = " \t\r\n"; } // Default is any space.
int argc = 0;
while (argc < maxargc) {
while (*in && strchr(splitchars,*in)) {in++;} // scan past any splitchars
if (! *in) return argc; // return if finished.
pargv[argc++] = in; // save ptr to start of arg.
in = strpbrk(in,splitchars); // go to end of arg.
if (!in) return argc; // return if finished.
*in++ = 0; // zero terminate this arg.
}
return argc;
}
std::ostream& operator<<(std::ostream& os, const Statistic<int> &stat) { stat.text(os); return os; }
std::ostream& operator<<(std::ostream& os, const Statistic<unsigned> &stat) { stat.text(os); return os; }
std::ostream& operator<<(std::ostream& os, const Statistic<float> &stat) { stat.text(os); return os; }
std::ostream& operator<<(std::ostream& os, const Statistic<double> &stat) { stat.text(os); return os; }
std::string replaceAll(const std::string input, const std::string search, const std::string replace)
{
std::string output = input;
int index = 0;
while (true) {
index = output.find(search, index);
if (index == std::string::npos) {
break;
}
output.replace(index, replace.length(), replace);
index += replace.length();
}
return output;
}
};

148
Utils.h Normal file
View File

@ -0,0 +1,148 @@
/*
* Copyright 2011 Range Networks, Inc.
* All Rights Reserved.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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.
*/
#ifndef GPRSUTILS_H
#define GPRSUTILS_H
#include <stdint.h>
#include <stdarg.h>
#include <string>
#include <string.h>
#include <math.h> // for sqrtf
#include "Logger.h"
namespace Utils {
extern double timef(); // high resolution time
extern const std::string timestr(); // A timestamp to print in messages.
extern void sleepf(double howlong); // high resolution sleep
extern int gcd(int x, int y);
// It is irritating to create a string just to interface to the brain-damaged
// C++ stream class, but this is only used for debug messages.
std::string format(const char *fmt, ...) __attribute__((format (printf,1,2)));
int cstrSplit(char *in, char **pargv,int maxargc, const char *splitchars=NULL);
// For classes with a text() function, provide a function to return a String,
// and also a standard << stream function that takes a pointer to the object.
// We dont provide the function that takes a reference to the object
// because it is too highly overloaded and generally doesnt work.
class Text2Str {
public:
virtual void text(std::ostream &os) const = 0;
std::string str() const;
};
std::ostream& operator<<(std::ostream& os, const Text2Str *val);
#if 0
// Generic Activity Timer. Lots of controls to make everybody happy.
class ATimer {
double mStart;
//bool mActive;
double mLimitTime;
public:
ATimer() : mStart(0), mLimitTime(0) { }
ATimer(double wLimitTime) : mStart(0), mLimitTime(wLimitTime) { }
void start() { mStart=timef(); }
void stop() { mStart=0; }
bool active() { return !!mStart; }
double elapsed() { return timef() - mStart; }
bool expired() { return elapsed() > mLimitTime; }
};
#endif
struct BitSet {
unsigned mBits;
void setBit(unsigned whichbit) { mBits |= 1<<whichbit; }
void clearBit(unsigned whichbit) { mBits &= ~(1<<whichbit); }
unsigned getBit(unsigned whichbit) const { return mBits & (1<<whichbit); }
bool isSet(unsigned whichbit) const { return mBits & (1<<whichbit); }
unsigned bits() const { return mBits; }
operator int(void) const { return mBits; }
BitSet() { mBits = 0; }
};
// Store current, min, max and compute running average and standard deviation.
template<class Type> struct Statistic {
Type mCurrent, mMin, mMax; // min,max optional initialization so you can print before adding any values.
unsigned mCnt;
double mSum;
//double mSum2; // sum of squares.
// (Type) cast needed in case Type is an enum, stupid language.
Statistic() : mCurrent((Type)0), mMin((Type)0), mMax((Type)0), mCnt(0), mSum(0) /*,mSum2(0)*/ {}
// Set the current value and add a statisical point.
void addPoint(Type val) {
mCurrent = val;
if (mCnt == 0 || val < mMin) {mMin = val;}
if (mCnt == 0 || val > mMax) {mMax = val;}
mCnt++;
mSum += val;
//mSum2 += val * val;
}
Type getCurrent() const { // Return current value.
return mCnt ? mCurrent : 0;
}
double getAvg() const { // Return average.
return mCnt==0 ? 0 : mSum/mCnt;
};
//float getSD() const { // Return standard deviation. Use low precision square root function.
// return mCnt==0 ? 0 : sqrtf(mCnt * mSum2 - mSum*mSum) / mCnt;
//}
void text(std::ostream &os) const { // Print everything in parens.
os << "("<<mCurrent;
if (mMin != mMax) { // Not point in printing all this stuff if min == max.
os <<LOGVAR2("min",mMin)<<LOGVAR2("max",mMax)<<LOGVAR2("avg",getAvg());
if (mCnt <= 999999) {
os <<LOGVAR2("N",mCnt);
} else { // Shorten this up:
char buf[10], *ep;
sprintf(buf,"%.3g",round(mCnt));
if ((ep = strchr(buf,'e')) && ep[1] == '+') { strcpy(ep+1,ep+2); }
os << LOGVAR2("N",buf);
}
// os<<LOGVAR2("sd",getSD()) standard deviation not interesting
}
os << ")";
// " min="<<mMin <<" max="<<mMax <<format(" avg=%4g sd=%3g)",getAvg(),getSD());
}
// Not sure if this works:
//std::string statStr() const {
// return (std::string)mCurrent + " min=" + (std::string) mMin +" max="+(string)mMax+ format(" avg=%4g sd=%3g",getAvg(),getSD());
//}
};
// This I/O mechanism is so dumb:
std::ostream& operator<<(std::ostream& os, const Statistic<int> &stat);
std::ostream& operator<<(std::ostream& os, const Statistic<unsigned> &stat);
std::ostream& operator<<(std::ostream& os, const Statistic<float> &stat);
std::ostream& operator<<(std::ostream& os, const Statistic<double> &stat);
// Yes, they botched and left this out:
std::ostream& operator<<(std::ostream& os, std::ostringstream& ss);
std::ostream &osprintf(std::ostream &os, const char *fmt, ...) __attribute__((format (printf,2,3)));
std::string replaceAll(const std::string input, const std::string search, const std::string replace);
}; // namespace
using namespace Utils;
#endif

View File

@ -32,6 +32,10 @@
#include <string.h>
#include <iostream>
#include <assert.h>
// We cant use Logger.h in this file...
extern int gVectorDebug;
#define BVDEBUG(msg) if (gVectorDebug) {std::cout << msg;}
/**
@ -59,6 +63,14 @@ template <class T> class Vector {
public:
/****
char *inspect() {
static char buf[100];
sprintf(buf," mData=%p mStart=%p mEnd=%p ",mData,mStart,mEnd);
return buf;
}
***/
/** Return the size of the Vector. */
size_t size() const
{
@ -246,6 +258,7 @@ template <class T> class Vector {
T* begin() { return mStart; }
const T* end() const { return mEnd; }
T* end() { return mEnd; }
bool isOwner() { return !!mData; } // Do we own any memory ourselves?
//@}

View File

@ -28,6 +28,10 @@
#include "Vector.h"
#include <iostream>
// We must have a gConfig now to include Vector.
#include "Configuration.h"
ConfigurationTable gConfig;
using namespace std;
typedef Vector<int> TestVector;

154
sqlite3util.cpp Normal file
View File

@ -0,0 +1,154 @@
/*
* Copyright 2010 Kestrel Signal Processing, Inc.
* All rights reserved.
*/
#include "sqlite3.h"
#include "sqlite3util.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
// Wrappers to sqlite operations.
// These will eventually get moved to commonlibs.
int sqlite3_prepare_statement(sqlite3* DB, sqlite3_stmt **stmt, const char* query)
{
int src = SQLITE_BUSY;
while (src==SQLITE_BUSY) {
src = sqlite3_prepare_v2(DB,query,strlen(query),stmt,NULL);
if (src==SQLITE_BUSY) {
usleep(100000);
}
}
if (src) {
fprintf(stderr,"sqlite3_prepare_v2 failed for \"%s\": %s\n",query,sqlite3_errmsg(DB));
sqlite3_finalize(*stmt);
}
return src;
}
int sqlite3_run_query(sqlite3* DB, sqlite3_stmt *stmt)
{
int src = SQLITE_BUSY;
while (src==SQLITE_BUSY) {
src = sqlite3_step(stmt);
if (src==SQLITE_BUSY) {
usleep(100000);
}
}
if ((src!=SQLITE_DONE) && (src!=SQLITE_ROW)) {
fprintf(stderr,"sqlite3_run_query failed: %s: %s\n", sqlite3_sql(stmt), sqlite3_errmsg(DB));
}
return src;
}
bool sqlite3_exists(sqlite3* DB, const char *tableName,
const char* keyName, const char* keyData)
{
size_t stringSize = 100 + strlen(tableName) + strlen(keyName) + strlen(keyData);
char query[stringSize];
sprintf(query,"SELECT * FROM %s WHERE %s == \"%s\"",tableName,keyName,keyData);
// Prepare the statement.
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
// Read the result.
int src = sqlite3_run_query(DB,stmt);
sqlite3_finalize(stmt);
// Anything there?
return (src == SQLITE_ROW);
}
bool sqlite3_single_lookup(sqlite3* DB, const char *tableName,
const char* keyName, const char* keyData,
const char* valueName, unsigned &valueData)
{
size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + strlen(keyData);
char query[stringSize];
sprintf(query,"SELECT %s FROM %s WHERE %s == \"%s\"",valueName,tableName,keyName,keyData);
// Prepare the statement.
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
// Read the result.
int src = sqlite3_run_query(DB,stmt);
bool retVal = false;
if (src == SQLITE_ROW) {
valueData = (unsigned)sqlite3_column_int64(stmt,0);
retVal = true;
}
sqlite3_finalize(stmt);
return retVal;
}
// This function returns an allocated string that must be free'd by the caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
const char* keyName, const char* keyData,
const char* valueName, char* &valueData)
{
valueData=NULL;
size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + strlen(keyData);
char query[stringSize];
sprintf(query,"SELECT %s FROM %s WHERE %s == \"%s\"",valueName,tableName,keyName,keyData);
// Prepare the statement.
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
// Read the result.
int src = sqlite3_run_query(DB,stmt);
bool retVal = false;
if (src == SQLITE_ROW) {
const char* ptr = (const char*)sqlite3_column_text(stmt,0);
if (ptr) valueData = strdup(ptr);
retVal = true;
}
sqlite3_finalize(stmt);
return retVal;
}
// This function returns an allocated string that must be free'd by tha caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
const char* keyName, unsigned keyData,
const char* valueName, char* &valueData)
{
valueData=NULL;
size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + 20;
char query[stringSize];
sprintf(query,"SELECT %s FROM %s WHERE %s == %u",valueName,tableName,keyName,keyData);
// Prepare the statement.
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
// Read the result.
int src = sqlite3_run_query(DB,stmt);
bool retVal = false;
if (src == SQLITE_ROW) {
const char* ptr = (const char*)sqlite3_column_text(stmt,0);
if (ptr) valueData = strdup(ptr);
retVal = true;
}
sqlite3_finalize(stmt);
return retVal;
}
bool sqlite3_command(sqlite3* DB, const char* query)
{
// Prepare the statement.
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
// Run the query.
int src = sqlite3_run_query(DB,stmt);
sqlite3_finalize(stmt);
return src==SQLITE_DONE;
}

29
sqlite3util.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef SQLITE3UTIL_H
#define SQLITE3UTIL_H
#include <sqlite3.h>
int sqlite3_prepare_statement(sqlite3* DB, sqlite3_stmt **stmt, const char* query);
int sqlite3_run_query(sqlite3* DB, sqlite3_stmt *stmt);
bool sqlite3_single_lookup(sqlite3* DB, const char *tableName,
const char* keyName, const char* keyData,
const char* valueName, unsigned &valueData);
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
const char* keyName, const char* keyData,
const char* valueName, char* &valueData);
// This function returns an allocated string that must be free'd by the caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
const char* keyName, unsigned keyData,
const char* valueName, char* &valueData);
bool sqlite3_exists(sqlite3* DB, const char* tableName,
const char* keyName, const char* keyData);
/** Run a query, ignoring the result; return true on success. */
bool sqlite3_command(sqlite3* DB, const char* query);
#endif