diff --git a/HISTORY.txt b/HISTORY.txt index 41c7052b..6652cdf5 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -5,10 +5,26 @@ key: - new feature * bug fixed o other +6.22 Released 6/11/2015 + - Added an IsWaitingForEvents() method to ReflectServer class, + so that a (user-supplied) watchdog thread can observe when the + ReflectServer is blocked waiting for I/O vs when it is doing + something. + - Added Mika's vc++14 subdirectory, which contains Visual C++ + project files for Visual Studio 2015. + - DataNode::GetAncestorNode() now takes an optional second argument + that tells it what to return if the ancestor node isn't found. + o Added some more Cygwin/MinGW compatibility changes contributed + by Mika Lindqvist. + o Rewrote some of the node-traversal callback methods so that they + no longer pass an integer argument by casting it to (void *). + * Tweaked various files to fix warnings reported by cppcheck 1.69. + * The stdout-display in qt_muscled wasn't read-only. Fixed. + 6.21 Released 5/14/2015 o Merged in Mika Lindqvist's patch to make the StackWalker code use less stack space. - o Merged in Mika Linkdqvist's patches for better Cygwin compatibility. + o Merged in Mika Lindqvist's patches for better Cygwin compatibility. * Made the StackWalker code a bit more robust. * Merged in Mika Lindqvist's patch to the VC++12 projects to link debug builds against the MultiThreadedDebug diff --git a/README.html b/README.html index 4ab1b850..d91612cb 100644 --- a/README.html +++ b/README.html @@ -2,7 +2,7 @@

MUSCLE: Crossbar Server, Portable Messaging and Support Classes

-5/14/2015 v6.21 jaf@meyersound.com

+6/11/2015 v6.22 jaf@meyersound.com

Jeremy Friesner / Meyer Sound Laboratories Inc.

Win32 compatibility contributions by Vitaliy Mikitchenko

C# client code by Wilson Yeung

diff --git a/besupport/admin_gui/MuscleAdminView.h b/besupport/admin_gui/MuscleAdminView.h index 4511250f..dfe1aa8b 100644 --- a/besupport/admin_gui/MuscleAdminView.h +++ b/besupport/admin_gui/MuscleAdminView.h @@ -37,7 +37,7 @@ class MuscleAdminView : public BView { protected: - MuscleAdminView(BMessage* archive); + explicit MuscleAdminView(BMessage* archive); virtual void Update(bool force = false); @@ -64,7 +64,7 @@ class MuscleAdminReplicant : public MuscleAdminView { public: MuscleAdminReplicant(BRect frame, int32 resizingMode, bool inDeskbar = false); - MuscleAdminReplicant(BMessage* archive); + explicit MuscleAdminReplicant(BMessage* archive); virtual ~MuscleAdminReplicant(); static MuscleAdminReplicant* Instantiate(BMessage* archive); diff --git a/html/Beginners Guide.html b/html/Beginners Guide.html index a0514f24..887bdc4d 100644 --- a/html/Beginners Guide.html +++ b/html/Beginners Guide.html @@ -1,7 +1,7 @@

MUSCLE Overview and Beginner's Guide

-

v6.21 / Jeremy Friesner / Meyer Sound Laboratories Inc (jaf@meyersound.com) 5/14/2015

+

v6.22 / Jeremy Friesner / Meyer Sound Laboratories Inc (jaf@meyersound.com) 6/22/2015

Click here for DOxygen class API documentation diff --git a/html/Custom Servers.html b/html/Custom Servers.html index 598fd2d7..d80b8505 100644 --- a/html/Custom Servers.html +++ b/html/Custom Servers.html @@ -1,7 +1,7 @@

Implementing a Custom Server with MUSCLE

-

v6.21 / Jeremy Friesner / Meyer Sound Laboratories Inc / jaf@meyersound.com 5/14/2015

+

v6.22 / Jeremy Friesner / Meyer Sound Laboratories Inc / jaf@meyersound.com 6/11/2015

Introduction

diff --git a/micromessage/MicroMessage.c b/micromessage/MicroMessage.c index 0a1d9ca5..39bd99ef 100644 --- a/micromessage/MicroMessage.c +++ b/micromessage/MicroMessage.c @@ -397,9 +397,7 @@ status_t UMAddData(UMessage * msg, const char * fieldName, uint32 dataType, cons dataPtr += sizeof(uint32); memcpy(dataPtr, dataBytes, numBytes); -#ifdef DISABLED_TO_SHUT_CLANGS_ANALYER_UP - dataPtr += numBytes; -#endif + //dataPtr += numBytes; // commented out to shut Clang static analyzer and cppcheck up IncreaseCurrentFieldDataLength(msg, numDataBytes); return B_NO_ERROR; @@ -528,7 +526,7 @@ void UMIteratorAdvance(UMessageFieldNameIterator * iter) { while(iter->_currentField) { - void * ftptr = GetFieldTypePointer(iter->_currentField); + uint8 * ftptr = GetFieldTypePointer(iter->_currentField); uint32 fieldDataLen = GetFieldDataLength(ftptr); iter->_currentField = ftptr+(sizeof(uint32)+sizeof(uint32)+fieldDataLen); if (iter->_currentField > (iter->_message->_buffer+iter->_message->_numValidBytes)) diff --git a/minimessage/MiniMessage.c b/minimessage/MiniMessage.c index 38382ca7..9b9284a0 100644 --- a/minimessage/MiniMessage.c +++ b/minimessage/MiniMessage.c @@ -786,7 +786,6 @@ status_t MMUnflattenMessage(MMessage * msg, const void * inBuf, uint32 inputBuff { uint32 i, readOffset = 0; const uint8 * buffer = (const uint8 *) inBuf; - const uint8 * dataPtr; /* Read and check protocol version number */ uint32 networkByteOrder, numEntries; @@ -815,6 +814,7 @@ status_t MMUnflattenMessage(MMessage * msg, const void * inBuf, uint32 inputBuff uint32 nameLength, tc, eLength; MMessageField * newField = NULL; MBool doAddField = MTrue; + const uint8 * dataPtr; /* Read entry name length */ if (ReadData(buffer, inputBufferBytes, &readOffset, &networkByteOrder, sizeof(networkByteOrder)) != B_NO_ERROR) return B_ERROR; diff --git a/qtsupport/QMessageTransceiverThread.h b/qtsupport/QMessageTransceiverThread.h index fc5e49d3..9a8f81ba 100644 --- a/qtsupport/QMessageTransceiverThread.h +++ b/qtsupport/QMessageTransceiverThread.h @@ -230,7 +230,7 @@ class QMessageTransceiverThreadPool : public IMessageTransceiverMaster, private * @param maxSessionsPerThread The maximum number of sessions to add to each * thread in the pool. Defaults to 32. */ - QMessageTransceiverThreadPool(uint32 maxSessionsPerThread = 32); + explicit QMessageTransceiverThreadPool(uint32 maxSessionsPerThread = 32); /** Destructor. Deletes all QMessageTransceiverThread objects in the pool. * Any QMessageTransceiverHandlers still attached to those threads will be detached. diff --git a/qtsupport/qt_advanced_example/ThreadedInternalSession.h b/qtsupport/qt_advanced_example/ThreadedInternalSession.h index 8781e791..914b4ade 100644 --- a/qtsupport/qt_advanced_example/ThreadedInternalSession.h +++ b/qtsupport/qt_advanced_example/ThreadedInternalSession.h @@ -17,7 +17,7 @@ class ThreadedInternalSession : public AdvancedThreadWorkerSession, private Thre /** Constructor * @param args This can contain whatever information the thread will find useful when it starts up. */ - ThreadedInternalSession(const MessageRef & args); + explicit ThreadedInternalSession(const MessageRef & args); /** Called during setup. Overridden to start the internal thread running. */ virtual status_t AttachedToServer(); diff --git a/qtsupport/qt_muscled/qt_muscled.cpp b/qtsupport/qt_muscled/qt_muscled.cpp index e8306aa1..aecddcaa 100644 --- a/qtsupport/qt_muscled/qt_muscled.cpp +++ b/qtsupport/qt_muscled/qt_muscled.cpp @@ -22,6 +22,7 @@ MuscledWindow :: MuscledWindow(const char * argv0) : _cpdio(false), _notifier(NU bl->setSpacing(0); _muscledStdoutText = new QPlainTextEdit; + _muscledStdoutText->setReadOnly(true); bl->addWidget(_muscledStdoutText); Queue argv; diff --git a/qtsupport/qt_muscled/qt_muscled.h b/qtsupport/qt_muscled/qt_muscled.h index d008cc57..137e7408 100644 --- a/qtsupport/qt_muscled/qt_muscled.h +++ b/qtsupport/qt_muscled/qt_muscled.h @@ -16,7 +16,7 @@ class MuscledWindow : public QWidget, public AbstractGatewayMessageReceiver Q_OBJECT public: - MuscledWindow(const char * argv0); + explicit MuscledWindow(const char * argv0); virtual ~MuscledWindow(); private slots: diff --git a/qtsupport/qt_muscled_browser/Browser.cpp b/qtsupport/qt_muscled_browser/Browser.cpp index 4786f30c..28c74557 100644 --- a/qtsupport/qt_muscled_browser/Browser.cpp +++ b/qtsupport/qt_muscled_browser/Browser.cpp @@ -21,7 +21,7 @@ using namespace muscle; class NodeTreeWidgetItem : public QTreeWidgetItem { public: - NodeTreeWidgetItem(QTreeWidget * parent) : QTreeWidgetItem(parent, QStringList("/")) {setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);} + explicit NodeTreeWidgetItem(QTreeWidget * parent) : QTreeWidgetItem(parent, QStringList("/")) {setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);} NodeTreeWidgetItem(NodeTreeWidgetItem * parent, const String & name) : QTreeWidgetItem(parent, QStringList(name())), _name(name) {setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);} NodeTreeWidgetItem * GetChildByName(const String & name) diff --git a/reflector/DataNode.cpp b/reflector/DataNode.cpp index 37c12898..3a7b5eeb 100644 --- a/reflector/DataNode.cpp +++ b/reflector/DataNode.cpp @@ -52,7 +52,6 @@ void DataNode :: IncrementSubscriptionRefCount(const String & sessionID, long de if (delta > 0) { - uint32 res = 0; if (_subscribers == NULL) { _subscribers = newnothrow Hashtable; @@ -60,18 +59,18 @@ void DataNode :: IncrementSubscriptionRefCount(const String & sessionID, long de } if (_subscribers) { - (void) _subscribers->Get(&sessionID, res); - (void) _subscribers->Put(&sessionID, res+delta); // I'm not sure how to cleanly handle out-of-mem here?? --jaf + uint32 * pCount = _subscribers->GetOrPut(&sessionID); + if (pCount) (*pCount) += delta; } } else if (delta < 0) { - uint32 res = 0; - if ((_subscribers)&&(_subscribers->Get(&sessionID, res) == B_NO_ERROR)) + uint32 * pCount = _subscribers ? _subscribers->Get(&sessionID) : NULL; + if (pCount) { uint32 decBy = (uint32) -delta; - if (decBy >= res) (void) _subscribers->Remove(&sessionID); - else (void) _subscribers->Put(&sessionID, res-decBy); // out-of-mem shouldn't be possible + if (decBy >= *pCount) (void) _subscribers->Remove(&sessionID); + else (*pCount) -= decBy; } } } @@ -301,7 +300,7 @@ status_t DataNode :: GetNodePath(String & retPath, uint32 startDepth) const char * dynBuf = NULL; const uint32 stackAllocSize = 256; - char stackBuf[stackAllocSize]; // try to do this without a dynamic allocation... + char stackBuf[stackAllocSize] = ""; // try to do this without a dynamic allocation... if (pathLen >= stackAllocSize) // but do a dynamic allocation if we have to (should be rare) { dynBuf = newnothrow_array(char, pathLen+1); diff --git a/reflector/DataNode.h b/reflector/DataNode.h index e76e795c..b8ed7e2a 100644 --- a/reflector/DataNode.h +++ b/reflector/DataNode.h @@ -237,19 +237,20 @@ class DataNode MUSCLE_FINAL_CLASS : public RefCountable, private CountedObject(this); while(r->GetParent()) r = r->GetParent(); return r;} /** Convenience function: Given a depth value less than or equal to our depth, returns a pointer to our ancestor node at that depth. - * @param depth The depth of the node we want returned, relative to the root of the tree. Zero would be the root node, one would be a child - * of the root node, and so on. - * @returns an ancestor DataNode, or NULL if such a node could not be found (most likely because (depth) is greater than this node's depth) + * @param depth The depth of the node we want returned, relative to the root of the tree. Zero would be the root node, + * one would be a child of the root node, and so on. + * @param defaultValue The value to return if an ancestor of the requested depth could not be found. Defaults to NULL. + * @returns an ancestor DataNode, or (defaultValue) if such a node could not be found (most likely because (depth) is greater than this node's depth) */ - DataNode * GetAncestorNode(uint32 depth) const + DataNode * GetAncestorNode(uint32 depth, DataNode * defaultValue = NULL) const { DataNode * r = const_cast(this); - while((r)&&(depth <= r->GetDepth())) + while((r)&&(r->GetDepth() >= depth)) { if (depth == r->GetDepth()) return r; r = r->GetParent(); } - return NULL; + return defaultValue; } /** Returns a checksum representing the state of this node and the nodes diff --git a/reflector/ReflectServer.cpp b/reflector/ReflectServer.cpp index 1d9474aa..4ffd291f 100644 --- a/reflector/ReflectServer.cpp +++ b/reflector/ReflectServer.cpp @@ -541,11 +541,17 @@ ServerProcessLoop() TCHECKPOINT; // This block is the center of the MUSCLE server's universe -- where we sit and wait for the next event - if (_multiplexer.WaitForEvents(nextPulseAt) < 0) { - if (_doLogging) LogTime(MUSCLE_LOG_CRITICALERROR, "WaitForEvents() failed, aborting!\n"); - ClearLameDucks(); - return B_ERROR; + _inWaitForEvents.AtomicIncrement(); // so a watchdog thread can know we're meant to be waiting at this point + int r = _multiplexer.WaitForEvents(nextPulseAt); + _inWaitForEvents.AtomicDecrement(); // so a watchdog thread can know we're done waiting at this point + + if (r < 0) + { + if (_doLogging) LogTime(MUSCLE_LOG_CRITICALERROR, "WaitForEvents() failed, aborting!\n"); + ClearLameDucks(); + return B_ERROR; + } } // Each event-loop cycle officially "starts" as soon as WaitForEvents() returns diff --git a/reflector/ReflectServer.h b/reflector/ReflectServer.h index 693952c9..c0a8fff0 100644 --- a/reflector/ReflectServer.h +++ b/reflector/ReflectServer.h @@ -5,6 +5,7 @@ #include "reflector/AbstractReflectSession.h" #include "support/NotCopyable.h" +#include "system/AtomicCounter.h" #include "util/NestCount.h" #include "util/SocketMultiplexer.h" @@ -248,6 +249,15 @@ class ReflectServer : public RefCountable, public PulseNode, private PulseNodeMa const ConstByteBufferRef & GetSSLPublicKeyCertificate() const {return _publicKey;} #endif + /** Returns true iff our event loop is currently blocked inside the SocketMultiplexer::WaitForEvents() call. + * Note that calling this function from another thread is subject to race conditions, and that + * if you call it from the thread that is running the ReflectServer's event loop it will always + * return false, since if the thread was blocked inside WaitForEvents() you wouldn't have control + * of the thread to call it. This method is here to enable a separate watchdog thread to observe + * the operations of the main thread; in general it is not necessary to call this method. + */ + bool IsWaitingForEvents() const {return (_inWaitForEvents.GetCount() == 1);} + protected: /** * This version of AddNewSession (which is called by the previous @@ -321,6 +331,8 @@ class ReflectServer : public RefCountable, public PulseNode, private PulseNodeMa #endif NestCount _inDoAccept; NestCount _inDoConnect; + + AtomicCounter _inWaitForEvents; }; DECLARE_REFTYPES(ReflectServer); diff --git a/reflector/StorageReflectSession.cpp b/reflector/StorageReflectSession.cpp index 526a1c5e..75e97f6e 100644 --- a/reflector/StorageReflectSession.cpp +++ b/reflector/StorageReflectSession.cpp @@ -224,7 +224,8 @@ Cleanup() else { // Remove all of our subscription-marks from neighbor's nodes - (void) _subscriptions.DoTraversal((PathMatchCallback)DoSubscribeRefCallbackFunc, this, GetGlobalRoot(), false, (void *)(-LONG_MAX)); + long decrementAll = -LONG_MAX; + (void) _subscriptions.DoTraversal((PathMatchCallback)DoSubscribeRefCallbackFunc, this, GetGlobalRoot(), false, &decrementAll); } _sharedData = NULL; } @@ -448,6 +449,19 @@ AfterMessageReceivedFromGateway(const MessageRef & msgRef, void * userData) PushSubscriptionMessages(); } +class GetSubtreesCallbackArgs +{ +public: + GetSubtreesCallbackArgs(Message * replyMsg, int32 maxDepth) : _replyMsg(replyMsg), _maxDepth(maxDepth) {/* empty */} + + Message * GetReplyMessage() const {return _replyMsg;} + int32 GetMaxDepth() const {return _maxDepth;} + +private: + Message * _replyMsg; + int32 _maxDepth; +}; + void StorageReflectSession :: MessageReceivedFromGateway(const MessageRef & msgRef, void * userData) @@ -490,8 +504,8 @@ MessageReceivedFromGateway(const MessageRef & msgRef, void * userData) NodePathMatcher matcher; matcher.PutPathsFromMessage(PR_NAME_KEYS, PR_NAME_FILTERS, msg, DEFAULT_PATH_PREFIX); - void * args[] = {reply(), (void *)((long)maxDepth)}; - (void) matcher.DoTraversal((PathMatchCallback)GetSubtreesCallbackFunc, this, GetGlobalRoot(), true, args); + GetSubtreesCallbackArgs args(reply(), maxDepth); + (void) matcher.DoTraversal((PathMatchCallback)GetSubtreesCallbackFunc, this, GetGlobalRoot(), true, &args); } MessageReceivedFromSession(*this, reply, NULL); // send the result back to our client } @@ -585,7 +599,11 @@ MessageReceivedFromGateway(const MessageRef & msgRef, void * userData) // This marks any currently existing matching nodes so they know to notify us // It must be done once per subscription path, as it uses per-sub ref-counting NodePathMatcher temp; - if ((temp.PutPathString(fixPath, ConstQueryFilterRef()) == B_NO_ERROR)&&(_subscriptions.PutPathString(fixPath, filter) == B_NO_ERROR)) (void) temp.DoTraversal((PathMatchCallback)DoSubscribeRefCallbackFunc, this, GetGlobalRoot(), false, (void *)1L); + if ((temp.PutPathString(fixPath, ConstQueryFilterRef()) == B_NO_ERROR)&&(_subscriptions.PutPathString(fixPath, filter) == B_NO_ERROR)) + { + long incrementOne = 1; + (void) temp.DoTraversal((PathMatchCallback)DoSubscribeRefCallbackFunc, this, GetGlobalRoot(), false, &incrementOne); + } } if ((subscribeQuietly == false)&&(getMsg.AddString(PR_NAME_KEYS, path) == B_NO_ERROR)) { @@ -1109,11 +1127,9 @@ PassMessageCallbackAux(DataNode & node, const MessageRef & msgRef, bool includeS { TCHECKPOINT; - DataNode * n = &node; - while(n->GetDepth() > 2) n = n->GetParent(); // go up to session level... - StorageReflectSession * next = dynamic_cast(GetSession(n->GetNodeName())()); + StorageReflectSession * next = dynamic_cast(GetSession(node.GetAncestorNode(NODE_DEPTH_SESSIONNAME, &node)->GetNodeName())()); if ((next)&&((next != this)||(includeSelfOkay))) next->MessageReceivedFromSession(*this, msgRef, &node); - return 2; // This causes the traversal to immediately skip to the next session + return NODE_DEPTH_SESSIONNAME; // This causes the traversal to immediately skip to the next session } int @@ -1122,9 +1138,7 @@ FindSessionsCallback(DataNode & node, void * userData) { TCHECKPOINT; - DataNode * n = &node; - while(n->GetDepth() > 2) n = n->GetParent(); // go up to session level... - AbstractReflectSessionRef sref = GetSession(n->GetNodeName()); + AbstractReflectSessionRef sref = GetSession(node.GetAncestorNode(NODE_DEPTH_SESSIONNAME, &node)->GetNodeName()); StorageReflectSession * next = dynamic_cast(sref()); FindMatchingSessionsData * data = static_cast(userData); @@ -1133,7 +1147,7 @@ FindSessionsCallback(DataNode & node, void * userData) data->_ret = B_ERROR; // Oops, out of memory! return -1; // abort now } - else return (data->_results.GetNumItems() == data->_maxResults) ? -1 : 2; // This causes the traversal to immediately skip to the next session + else return (data->_results.GetNumItems() == data->_maxResults) ? -1 : NODE_DEPTH_SESSIONNAME; // This causes the traversal to immediately skip to the next session } int @@ -1142,16 +1156,14 @@ KickClientCallback(DataNode & node, void * /*userData*/) { TCHECKPOINT; - DataNode * n = &node; - while(n->GetDepth() > 2) n = n->GetParent(); // go up to session level... - AbstractReflectSessionRef sref = GetSession(n->GetNodeName()); + AbstractReflectSessionRef sref = GetSession(node.GetAncestorNode(NODE_DEPTH_SESSIONNAME, &node)->GetNodeName()); StorageReflectSession * next = dynamic_cast(sref()); if ((next)&&(next != this)) { LogTime(MUSCLE_LOG_DEBUG, "Session [%s/%s] is kicking session [%s/%s] off the server.\n", GetHostName()(), GetSessionIDString()(), next->GetHostName()(), next->GetSessionIDString()()); next->EndSession(); // die!! } - return 2; // This causes the traversal to immediately skip to the next session + return NODE_DEPTH_SESSIONNAME; // This causes the traversal to immediately skip to the next session } int @@ -1160,27 +1172,14 @@ GetSubtreesCallback(DataNode & node, void * ud) { TCHECKPOINT; - void ** args = (void **)ud; - Message * reply = static_cast(args[0]); - int32 maxDepth = (int32) ((long)args[1]); + GetSubtreesCallbackArgs & args = *(static_cast(ud)); - bool inMyOwnSubtree = false; // default: actual value will only be calculated if it makes a difference - bool reflectToSelf = GetReflectToSelf(); - if (reflectToSelf == false) - { - // Make sure (node) isn't part of our own tree! If it is, move immediately to the next session - const DataNode * n = &node; - while(n->GetDepth() > 2) n = n->GetParent(); - if ((_indexingPresent == false)&&(GetSession(n->GetNodeName())() == this)) return 2; // skip to next session node - } - // Don't send our own data to our own client; he already knows what we have, because he uploaded it! - if ((inMyOwnSubtree == false)||(reflectToSelf)) - { - MessageRef subMsg = GetMessageFromPool(); - String nodePath; - if ((subMsg() == NULL)||(node.GetNodePath(nodePath) != B_NO_ERROR)||(reply->AddMessage(nodePath, subMsg) != B_NO_ERROR)||(SaveNodeTreeToMessage(*subMsg(), &node, "", true, (maxDepth>=0)?(uint32)maxDepth:MUSCLE_NO_LIMIT, NULL) != B_NO_ERROR)) return 0; - } - return node.GetDepth(); // continue traversal as usual + // Make sure (node) isn't part of our own tree! If it is, move immediately to the next session + if ((_indexingPresent == false)&&(GetReflectToSelf() == false)&&(GetSession(node.GetAncestorNode(NODE_DEPTH_SESSIONNAME, &node)->GetNodeName())() == this)) return NODE_DEPTH_SESSIONNAME; + + MessageRef subMsg = GetMessageFromPool(); + String nodePath; + return ((subMsg() == NULL)||(node.GetNodePath(nodePath) != B_NO_ERROR)||(args.GetReplyMessage()->AddMessage(nodePath, subMsg) != B_NO_ERROR)||(SaveNodeTreeToMessage(*subMsg(), &node, "", true, (args.GetMaxDepth()>=0)?(uint32)args.GetMaxDepth():MUSCLE_NO_LIMIT, NULL) != B_NO_ERROR)) ? 0 : node.GetDepth(); } int @@ -1202,7 +1201,7 @@ int StorageReflectSession :: DoSubscribeRefCallback(DataNode & node, void * userData) { - node.IncrementSubscriptionRefCount(GetSessionIDString(), (long) userData); + node.IncrementSubscriptionRefCount(GetSessionIDString(), *static_cast(userData)); return node.GetDepth(); // continue traversal as usual } @@ -1214,32 +1213,22 @@ GetDataCallback(DataNode & node, void * userData) MessageRef * messageArray = (MessageRef *) userData; - bool inMyOwnSubtree = false; // default: actual value will only be calculated if it makes a difference - bool reflectToSelf = GetReflectToSelf(); - if (reflectToSelf == false) - { - // Make sure (node) isn't part of our own tree! If it is, move immediately to the next session - const DataNode * n = &node; - while(n->GetDepth() > 2) n = n->GetParent(); - if ((_indexingPresent == false)&&(GetSession(n->GetNodeName())() == this)) return 2; // skip to next session node - } + // Make sure (node) isn't part of our own tree! If it is, move immediately to the next session + if ((_indexingPresent == false)&&(GetReflectToSelf() == false)&&(GetSession(node.GetAncestorNode(NODE_DEPTH_SESSIONNAME, &node)->GetNodeName())() == this)) return NODE_DEPTH_SESSIONNAME; // Don't send our own data to our own client; he already knows what we have, because he uploaded it! - if ((inMyOwnSubtree == false)||(reflectToSelf)) + MessageRef & resultMsg = messageArray[0]; + if (resultMsg() == NULL) resultMsg = GetMessageFromPool(PR_RESULT_DATAITEMS); + String np; + if ((resultMsg())&&(node.GetNodePath(np) == B_NO_ERROR)) { - MessageRef & resultMsg = messageArray[0]; - if (resultMsg() == NULL) resultMsg = GetMessageFromPool(PR_RESULT_DATAITEMS); - String np; - if ((resultMsg())&&(node.GetNodePath(np) == B_NO_ERROR)) - { - (void) resultMsg()->AddMessage(np, node.GetData()); - if (resultMsg()->GetNumNames() >= _maxSubscriptionMessageItems) SendGetDataResults(resultMsg); - } - else - { - WARN_OUT_OF_MEMORY; - return 0; // abort! - } + (void) resultMsg()->AddMessage(np, node.GetData()); + if (resultMsg()->GetNumNames() >= _maxSubscriptionMessageItems) SendGetDataResults(resultMsg); + } + else + { + WARN_OUT_OF_MEMORY; + return 0; // abort! } // But indices we need to send to ourself no matter what, as they are generated on the server side. @@ -1280,7 +1269,7 @@ RemoveDataCallback(DataNode & node, void * userData) { TCHECKPOINT; - if (node.GetDepth() > 2) // ensure that we never remove host nodes or session nodes this way + if (node.GetDepth() > NODE_DEPTH_SESSIONNAME) // ensure that we never remove host nodes or session nodes this way { DataNodeRef nodeRef; if (node.GetParent()->GetChild(node.GetNodeName(), nodeRef) == B_NO_ERROR) @@ -1782,7 +1771,8 @@ status_t StorageReflectSession :: RemoveParameter(const String & paramName, bool // Remove the references from this subscription from all nodes NodePathMatcher temp; (void) temp.PutPathString(str, ConstQueryFilterRef()); - (void) temp.DoTraversal((PathMatchCallback)DoSubscribeRefCallbackFunc, this, GetGlobalRoot(), false, (void *)-1L); + long decrementOne = -1; + (void) temp.DoTraversal((PathMatchCallback)DoSubscribeRefCallbackFunc, this, GetGlobalRoot(), false, &decrementOne); } } else if (paramName == PR_NAME_REFLECT_TO_SELF) SetRoutingFlag(MUSCLE_ROUTING_FLAG_REFLECT_TO_SELF, false); diff --git a/reflector/StorageReflectSession.h b/reflector/StorageReflectSession.h index d95ea54a..59eb4689 100644 --- a/reflector/StorageReflectSession.h +++ b/reflector/StorageReflectSession.h @@ -584,6 +584,13 @@ class StorageReflectSession : public DumbReflectSession, private CountedObject # include #else @@ -333,7 +335,7 @@ class MutexEventLog { if ((_tailBlock == NULL)||(_tailBlock->IsFull())) { - MutexEventBlock * newBlock = (MutexEventBlock *) malloc(sizeof(MutexEventBlock)); // THIS LINE CAN ONLY CALL plain old malloc() and nothing else!!! + MutexEventBlock * newBlock = static_cast(malloc(sizeof(MutexEventBlock))); // THIS LINE CAN ONLY CALL plain old malloc() and nothing else!!! if (newBlock) { newBlock->Initialize(); @@ -419,7 +421,7 @@ void DeadlockFinder_LogEvent(bool isLock, const void * mutexPtr, const char * fi MutexEventLog * mel = _mutexEventLogs.GetThreadLocalObject(); if (mel == NULL) { - mel = (MutexEventLog *) malloc(sizeof(MutexEventLog)); // MUST CALL malloc() here to avoid inappropriate re-entrancy! + mel = static_cast(malloc(sizeof(MutexEventLog))); // MUST CALL malloc() here to avoid inappropriate re-entrancy! if (mel) { mel->Initialize(muscle_thread_id::GetCurrentThreadID()); @@ -1053,7 +1055,7 @@ ConstSocketRef GetConstSocketRefFromPool(int fd, bool okayToClose, bool returnNU // to inherit the socket will have to either avoid calling this // for those sockets, or call SetHandleInformation() again // afterwards to reinstate the inherit-handle flag) - (void) SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); + (void) SetHandleInformation((HANDLE)((ptrdiff)fd), HANDLE_FLAG_INHERIT, 0); #endif } else if (okayToClose) CloseSocket(fd); diff --git a/test/microchatclient.c b/test/microchatclient.c index 5e675c3e..d2a9175d 100644 --- a/test/microchatclient.c +++ b/test/microchatclient.c @@ -368,7 +368,6 @@ int main(int argc, char ** argv) const char * hostName = "beshare.tycomsystems.com"; const char * userName = "microclyde"; const char * userStatus = "here"; - const char * tempStr; int s; int port = 0; struct User * users = NULL; /* doubly-linked-list! */ @@ -389,7 +388,6 @@ int main(int argc, char ** argv) s = Connect(hostName, (uint16)port); if (s >= 0) { - char text[1000] = ""; UBool keepGoing = UTrue; fd_set readSet, writeSet; @@ -525,7 +523,6 @@ int main(int argc, char ** argv) case PR_RESULT_DATAITEMS: { /* Look for sub-messages that indicate that nodes were removed from the tree */ - uint32 removeCount = 0; uint32 i; const char * nodepath; for (i=0; ((nodepath = UMGetString(&msg, PR_NAME_REMOVED_DATAITEMS, i)) != NULL); i++) @@ -564,7 +561,6 @@ int main(int argc, char ** argv) int pathDepth = GetPathDepth(fieldName); if (pathDepth == USER_NAME_DEPTH) { - uint32 msgCount = 0; uint32 i = 0; while(1) { diff --git a/test/minichatclient.c b/test/minichatclient.c index 78960f1a..fade4d65 100644 --- a/test/minichatclient.c +++ b/test/minichatclient.c @@ -429,7 +429,6 @@ int main(int argc, char ** argv) const char * hostName = "beshare.tycomsystems.com"; const char * userName = "miniclyde"; const char * userStatus = "here"; - const char * tempStr; int s; int port = 0; struct User * users = NULL; /* doubly-linked-list! */ @@ -452,7 +451,6 @@ int main(int argc, char ** argv) s = Connect(hostName, (uint16)port); if (s >= 0) { - char text[1000] = ""; MBool keepGoing = MTrue; fd_set readSet, writeSet; diff --git a/test/testhashtable.cpp b/test/testhashtable.cpp index a1f84a04..be0289e6 100644 --- a/test/testhashtable.cpp +++ b/test/testhashtable.cpp @@ -32,7 +32,7 @@ void bomb(const char * fmt, ...) class TestThread : public Thread { public: - TestThread(const MessageRef & msg) : _msg(msg) {/* empty */} + explicit TestThread(const MessageRef & msg) : _msg(msg) {/* empty */} protected: virtual void InternalThreadEntry() diff --git a/test/testrefcount.cpp b/test/testrefcount.cpp index 3040915e..cc13a5c5 100644 --- a/test/testrefcount.cpp +++ b/test/testrefcount.cpp @@ -15,7 +15,7 @@ class TestItem : public RefCountable { public: TestItem() {/* empty */} - TestItem(const String & name) {SetName(name);} + explicit TestItem(const String & name) {SetName(name);} ~TestItem() {_name = "Dead";} // Just to make dead-item-usage detection a bit easier const String & GetName() const {return _name;} diff --git a/test/testreflectclient.cpp b/test/testreflectclient.cpp index 84bbf783..9411566c 100644 --- a/test/testreflectclient.cpp +++ b/test/testreflectclient.cpp @@ -48,7 +48,7 @@ enum { class MyLooper : public BLooper { public: - MyLooper(MessageTransceiverThread & mtt) : + explicit MyLooper(MessageTransceiverThread & mtt) : #ifdef __ATHEOS__ Looper(""), #endif diff --git a/test/testtuple.cpp b/test/testtuple.cpp index 4586bb64..4e84f2d8 100644 --- a/test/testtuple.cpp +++ b/test/testtuple.cpp @@ -35,7 +35,7 @@ class MyTupleSubclass : public Tuple<5, float> public: MyTupleSubclass() {/* empty */} - MyTupleSubclass(float first) + explicit MyTupleSubclass(float first) { for (uint32 i=0; i +#endif + namespace muscle { /** This class wraps an object of the specified type, so that the wrapped object can be used as diff --git a/util/NetworkUtilityFunctions.cpp b/util/NetworkUtilityFunctions.cpp index 43bac2ed..7edf793c 100644 --- a/util/NetworkUtilityFunctions.cpp +++ b/util/NetworkUtilityFunctions.cpp @@ -16,10 +16,12 @@ # include # include // for SIO_UDP_CONNRESET, etc # include +# if !(defined(__MINGW32__) || defined(__MINGW64__)) # ifndef MUSCLE_AVOID_MULTICAST_API # include // for IP_MULTICAST_LOOP, etc # endif # pragma warning(disable: 4800 4018) +# endif typedef char sockopt_arg; // Windows setsockopt()/getsockopt() use char pointers #else typedef void sockopt_arg; // Whereas sane operating systems use void pointers @@ -1255,7 +1257,7 @@ status_t GetNetworkInterfaceInfos(Queue & results, uint32 { ip_address broadcastIP, netmask; uint32 numLocalAddrs = (bytesReturned/sizeof(INTERFACE_INFO)); - for (int i=0; i #endif +#if defined(__MINGW32__) || defined(__MINGW64__) +# include +# include +#endif + #ifdef BONE # include // sikosis at bebits.com says this is necessary... hmm. #endif diff --git a/util/RefCount.h b/util/RefCount.h index 656988b6..ccb380bd 100644 --- a/util/RefCount.h +++ b/util/RefCount.h @@ -29,7 +29,7 @@ class RefCountable RefCountable() : _manager(NULL) {/* empty */} /** Copy constructor -- ref count and manager settings are deliberately not copied over! */ - RefCountable(const RefCountable &) : _manager(NULL) {/* empty */} + RefCountable(const RefCountable &) : _refCount(), _manager(NULL) {/* empty */} /** Virtual destructor, to keep C++ honest. Don't remove this unless you like crashing */ virtual ~RefCountable() {/* empty */} diff --git a/vc++12/README.txt b/vc++12/README.txt index 9aef188e..da16ec36 100644 --- a/vc++12/README.txt +++ b/vc++12/README.txt @@ -4,7 +4,7 @@ Note that these project files require Visual C++ 2013. To compile muscle, do the following: -1. Open the "muscle.sln" project file in VC++ +1. Open the "muscle.sln" solution file in VC++ 2. Click Build->Build Solution @@ -15,4 +15,4 @@ To compile muscle, do the following: your server with muscled.exe, and maintain it with admin.exe. You can build your own apps and link them against muscle.lib. --Mika Mikitchenko (aka "Monni") +-Mika Lindqvist (aka "Monni") diff --git a/vc++12/muscle.vcxproj b/vc++12/muscle.vcxproj index 14c2203d..67c75c6e 100644 --- a/vc++12/muscle.vcxproj +++ b/vc++12/muscle.vcxproj @@ -95,7 +95,7 @@ .\Junk/muscle.pch .\Junk/ .\Junk/ - .\Junk\muscle.pdb/ + .\Junk\muscle.pdb Level3 true @@ -129,7 +129,7 @@ .\Junk/muscle.pch .\Junk/ .\Junk/ - .\Junk/muscle + .\Junk\muscle.pdb Level3 true @@ -703,7 +703,6 @@ - @@ -721,7 +720,6 @@ - @@ -743,14 +741,13 @@ - + - @@ -762,7 +759,7 @@ - + diff --git a/vc++12/muscled.vcxproj b/vc++12/muscled.vcxproj index 3567ef54..d843621f 100644 --- a/vc++12/muscled.vcxproj +++ b/vc++12/muscled.vcxproj @@ -142,7 +142,7 @@ .\Junk/muscled.pch .\Junk/ .\Junk/ - .\Junk/muscled + .\Junk\muscled.pdb Level3 true @@ -227,7 +227,7 @@ .\Junk/muscled.pch .\Junk/ .\Junk/ - .\Junk/muscled\muscled.pdb + .\Junk\muscled.pdb Level3 true diff --git a/vc++14/README.txt b/vc++14/README.txt new file mode 100644 index 00000000..bb416dcf --- /dev/null +++ b/vc++14/README.txt @@ -0,0 +1,18 @@ +In this directory you will find Visual C++ project files created by Mika + +Note that these project files require Visual C++ 2015. + +To compile muscle, do the following: + +1. Open the "muscle.sln" solution file in VC++ + +2. Click Build->Build Solution + +3. Sit back and relax. The muscle build should complete in a minute or two. + +4. Open the new "Build" folder that is created inside vc++14. You should see + three files there: admin.exe, muscled.exe, and muscle.lib. You can run + your server with muscled.exe, and maintain it with admin.exe. You can + build your own apps and link them against muscle.lib. + +-Mika Lindqvist (aka "Monni") diff --git a/vc++14/admin.vcxproj b/vc++14/admin.vcxproj new file mode 100644 index 00000000..4ed44a72 --- /dev/null +++ b/vc++14/admin.vcxproj @@ -0,0 +1,279 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788} + admin + + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + .\Build\ + .\Build\ + .\Build\ + .\Build\ + .\Junk\admin\ + .\Junk\admin\ + .\Junk\admin\ + .\Junk\admin\ + false + false + false + false + + + + .\Junk/admin.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\zlib\zlib\win32;.\;..\;..\..\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Junk/admin.pch + .\Junk/ + .\Junk/ + .\Junk\admin.pdb + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build/admin.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/admin.pdb + Console + false + + + MachineX86 + UseLinkTimeCodeGeneration + + + true + .\Junk/admin.bsc + + + + + .\Junk/admin.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\zlib\zlib\win32;.\;..\;..\..\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Junk/admin.pch + .\Junk/ + .\Junk/ + .\Junk\admin.pdb + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build/admin.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/admin.pdb + Console + false + + + UseLinkTimeCodeGeneration + + + true + .\Junk/admin.bsc + + + + + .\Junk/admin.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\zlib\zlib\win32;.\;..\;..\..\;%(AdditionalIncludeDirectories) + WIN32;DEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\Junk/admin.pch + .\Junk/ + .\Junk/ + .\Junk\admin.pdb + Level3 + true + /FS %(AdditionalOptions) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build/admin.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/admin.pdb + Console + false + + + MachineX86 + true + UseLinkTimeCodeGeneration + + + true + .\Junk/admin.bsc + + + + + .\Junk/admin.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\zlib\zlib\win32;.\;..\;..\..\;%(AdditionalIncludeDirectories) + WIN32;DEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\Junk/admin.pch + .\Junk/ + .\Junk/ + .\Junk\admin.pdb + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build/admin.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/admin.pdb + Console + false + + + true + UseLinkTimeCodeGeneration + + + true + .\Junk/admin.bsc + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + {001c4ecc-76a2-4008-bbcc-bbf252ec93a5} + false + + + + + + \ No newline at end of file diff --git a/vc++14/muscle.sln b/vc++14/muscle.sln new file mode 100644 index 00000000..a23f7a2b --- /dev/null +++ b/vc++14/muscle.sln @@ -0,0 +1,53 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40302.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "admin", "admin.vcxproj", "{5723BD9A-B23F-4F4F-8D12-C246D8B3D788}" + ProjectSection(ProjectDependencies) = postProject + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5} = {001C4ECC-76A2-4008-BBCC-BBF252EC93A5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "muscle", "muscle.vcxproj", "{001C4ECC-76A2-4008-BBCC-BBF252EC93A5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "muscled", "muscled.vcxproj", "{6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}" + ProjectSection(ProjectDependencies) = postProject + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5} = {001C4ECC-76A2-4008-BBCC-BBF252EC93A5} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Debug|Win32.ActiveCfg = Debug|Win32 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Debug|Win32.Build.0 = Debug|Win32 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Debug|x64.ActiveCfg = Debug|x64 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Debug|x64.Build.0 = Debug|x64 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Release|Win32.ActiveCfg = Release|Win32 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Release|Win32.Build.0 = Release|Win32 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Release|x64.ActiveCfg = Release|x64 + {5723BD9A-B23F-4F4F-8D12-C246D8B3D788}.Release|x64.Build.0 = Release|x64 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Debug|Win32.Build.0 = Debug|Win32 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Debug|x64.ActiveCfg = Debug|x64 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Debug|x64.Build.0 = Debug|x64 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Release|Win32.ActiveCfg = Release|Win32 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Release|Win32.Build.0 = Release|Win32 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Release|x64.ActiveCfg = Release|x64 + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5}.Release|x64.Build.0 = Release|x64 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Debug|Win32.Build.0 = Debug|Win32 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Debug|x64.ActiveCfg = Debug|x64 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Debug|x64.Build.0 = Debug|x64 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Release|Win32.ActiveCfg = Release|Win32 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Release|Win32.Build.0 = Release|Win32 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Release|x64.ActiveCfg = Release|x64 + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vc++14/muscle.vcxproj b/vc++14/muscle.vcxproj new file mode 100644 index 00000000..9129c3f4 --- /dev/null +++ b/vc++14/muscle.vcxproj @@ -0,0 +1,789 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {001C4ECC-76A2-4008-BBCC-BBF252EC93A5} + muscle + + + + StaticLibrary + false + MultiByte + v140 + + + StaticLibrary + false + MultiByte + v140 + + + StaticLibrary + false + MultiByte + v140 + + + StaticLibrary + false + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + .\Build\ + .\Build\ + .\Build\ + .\Build\ + .\Junk\muscle\ + .\Junk\muscle\ + .\Junk\muscle\ + .\Junk\muscle\ + + + + .\Junk/muscle.tlb + + + + + MaxSpeed + AnySuitable + ..\zlib\zlib\win32;..\;..\..\;.\;..\regex\regex;%(AdditionalIncludeDirectories) + WIN32;WINAPI_FAMILY=100;UNICODE;NDEBUG;_LIB;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Junk/muscle.pch + .\Junk/ + .\Junk/ + .\Junk\muscle.pdb + Level3 + true + true + Speed + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Build\muscle.lib + true + true + + + true + .\Junk/muscle.bsc + + + + + .\Junk/muscle.tlb + + + + + MaxSpeed + AnySuitable + ..\zlib\zlib\win32;..\;..\..\;.\;..\regex\regex;%(AdditionalIncludeDirectories) + WIN32;WINAPI_FAMILY=100;UNICODE;NDEBUG;_LIB;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Junk/muscle.pch + .\Junk/ + .\Junk/ + .\Junk\muscle.pdb + Level3 + true + true + Speed + false + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Build\muscle.lib + true + true + + + true + .\Junk/muscle.bsc + + + + + MaxSpeed + AnySuitable + ..\zlib\zlib\win32;..\;..\..\;.\;..\regex\regex;%(AdditionalIncludeDirectories) + WIN32;WINAPI_FAMILY=100;UNICODE;DEBUG;_LIB;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\Junk/muscle.pch + .\Junk/ + .\Junk/ + .\Junk\muscle.pdb + Level3 + true + /FS %(AdditionalOptions) + true + Speed + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Build\muscle.lib + true + true + + + true + .\Junk/muscle.bsc + + + + + .\Junk/muscle.tlb + + + + + MaxSpeed + AnySuitable + ..\zlib\zlib\win32;..\;..\..\;.\;..\regex\regex;%(AdditionalIncludeDirectories) + WIN32;UNICODE;WINAPI_FAMILY=100;DEBUG;_LIB;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\Junk/muscle.pch + .\Junk/ + .\Junk/ + .\Junk\muscle.pdb + Level3 + true + true + Speed + false + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Build\muscle.lib + true + true + + + true + .\Junk/muscle.bsc + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vc++14/muscled.vcxproj b/vc++14/muscled.vcxproj new file mode 100644 index 00000000..0158035c --- /dev/null +++ b/vc++14/muscled.vcxproj @@ -0,0 +1,280 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {6A82FF6A-1634-45EB-AAB4-6360EA6F19B0} + muscled + + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + v120 + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + .\Build\ + .\Build\ + .\Build\ + .\Build\ + .\Junk\muscled\ + .\Junk\muscled\ + .\Junk\muscled\ + .\Junk\muscled\ + false + false + false + false + + + + .\Junk/muscled.tlb + + + + + MaxSpeed + OnlyExplicitInline + .\;..\;..\..\;..\..\zlib\zlib\win32;%(AdditionalIncludeDirectories) + WIN32;UNICODE;NDEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Junk/muscled.pch + .\Junk/ + .\Junk/ + .\Junk\muscled.pdb + Level3 + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build\muscled.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/muscled.pdb + Console + false + + + MachineX86 + UseLinkTimeCodeGeneration + + + true + .\Junk/muscled.bsc + + + + + .\Junk/muscled.tlb + + + + + MaxSpeed + OnlyExplicitInline + .\;..\;..\..\;..\..\zlib\zlib\win32;%(AdditionalIncludeDirectories) + WIN32;UNICODE;NDEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Junk/muscled.pch + .\Junk/ + .\Junk/ + .\Junk\muscled.pdb + Level3 + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build\muscled.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/muscled.pdb + Console + false + + + UseLinkTimeCodeGeneration + + + true + .\Junk/muscled.bsc + + + + + .\Junk/muscled.tlb + + + + + MaxSpeed + OnlyExplicitInline + .\;..\;..\..\;..\..\zlib\zlib\win32;%(AdditionalIncludeDirectories) + WIN32;UNICODE;DEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\Junk/muscled.pch + .\Junk/ + .\Junk/ + .\Junk\muscled.pdb + Level3 + true + /FS %(AdditionalOptions) + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Build\muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build\muscled.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/muscled.pdb + Console + false + + + MachineX86 + true + UseLinkTimeCodeGeneration + + + true + .\Junk/muscled.bsc + + + + + .\Junk/muscled.tlb + + + + + MaxSpeed + OnlyExplicitInline + .\;..\;..\..\;..\..\zlib\zlib\win32;%(AdditionalIncludeDirectories) + WIN32;UNICODE;DEBUG;_CONSOLE;MUSCLE_ENABLE_ZLIB_ENCODING;MUSCLE_USE_CPLUSPLUS11;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\Junk/muscled.pch + .\Junk/ + .\Junk/ + .\Junk\muscled.pdb + Level3 + true + + + UNICODE;NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Build\muscle.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;iphlpapi.lib;version.lib;%(AdditionalDependencies) + Build\muscled.exe + true + .\Build;%(AdditionalLibraryDirectories) + .\Junk/muscled.pdb + Console + false + + + true + UseLinkTimeCodeGeneration + + + true + .\Junk/muscled.bsc + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + {001c4ecc-76a2-4008-bbcc-bbf252ec93a5} + false + + + + + + \ No newline at end of file