Compare commits

..
Author SHA1 Message Date
hoiji09 e9d878edae Simplified Locking in MultList
This was done by moving the mutex from EntList to MultList.
2014-10-05 21:15:24 +05:30
Mark Pictor ba74c53ca0 for std::thread, change reference args to pointers
I ran into an error "...error: no type named 'type' in class std::result_of..."
Google led me to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57716
and I eliminated the error by changing references to pointers as described at
http://stackoverflow.com/questions/15235885/invalid-initialization-of-non-const-reference-with-c11-thread
2014-08-21 20:27:36 -04:00
hoiji09 5dc00ba03f Merge remote-tracking branch 'origin/master' into hj/thread-safety
Conflicts:
	src/clstepcore/instmgr.cc
2014-08-18 19:37:13 +05:30
hoiji09 1265e0c110 Added exit(success/fail) in thread-safety test 2014-08-18 17:45:31 +05:30
hoiji09 e73ad4df1c instMgrAdapter took dependency on sc_thread
lazyTypes.h was also modified. HAVE_STD_THREAD macros were removed from cllazyfile library *.cc and *.h since classes sc_thread and sc_mutex internally handles the macros.
2014-08-18 17:28:30 +05:30
hoiji09 f0fdfd706f Added class sc_thread in sc_thread.h 2014-08-18 17:25:58 +05:30
hoiji09 bac1435936 Added sc_thread.h in clutils
This acts like a wrapper to some of the thread functionalities (like get_id()) which is being used in stepcode. If the compiler does not supports thread functionalities then this class provides dummy types and functionalities.
2014-08-18 17:00:01 +05:30
hoiji09 54457e567a Utilized sc_mutex in cllazyfile
Earlier std::mutex was being used. It was replaces with sc_mutex which acts like a wrapper to std::mutex
2014-08-18 16:56:06 +05:30
hoiji09 2aa936b601 Corrected a coment sc_mutex.h 2014-08-18 14:08:18 +05:30
hoiji09 85a248a50a Added NO_REGISTRY Macro to lazy_thread_safety_test
lazy_thread_safety_test had 2 checks which were schema dependent. These checks are now wrapped in NO_REGISTRY macro.
2014-08-18 11:57:17 +05:30
Cliff Yapp f72e01e610 Apply BRL-CAD change r61607 - Harden verify_generated.cmake.in to odd pathnames 2014-08-17 23:25:03 -04:00
Cliff Yapp 7531579d39 Update generated expscan.c file 2014-08-17 23:23:02 -04:00
Cliff Yapp 2ff6f4b434 Apply BRL-CAD change r61104 from brlcad - remove the misspelled readme markdown file that only contains the word 'Howto' 2014-08-17 23:12:37 -04:00
Cliff Yapp f357ef4c83 Apply BRL-CAD change r61065 - The insertion mechanism for the sortedMaster array performed very badly in the case where a large file has a batch of low-id-number entities towards the end of the file. Tossing in std::map in place of that array avoids the bad corner case, but we may pay a performance penalty in other situations - depending on what the bottle necks are, this may be work revisiting. For now, this seems to work well enough. 2014-08-17 23:09:50 -04:00
Cliff Yapp 752f976475 Suppress CMake warning 26 - need to figure out the 'right' approach eventually, but for now this is needed with CMake 3.0 2014-08-17 23:04:24 -04:00
Cliff Yapp 03dbb8ee9f Apply BRL-CAD change r58740 from tbrowder2 - fix typo 2014-08-17 22:57:17 -04:00
Cliff Yapp 3e51af51b4 Apply BRL-CAD change r58523 from n_reed - include ios header for std::ios namespace; fixes 'symbol not found' in exp2cxx on os x 2014-08-17 22:55:44 -04:00
Cliff Yapp 87e1f9948c Apply BRL-CAD change r58222 from tbrowder2 - added FIXME to warn of error with tightned standards 2014-08-17 22:54:01 -04:00
Cliff Yapp b905bec990 Apply BRL-CAD change r58172 from tbrowder2 - correct grammar 2014-08-17 22:52:56 -04:00
hoiji09 03981d27e0 One more subclass of SDAI__set
Adding the Remove( SDAI_ptr ) API to SDAI__set made SDAI_Application_instance__set a candidate for inheriting common logic from SDAI__set.
Note: This class was already made thread safe in one of the previous commits. This commit only removes the now apparent duplicate code.
2014-08-15 23:25:32 +05:30
hoiji09 f26cb0457d Added SDAI__set::Remove( SDAI_ptr ) function
The semantics of this function would be similar to SDAI__set::Remove( SDAI__set::Index( SDAI_ptr ) ). The only difference would be that in the new function both the operations are done under a single lock.
Wherever the old Remove( Index( SDAI_ptr ) ) code snippet was found, it was replaced by the new Remove( SDAI_ptr ) function.
2014-08-15 22:56:49 +05:30
hoiji09 42d71188fc Made SDAI__set thread safe
This was done by introducing a mutex in the SDAI__set class.
2014-08-15 22:20:09 +05:30
hoiji09 40c3a1c33b Made use of sdaiSet
The classes in cldai which were chosen to inherit from sdaiSet were: SDAI_DAObject__set, SDAI_Entity_extent__set and SDAI_Model_contents__list.
2014-08-15 21:46:48 +05:30
hoiji09 fa75e8cedd Added class sdaiSet in cldai library
This class will act as a superclass of few other classes in the same library, hence will contain the common logic of its subclasses.
2014-08-15 21:41:50 +05:30
hoiji09 b17bcbdaf0 Removed warning from SDAI_instance__set commit 2014-08-15 20:41:30 +05:30
hoiji09 731673f827 Thread safety in SDAI_Application_instance__set
Done by introducing a recursive_mutex in the SDAI_Application_instance__set class.
2014-08-13 21:06:26 +05:30
hoiji09 e941244617 Added a comment about thread safety in STEPfile 2014-08-13 11:15:41 +05:30
hoiji09 91efe7c0e5 Safe attributes iteration in STEPfile 2014-08-13 10:55:12 +05:30
hoiji09 02b41416fb Safe InstMgr iteration in STEPfile
Variables of class InstMgr were being iterated upon in class STEPfile through the variables _instances (including its get function instances()) and _headerInstances. The mtx defined in InstMgr was invoked to make them safe.
2014-08-13 10:44:34 +05:30
hoiji09 9cbe6d1dd9 GetApplication_instanceFromFileId in InstMgr class
The SDAI_Application_instance * GetApplication_instance( MgrNode * ) and MgrNode * FindFileId( int ) methods of class InstMgr were often being used together in the class STEPfile. Hence a special function was created in class InstMgr of the form SDAI_Application_instance * GetApplication_instanceFromFileId( int ) which would take care of locking and consistency issues. This function was then used in STEPfile.
2014-08-13 10:19:24 +05:30
hoiji09 a3ce139347 Protected _headerId in STEPfile (cleditor)
_headerId is a counter used in STEPfile class. Its value can change in ReadHeader and ReadExchangeFile methods. Hence a mutex was introduced in order to protect it.
2014-08-13 10:07:32 +05:30
hoiji09 e3fbc14282 Removed istream *in2 from STEPfile::AppendFile
Originally For the second pass a new istream (in2) was being created and the .step file was being opened again. This was prevented by directing the original istream (in) to the beggining of the .step file.
2014-08-10 22:44:11 +05:30
hoiji09 9f24e3ef64 Optimized ReadReal
Replaced calls to input stream peek & get with judicious use of get.
2014-08-08 20:10:05 +05:30
hoiji09 7f653188c4 Converted GetKeyword to FillKeyword
In the original function a static string was being used. The dependency on the static string was removed by passing a string as a parameter from the caller to callee, so that the function could operate without worrying about thread safety.
The function name change mimics the change in the semantics of the function.
2014-08-08 11:04:21 +05:30
hoiji09 3c616f1455 Made DirObj of clutils thread safe
This was achieved introducing a mutex in the DirObj class. Course-Level (fat) Locking was done only in publically accessed function.
2014-08-06 20:36:25 +05:30
hoiji09 376dc4a482 Thread safety in CmdMgr of cleditor 2014-08-06 20:32:52 +05:30
hoiji09 0fe8bc3a91 Made ReplicateList in cleditor thread safe
Used mtxP of the superclass SingleLinkList to ensure thread safety
2014-08-06 20:31:25 +05:30
hoiji09 dc5a00f0ea Thread Safety in ComplexCollect
A mutex was introduced to proctect the counter and the pointer to clists.
The insert and remove functions were tricky to make thread safe as clists may or may-not have been initialized. Hand-over-hand locking was used.
2014-08-03 00:51:47 +05:30
hoiji09 27f781477c Thread safety in ComplexList
Like the classes before, used sharedMtxP to protect the EntNode list whenver it was being iterated upon.
Also added a public mutex to protect the public next pointer. Resposibilty of using it will fall to the class which is using next pointer (ComplexCollect)
2014-08-03 00:19:22 +05:30
hoiji09 1095f7346d Thread safety in OrList
Similar to AndList. However the mutex belonging to the superclass EntList was used to protect various counters (choiceCount, choice) used by OrList
2014-08-03 00:10:18 +05:30
hoiji09 3c848a5d2b Thread safety in Join-, And-, AndOr- List
sharedMtxP of EntNode class was invoked to keep the list of EntNode consistent whenever the EntNode list was being used multiple times in a function
2014-08-02 23:36:36 +05:30
hoiji09 79c9901662 Thread safety in MultList
The mutex defined in the superclass EntList was used in the function appendList.
2014-08-02 23:23:54 +05:30
hoiji09 07448b77d6 Thread Safety in SimpleList
Used sharedMtxP defined in EntNode class to protect EntNode list structure which was being accessed in functions of SimpleList class
2014-08-02 23:01:21 +05:30
hoiji09 0a45ce2aa5 Thread safety in EntList.
Under the assumptions that an EntList object cannot be inserted in between two EntList objects and cannot be removed from a list of EntList objects, making this class thread safe became trivially easy.
One mutex per EntList object was introduced to support appending of EntList objects. As this feature would be used by its subclass (MultList)
2014-08-02 22:32:00 +05:30
Cliff Yapp 63298df542 Until we reach a final decision on what to do about the schema_scanner, handle the .exe case 2014-08-01 21:04:23 -04:00
Cliff Yapp 319a8ab59d Only set a property on lazy_test-static if it is present as a target. 2014-08-01 21:01:37 -04:00
Cliff Yapp 607f732671 Need the NO_REGISTRY flag for the static version of this target as well. 2014-08-01 07:24:27 -04:00
Cliff Yapp e649757417 Install schema headers in locations that match the build tree hierarchy, so include directives will work both with in-build-tree and installed stepcode layouts. 2014-07-31 21:26:57 -04:00
hoiji09 3fdbe460f1 Made STEPcomplex thread safe
The assumption used was that STEPcomplex class wont in future provide an API through which threads can remove / insert a STEPcomplex node.
Three already declared mutexes were used in for this purpose:
(1) A recursive mutex for each STEPcomplex node (borrowed from the superclass SDAI_Application_instance)
(2) A recursive mutex belonging to AttrDescriptorList class (originally defined in SingleLinkList class)
(3) A recursive shared mutex belonging to EntNode class.

The fixed order between the locks was: (2) > (1). (3) was independent.
2014-07-24 23:06:21 +05:30
hoiji09 2cabefa944 Minor STEPcomplex optimization
Collapsed an if condition into a while condition without changing the semantics
2014-07-24 22:47:23 +05:30
hoiji09 7233d604a1 Fixed locking in sdaiApplication_instance.cc
The STEPattributeList data was being iterated and modiefied by the SDAI_Application_instance class without invoking the mutex of the STEPattribute class. This was fixed in this commit.
2014-07-24 22:31:26 +05:30
hoiji09 06b7ee5823 Made sdaiSelect::CanBe( BASE_TYPE ) thread safe. 2014-07-22 11:03:32 +05:30
hoiji09 36d4876333 Locking in ExpDict.cc
There were some functions in ExpDict.cc that were not properly locked before. Locking was done in them
2014-07-22 10:54:10 +05:30
hoiji09 cdede9ee27 Made SDAI_Application_instance thread safe.
This was done by introducing a mutex for each SDAI_Application_instance.
AppendMultInstance was made thread safe by doing hand to hand locking.
GetMiEntity was made thread safe acquiring locks in increasing order and releasing locks in decreasing order.
The checks in sdaiApplication_instance_thread_safety_test now pass.
2014-07-18 20:49:02 +05:30
hoiji09 66999c76aa Internal changes in sdaiApplication_instance.cc
These changes have been done to facitilate the use of mutexes to make the SDAI_Application_instance class thread safe. (No mutex has been used introduced yet)
2014-07-18 16:02:12 +05:30
hoiji09 62761ceba8 Added test for checking thread safety
This test would check thread safety for AppendMultInstance & GetMiEntity functions in class SDAI_Application_instance. The tests failed for both.
Rest of the functions were not checked since the locking in them was trivial.
2014-07-18 15:00:28 +05:30
hoiji09 1aa1ed110f Redefined GetMiEntity API
GetMiEntity function is a part of SDAI_Application_instance class. The function now accepts const char * (instead of char *) as parameter.
2014-07-18 14:54:19 +05:30
hoiji09 10f041c779 Made STEPattributeList thread safe
Couple of functions were identified as vulnerable. The mutex defined in the superclass SingleLinkList was used.
2014-07-18 14:46:45 +05:30
hoiji09 25081dfa0e Removed the infinite recursion bug in STEPattribute
The bug would surface if a STEPattribute instance which has been redefined, has its ShallowCopy function invoked.
2014-07-18 14:35:31 +05:30
hoiji09 ca7594bd75 Removed garbage characters 2014-07-13 22:43:40 +05:30
hoiji09 b7cc806a57 Made EntNode of complexSupport.h thread safe
Since EntNode had no covering list counterpart, a shared recursive mutex was introduced. The pointer to this mutex would be with every node.
2014-07-12 18:55:33 +05:30
hoiji09 cb1f402b15 Made STEPaggregrate thread safe.
This was done by relying on the mtx used by its superclass: SingleLinkList.
2014-07-12 16:40:46 +05:30
hoiji09 25ec194b33 Modified add_schema_dependent_test module
Some of the unit tests were failing due to assertions failures inside mutexes.
Ultimately the CMakeFiles were changed and all the tests except of 'test_inverse_attr3' are passing
2014-07-12 13:52:33 +05:30
hoiji09 832154ae44 Made SubSuperIterators.h thread safe
This was done by introducing a recursive mutex meant to protect the std::deque 'q' and unsigned integer 'position'
2014-07-10 17:04:37 +05:30
hoiji09 6e5475e37d Removed duplicated code in SubSuperIterators.cc 2014-07-10 16:33:23 +05:30
hoiji09 529d3a0ca0 Duplicate code was removed in STEPaggregrate
STEPaggregrate and its superclass SingleLinkList.cc had the same destructor.
2014-07-10 11:18:38 +05:30
hoiji09 d169a58ec5 Changes in cmake to build lazy tests
Some changes in cmakefiles had caused the test associated with lazy_test to stop building. Those changes were reviewed and corrected.
2014-07-09 22:02:34 +05:30
hoiji09 e951c2c71a Corrected SingleLinkedList mtx bug
The mtx is converted into sc_recursive_mtx deleted in the destructor
2014-07-09 21:12:16 +05:30
hoiji09 077633aa77 Made Registry Schema and Type operations thread safe
All the checks in Registry_thread_safety_test now pass
2014-06-25 22:26:17 +05:30
hoiji09 58ca507d13 Made the Registry entity operation thread safe
The checks related entity operations in Registry_thread_safety_test now pass.
2014-06-25 22:15:00 +05:30
hoiji09 738d1820df Added test to check thread safety of Registry class
The Entity, Schema and Type operations are tested. For each, there are 3 checks: Add-Add, Remove-Remove, Add-Remove.
For every check the two operation are done first serially and then parallely. Their results are then compared.
2014-06-25 12:05:20 +05:30
hoiji09 391180bc2d Made Schema thread safe by using 3 mutexes.
The 3 mutexes were used to protect the _function_list, _procedure_list & _global_rules data structures.
The first two are vectors. The last is already a thread safe structure, however its being lazy-initilized hence a mutex is needed.
2014-06-25 11:56:11 +05:30
hoiji09 fe33e5d5cb Made Global_rule thread safe by using a mutex.
Even though its superclass i.e Dictionary_instance__set was made thread safe, thread safety in functions 'entities_' and 'where_rules_' was being violated
2014-06-25 11:51:09 +05:30
hoiji09 cf9a203988 Made Dictionary_instance__set thread safe. 2014-06-25 11:45:08 +05:30
hoiji09 6b97cbe906 Made SingleLinkList class thread safe
This was done by adding a mutex. Also a cmake file was modified inorder to compile the above changes.
2014-06-25 11:37:10 +05:30
hoiji09 643da31f92 Added a missing return statement 2014-06-23 17:26:34 +05:30
hoiji09 e02ce60f9d Made Where_rule__list a subclass.
The superclass was Dictionary_instance__set
2014-06-22 22:11:31 +05:30
hoiji09 3db2ab29c0 Took Dependency on Dictionary_instance__set
Explicit_item_id__set, Implicit_item_id__set, Interface_spec__set, Global_rule__set and Uniqueness_rule__set became subclass of Dictionary_instance__set.
Lot of Duplicated code was removed this way
2014-06-22 21:56:39 +05:30
hoiji09 dc8e00b794 Added Dictionary_instance__set
This class is intended to be a superclass of all the *__set classes. This will help to removve duplicate code
2014-06-22 21:52:15 +05:30
hoiji09 2a4d42e596 Added std_recursive_mutex in GenNodeArray.
Also modified classes which inherit the above accordingly
2014-06-18 22:43:31 +05:30
hoiji09 29ec4e33e1 Minor refractoring in MgrNodeArray
This will be helpful when we introduce a mutex in GenNodeArray.
2014-06-18 22:34:02 +05:30
hoiji09 d0e9aa9dfb Added GetGenNode function in GenNodeArray.
This function is a safer couterpart to [] function.
Replaced call to the [] function with calls to GetGenNode function. Was feasable since the former is only used for getting GenericNode pointers.
2014-06-18 22:26:42 +05:30
hoiji09 d6c133f805 Introduced recursive_mutex in gennodelist
mgrnodelist which inherits gennodelist was also changed
2014-06-18 22:08:39 +05:30
hoiji09 ad6752a80f Used containingList to remove duplicate code. 2014-06-18 22:00:48 +05:30
hoiji09 f89e3c4999 Modified the insert function in gen/mgr/disp lists.
The new insert function checks whether the existing node belongs to the same list or not. If it doesn't it does nothing and returns false.
This will be very helpful when introducing thread safety in list structures.
2014-06-18 21:51:28 +05:30
hoiji09 17c720206a Added another occurance of containingList 2014-06-18 21:49:32 +05:30
hoiji09 05360da87c Added containingList pointer in GenericNode
This pointer will point to the list of which the node is part of. Also moved some code between files.
2014-06-18 21:41:39 +05:30
hoiji09 d6ad56ee6c Locked more potentially thread-unsafe functions. 2014-06-18 11:51:18 +05:30
hoiji09 79f9473d01 Added sc_recursive_mutex
This will be used to handle situtations where there are 2 public apis. Both modify an internal data structure, hence lock it.
However one API depends on other. Thereby it will have to-reobtain the lock.
2014-06-18 11:44:54 +05:30
hoiji09 f6b92019b1 Corrected locking in getApplication_Instance 2014-06-18 11:41:26 +05:30
hoiji09 65f767aa7b Increasing the number of iterations.
A print statement is also corrected.
2014-06-18 11:30:41 +05:30
Mark df100f5764 Merge pull request #298 from cshorler/ap203e2_fixes
Ap203e2 fixes
2014-06-15 14:06:45 -04:00
hoiji09 164c0651e1 Made Append / Delete in instmgr thread safe.
The InstMgr_thread_safety_test passes. Had to a change file in cmake directory in order to compile the changes.
2014-06-15 14:40:41 +05:30
hoiji09 485fad46ca Removed duplicate code 2014-06-15 14:34:23 +05:30
hoiji09 d990137d1b Modified CMakeLists.txt to include HAVE_STD_THREAD defs.
The cmake files of cldai, cleditor & clstepcore libraries have been changed.
2014-06-15 14:27:23 +05:30
hoiji09 5cba5e6a8a Added a test for checking thread safety in instmgr
The test tries to insert and delete instances simultaneosly, sequentially and parallely and later compares there results for any disparity.
2014-06-15 14:21:16 +05:30
hoiji09 e67a5f51d1 Added sc_mutex.h to src/clutils
It is wrapper to std::mutex. It does nothing if HAVE_STD_MUTEX is not defined.
2014-06-15 13:32:17 +05:30
Christopher Horler b65af6f982 first fix for Python MRO issue 2014-06-08 20:47:00 +01:00
Christopher Horler 65d3937e72 add simple sort to Linked_List implementation 2014-06-08 20:44:50 +01:00
Christopher Horler d635ee5ca8 fix some NameErrors due to ordering of the output classes / types 2014-06-08 20:43:30 +01:00
hoiji09 7981d8835b Function comments 2014-06-08 11:23:09 +05:30
hoiji09 0972caa573 Function comments made to follow conventions 2014-06-08 11:21:23 +05:30
Christopher Horler bd80de24bc add simple support for logical XOR output, assumes parameters are already boolean types 2014-06-07 21:16:53 +01:00
Christopher Horler 44a6abb36e update REPEAT / looping statement outputs 2014-06-07 21:13:35 +01:00
Christopher Horler cabf5df7ac map special characters \x9 \xA \xD in EXPRESS literals to Python \t \n \r 2014-06-07 21:11:17 +01:00
Christopher Horler 5fc6630b3f Python keywords are replaced by keyword_ (underscore), this fixes a few associated outputs to avoid invalid Python code 2014-06-07 21:01:16 +01:00
hoiji09 313e99c7f3 Finer grain locking in loadInstance
Also doing double checking in the thread safe version for better performance in case of many threads.
2014-06-02 23:03:01 +05:30
hoiji09 b20c9860a3 Added openFileSafely( fname ) functionality
Plenty of mutexes were used for this purpose. Fine grain locking addInstance in function.
The code passes the test for thread safety in opening multiple files.
2014-06-02 22:52:28 +05:30
hoiji09 5558c7f0b1 lazyInstMgr::registerDataSection semantics changed
Keeping in mind the thread safety, registring a data section is now a two step process. In first step an entry is reserved, by filling it with a null value, and getting its index. In the second step the null value is replaced with the new value.
The destructor has been changed keeping in mind that a _dataSection entry might also be a null. Destroying _instanceTypes data structure in the destructor
2014-06-02 22:37:31 +05:30
hoiji09 1700288489 Removed static variable nextFreeInstance
This was done my making the static variable an object variable. Hence now it is possible that different threads give header instances present in different file, same instanceID
2014-06-02 22:23:28 +05:30
hoiji09 0e2ab604e9 Removed static variable (string str) in sectionReader.cc
The function sectionReader::getDelimitedKeyword( delims ) was changed to sectionReader::fillDelimitedKeyword( delims, string& ).
This was done to make reading from the file stream thread safe.
2014-06-02 22:17:08 +05:30
hoiji09 22a6b9014f Added a compatible wrapper for mutex lock / unlock
This wrapper will invoke the corresponding lock or unlock function std::thread is supported or a dummy function if not.
Hence the wrapper can be easily be used by functions irrespective of whether std::mutex is supported or not.
2014-06-02 22:08:33 +05:30
hoiji09 b865666b55 Added test for opening multiple files in parallel
The test fails with a string error
2014-06-02 22:01:25 +05:30
hoiji09 343c9c54e2 Added FindFileIdSafely and GetSTEPentitySafely functions
A new typedef in lazyTypes had to be introduced mapping threadId to a pointer to a mgrNodeHelper instance.
The test for thread safety was passed by the code.
2014-05-28 21:02:04 +05:30
hoiji09 21aa179953 Added test checking thread safety of getSTEPentity()
The test was created by modifying the test for checking thread safety of loadInstance. The test failed due to a abort from lazy parser
2014-05-28 20:54:45 +05:30
hoiji09 80d021e4cb Added thread safe loadInstanceSafely( instanceID )
It passes the test added earlier
2014-05-28 20:49:58 +05:30
hoiji09 5f38d1bd93 Added test for checking thread safety of loadInstance
The check fails with a abort comming from the parser as loadInstance is not thread safe
2014-05-28 20:46:47 +05:30
hoiji09 c6800fc9b4 Initializing _mainRegistry to 0 in lazyInstMgr constructor
This was needed to prevent the assert in setRegistry from failing under the following workload
lazyInstMgr * mgr = new lazyInstMgr;
mgr->initRegistry( SchemaInit );
mgr->openFile( fileName );
delete mgr;
lazyInstMgr * mgr = new lazyInstMgr;
mgr->initRegistry( SchemaInit );
2014-05-28 20:31:56 +05:30
hoiji09 4bd2682b51 Fixed an appearance of a warning in loadInstance(id)
Earlier even if the instance 'id' had already been loaded before, the function would display a warning that the instance 'id' was not found in any section
2014-05-28 20:17:02 +05:30
hoiji09 e357da8a75 Fixed lazy parser not handling newlines in step files
This bug was first noticed when trying to lazy-load instance: 637538274 in data/cd209/ATS1-out.stp.
The parser now stores the first whitespace character and skips the following whitespaces. It then compares the first whitespace character and the character in the current position with the set of provided delimeters to determine whether correct delimeter has been reached.
2014-05-28 20:09:26 +05:30
hoiji09 97e6b9b3c6 Explicit HAVE_STD_THREAD decleration through CMake 2014-05-28 19:34:00 +05:30
hoiji09 14107427b9 Added thread-safe instance dependencies counterpart 2014-05-27 22:13:16 +05:30
hoiji09 c2aecfb649 Added HAVE_STD_THREAD on mutex declerations also. 2014-05-27 19:22:58 +05:30
hoiji09 f511696c5d Used the HAVE_STD_THREAD macro
HAVE_STD_THREAD macro was used in src/cllazyfile/CMakeLists.txt and various *.cc and *.h files. The *safely functions have clubbed together in this commit
2014-05-27 18:45:38 +05:30
hoiji09 705483d0ab Catered to unsigned-signed overflow 2014-05-27 17:28:54 +05:30
hoiji09 ab3c2d4717 Commented on which step file was used in the test 2014-05-23 11:27:03 +05:30
hoiji09 88545df537 Added thread safe count and getInstances function
The functions are countInstancesSafely( string type ) and getInstancesSafely( string type )
2014-05-23 11:18:48 +05:30
hoiji09 cc3c4ec705 Added test for checking thread safety.
The test checks for thread safety in retrieving the list of instances of a particular type.
2014-05-23 11:04:17 +05:30
hoiji09 8a528de01c Removed Redundant Code and better formatting. 2014-05-23 10:44:52 +05:30
hoiji09 c0e26cda16 Added getFwdRefsSafely() and getRevRefsSafely()
These functions are thread safe counterparts to getFwdRefs() and getRevRefs() respectively. The CMakeFiles have been modified to make this test run. They will be restored in the later commits.
2014-05-19 19:08:50 +05:30
hoiji09 a47447a7f9 Improved thread safety test
Moved mgr->getFwdRefs() inside the thread workload
2014-05-19 10:18:22 +05:30
hoiji09 8b8cde064f Added Test for checking thread safety
Currently it only checks whether concurrent read accesses to _fwdInstanceRefs & _revInstanceRefs are thread safe our not.
2014-05-19 09:33:05 +05:30
hoiji09 025ffba8fd Removed signed-unsigned comparison warning 2014-05-13 17:53:42 +05:30
Mark b7df5a0e6f Merge pull request #296 from jasondegraw/master
Add CMAKE_GENERATOR to schema scanner build
2014-04-23 20:36:11 -04:00
Jason W. DeGraw 9aa3b4201f Add CMAKE_GENERATOR to schema scanner build
Command line configuration with MinGW on Windows was failing
in schemaScanner.cmake because the generator wasn't getting
passed through to the build of the scanner. This commit adds
the generator to the scanner build command and fixes #295.
2014-04-19 14:38:12 -04:00
Cliff Yapp 6d57acff5b Apparently get_filename_component needs some help when it comes to windows drive names. 2014-04-08 21:22:55 -04:00
Mark c3094242c8 Merge pull request #294 from hoiji09/master
Added a function to lazyInstMgr for recursively getting Instance Dependencies.
2014-03-30 12:37:59 -04:00
hoiji09 1c048abd2e Removing self dependency of an instance
lazyInstMgr::instanceDependencies will now not add the instance being queried for in the generated dependency list.
2014-03-30 09:35:06 +05:30
hoiji09 3e4af5a77e Changes in printDeps test module
Changed the function return type from int to void, replaced '\n' by std::endl. Minor modifications to other print statements
2014-03-30 09:22:19 +05:30
hoiji09 a285652f01 Removed extra whitespace
The whitespace accidently got added in the last commit
2014-03-30 08:49:52 +05:30
Cliff Yapp 5abaebb04b Try to make the RELATIVE_PATH_TO_TOPLEVEL macro robust for out-of-src-dir situations. 2014-03-29 12:24:44 -04:00
hoiji09 35b76941bd Added instanceDependencies function in lazyInstMgr
This function lists all instances that one instance recursively depends upon
2014-03-27 21:11:25 +05:30
Mark 7301b34c27 Merge pull request #293 from hoiji09/master
Buffering a read to speedup lazy loading
2014-03-17 17:14:22 -04:00
hoiji09 e4426e3a64 Resolved bad error messages 2014-03-14 11:35:53 +05:30
hoiji09 39d37e9b09 Missing newline added 2014-03-14 07:51:47 +05:30
hoiji09 a7fc5d1e76 Added a comment on double checking.
The double checking is done while parsing a instance id from the file to a variable of type InstanceID
2014-03-14 00:24:00 +05:30
hoiji09 f6fde2f1e1 strtoull macro support for MSVC. 2014-03-14 00:14:18 +05:30
hoiji09 d43b52d61e Splitting warning and error detection 2014-03-10 09:07:32 +05:30
hoiji09 9cded87862 Safer String to Integer conversion.
Accurate inference of number of characters in the string representation of the instance number. On finding a very large instance number, lazyloading will skip that section.
2014-03-10 07:34:02 +05:30
hoiji09 8de8875cd8 Corrected a Malformed comment 2014-03-09 18:50:50 +05:30
hoiji09 7ff99c9564 Added std::endl to the warning message 2014-03-09 18:42:44 +05:30
hoiji09 3f0115631b Updated error message
The error message on finding a very large instance ID is saner
2014-03-09 12:24:27 +05:30
hoiji09 bcd9a58abc Buffered a read to increase speed in Lazy Loading
Added a buffer in SectionReader::readInstanceNumber(). This leads to 1.5x speedup of lazy loading on a 32-bit System. Also Adhered to comments pointed out in the previous commit.
2014-03-06 10:57:40 +05:30
Mark 4a0a27cc30 Merge pull request #289 from stepcode/mp/config-parse-rebase
Split generated code
2014-03-05 22:52:31 -05:00
hoiji09 5c24152afe Introduced a buffer in SectionReader::readInstanceNumber() to fasten lazy loading 2014-03-05 09:51:47 +05:30
Mark Pictor 87fbca7359 C string safety in TYPEget_ctype / TYPE_get_ctype
Check string lengths, only copy if necessary

found due to an OSX segfault - the static char[] retval was getting copied into itself due to recursion

    frame #4: 0x00007fff92da1860 libsystem_c.dylib`__chk_fail + 48
    frame #5: 0x00007fff92da1870 libsystem_c.dylib`__chk_fail_overlap + 16
    frame #6: 0x00007fff92da18a1 libsystem_c.dylib`__chk_overlap + 49
    frame #7: 0x00007fff92da1a6c libsystem_c.dylib`__strcpy_chk + 64
    frame #8: 0x0000000100013a98 exp2cxx`TYPEget_ctype(t=0x0000000101a580e0) + 280 at class_strings.c:56
2014-03-04 20:10:04 -05:00
Mark 2338dd11e1 increase schema scanner config/build timeouts
config is slow on windows and the 10s limit caused intermittent failures
2014-03-02 15:44:33 -05:00
Mark Pictor f1ee9585d1 add dependencies for tests, so tests won't fail if 'make' wasn't run before 'make test' 2014-03-01 13:49:30 -05:00
Mark Pictor 5d78a327db update AP203Minimum - generated code is in different dir now 2014-03-01 13:47:42 -05:00
Mark Pictor 832a6e75b6 print ReferentType calls, etc, to files->init for TYPEs that are typedef'd 2014-03-01 11:53:31 -05:00
Mark Pictor 252f19754f remove empty loop 2014-03-01 11:53:31 -05:00
Mark Pictor 1598dee630 remove useless switch statement, replace with if 2014-03-01 11:53:31 -05:00
Mark Pictor 15993bdd96 improve 2 error messages 2014-03-01 11:53:31 -05:00
Mark Pictor a8ffbc17d3 missing colon in error messages 2014-03-01 11:53:31 -05:00
Mark Pictor 7f0a0f852f fix tests that were broken by file name changes 2014-03-01 11:53:31 -05:00
Mark Pictor cd0d8b496b cannot treat the schema scanner source as a config file, so add /*WARNING*/ 2014-03-01 11:53:31 -05:00
Mark Pictor 4d945de475 perplex/lemon/re2c not found messages can confuse users
make find_package quiet for all 3, then if all were found, print a message
to that effect.
2014-03-01 11:53:30 -05:00
Mark Pictor bbe607be60 fix copy/paste error in cmake message 2014-03-01 11:53:30 -05:00
Mark Pictor 38467bdca3 add build logic for unity builds (mostly in generated CMLists) 2014-03-01 11:53:30 -05:00
Mark Pictor 78d99f2f4e change generated CMLists ws to better match starseeker's ws 2014-03-01 11:53:30 -05:00
Mark Pictor 5c021b2b7f tests were broken because macro name changed
make two variables CACHE INTERNAL so that their values are available in other scopes (i.e. in test dirs)
2014-03-01 11:53:30 -05:00
Cliff Yapp 10fb7419b5 More whitespace and case tweaks 2014-03-01 11:53:30 -05:00
Cliff Yapp f4ac673b71 whitespace and case changes on .cmake files 2014-03-01 11:53:30 -05:00
Cliff Yapp 1696fea0c7 Case and whitespace on toplevel CMake files 2014-03-01 11:53:30 -05:00
Cliff Yapp 44e02c957a whitespace changes 2014-03-01 11:53:30 -05:00
Cliff Yapp c0e74a9eef Add CMake footer comment to CMake files 2014-02-28 22:06:09 -05:00
Mark Pictor a7579f0bc9 remove helper function header - code moved to headers for individual types/entities 2014-02-28 22:02:07 -05:00
Mark Pictor 317b40bff0 minor formatting changes 2014-02-28 22:02:07 -05:00
Mark Pictor d4d42b7d1c print helper functions in header 2014-02-28 22:02:07 -05:00
davyw 492f455598 allow schema scanner to build on windows 2014-02-28 22:02:07 -05:00
Mark Pictor 2ccc5ce360 add underscore to schema shortname for readability - Sdai -> Sdai_ 2014-02-28 22:02:07 -05:00
Mark Pictor 05a74dedd8 change code generation message a bit 2014-02-28 22:02:07 -05:00
Mark Pictor 5043c035a3 renamed enums, selects don't get their own files 2014-02-28 22:02:07 -05:00
Mark Pictor 426e2b4ab3 add two cmake messages 2014-02-28 22:02:07 -05:00
Mark Pictor 2d651bfad4 unnecessary variable in a macro 2014-02-28 22:02:07 -05:00
starseeker c6f0c44a02 print file count, not list of all files, when generating. 2014-02-28 22:02:07 -05:00
starseeker 6533032fd9 workaround makefile corruption by changing how file lists are handled 2014-02-28 22:02:07 -05:00
Mark Pictor 26822ef959 exp2cxx wasn't running because script args were handled incorrectly 2014-02-28 22:02:07 -05:00
Mark Pictor 86f884b399 TODO 2014-02-28 22:02:06 -05:00
Mark Pictor 4fd5dd9f74 improve cmake comments, user messages 2014-02-28 22:02:06 -05:00
Mark Pictor 8e08f71fe8 don't build schema scanner unless schemas are to be built 2014-02-28 22:02:06 -05:00
Mark Pictor b320bfe3f7 generate a short schema name in the schema scanner
this name is one of:
* the schema file name without extension,
* the schema dir name if in sc/data/ and 3+ chars
* or the official schema name on the SCHEMA line.
2014-02-28 22:02:06 -05:00
Mark Pictor 34d917fb19 update scanner to match renamed schema macros file 2014-02-28 22:02:06 -05:00
Mark Pictor 86bae779b0 inching forward on schema scanner 2014-02-28 22:02:06 -05:00
Mark Pictor b15ba38edf try again to make msvc use same dir as other compilers 2014-02-28 22:02:06 -05:00
Mark Pictor 96bd4520b5 move more schema logic into new file, rename file 2014-02-28 22:02:06 -05:00
Mark Pictor 5dd996d38d add mkDirIfNone(), like mkdir but no error if path is already a dir 2014-02-28 22:02:06 -05:00
Mark Pictor 5384fe0dbb fix locate_schema macro 2014-02-28 22:02:06 -05:00
Mark Pictor 2d4346dd5a better way of printing user messages after everything else 2014-02-28 22:02:06 -05:00
Mark Pictor ce6a37e49a move output dirs logic into separate file so schema_scanner can use it as well 2014-02-28 22:02:06 -05:00
Mark Pictor 0b2f9ee3fc move packaging and uninstall into SC_Build_opts.cmake 2014-02-28 22:02:06 -05:00
Mark Pictor a9120d79f7 move logic related to creating sc_cf.h, sc_version_string.h to own file 2014-02-28 22:02:06 -05:00
Mark Pictor e1fe3e0b9f move lexer/parser generation logic into own file 2014-02-28 22:02:05 -05:00
Mark Pictor d14e7670c2 put cmake locale stuff in its own file 2014-02-28 22:02:05 -05:00
Mark Pictor 37a95f5e63 move build optons, build/install dirs, etc to SC_Build_opts.cmake 2014-02-28 22:02:05 -05:00
Mark Pictor 207d6c26c2 remove old message 2014-02-28 22:02:05 -05:00
Mark Pictor 7de64b6bc4 rename SC_Utils.cmake to SC_Targets.cmake 2014-02-28 22:02:05 -05:00
Mark Pictor a4e96f62ff put path macros in a separate file, and include it 2014-02-28 22:02:05 -05:00
Mark Pictor 993c40f6ad MSVC insists on putting schema_scanner.exe in a different dir 2014-02-28 22:02:05 -05:00
Mark Pictor a035292cf0 another TODO 2014-02-28 22:02:05 -05:00
Mark Pictor 6ca7b04dfd cxxSchemaMacros.cmake - will contain macros used in the generated CMakeLists files 2014-02-28 22:02:05 -05:00
Mark Pictor 427ecaf09f add schema scanner README 2014-02-28 22:02:05 -05:00
Mark Pictor b7a8ac4cbb make build/schema dir 2014-02-28 22:02:05 -05:00
Mark Pictor 2e6ee6695a cmake changes to match new behavior of scanner 2014-02-28 22:02:05 -05:00
Mark Pictor 86bf2dff99 maybe this will force MSVC to behave?
http://stackoverflow.com/questions/7229571/cmake-visual-studio-debug-folder
http://www.cmake.org/cmake/help/v2.8.8/cmake.html#prop_tgt:RUNTIME_OUTPUT_DIRECTORY_CONFIG
2014-02-28 22:02:05 -05:00
Mark Pictor c4fde8c96f comment, formatting 2014-02-28 22:02:04 -05:00
Mark Pictor 3088d3d63f check for errors in 2 places 2014-02-28 22:02:04 -05:00
Mark Pictor 99fbadcdfd print path to the dir containing the generated CMakeLists for CMake 2014-02-28 22:02:04 -05:00
Mark Pictor 685e95f618 windows needs _snprintf 2014-02-28 22:02:04 -05:00
Mark Pictor b8d35ce517 improve formatting of generated CMakeLists 2014-02-28 22:02:04 -05:00
Mark Pictor d1f57453dd print ss contents not address 2014-02-28 22:02:04 -05:00
Mark Pictor 86302fb0f3 take a stab at writing a CMakeLists.txt for the schema 2014-02-28 22:02:04 -05:00
Mark Pictor 4efb670ddf used wrong variable to set output dir 2014-02-28 22:02:04 -05:00
Mark Pictor 5bdac5427b use schemas subdir for output? 2014-02-28 22:02:04 -05:00
Mark Pictor a01fa5708a start on creating cmakelists within the schema scanner 2014-02-28 22:02:04 -05:00
Mark Pictor ec4eed7367 rename schemaScanner to .cpp 2014-02-28 22:02:04 -05:00
Mark Pictor c080fbc8dc aggregates are always builtin 2014-02-28 22:02:04 -05:00
Mark Pictor 599f51891d always clean and rebuild the schema scanner when cmake executes 2014-02-28 22:02:04 -05:00
Mark Pictor ce4227c6b5 don't print file names for built in types 2014-02-28 22:02:04 -05:00
Mark Pictor 0dd18d246a improve some comments 2014-02-28 22:02:03 -05:00
Mark Pictor 1cc0beec4b eliminate gcc warnings 2014-02-28 22:02:03 -05:00
Mark Pictor aa8842ea56 allow schema scanner to be built when sc_version_string.h doesn't exist 2014-02-28 22:02:03 -05:00
Mark Pictor 2cd5d494f9 move keywords from express.[ch] to exp_kw.[ch] 2014-02-28 22:02:03 -05:00
Mark Pictor 6092c9b29f move some functions from express.[ch] to info.[ch] 2014-02-28 22:02:03 -05:00
Mark Pictor 8f57958813 print better messages in schemaScanner.cmake 2014-02-28 22:02:03 -05:00
Mark Pictor 10ef152fc6 assertion - is a type really a type? 2014-02-28 22:02:03 -05:00
Mark Pictor 95d339e2c7 use schema scanner in data/CMakeLists.txt 2014-02-28 22:02:03 -05:00
Mark Pictor 25521ee3af make the schema scanner macro do more work; getting close now 2014-02-28 22:02:03 -05:00
Mark Pictor f7c56d3e5a move fns 2014-02-28 22:02:03 -05:00
Mark Pictor b2b0039d2f update exp2cxx to use new code 2014-02-28 22:02:03 -05:00
Mark Pictor 91e9528afe perhaps I shouldn't print a type name for entities and vice versa 2014-02-28 22:02:03 -05:00
Mark Pictor 52acad573b move some functions related to class/file names into class_strings.c/h
this is to reduce the number of source files necessary for the schema scanner
2014-02-28 22:02:02 -05:00
Mark Pictor 44ab3e3352 run the schema scanner from data/CMakeLists.txt 2014-02-28 22:02:02 -05:00
Mark Pictor 30b04d741f update schema scanner 2014-02-28 22:02:02 -05:00
Mark Pictor abf0541ae9 remove TODO file - both items in it were fixed long ago 2014-02-28 22:02:02 -05:00
Mark Pictor bb41fd4863 initial revision of schema scanner 2014-02-28 22:02:02 -05:00
Mark Pictor 9c5e27590d expparse.y revision log dates to the 90's - remove most of it 2014-02-28 22:02:02 -05:00
Mark Pictor 0b16a413f7 use 'const char *' for filename 2014-02-28 21:55:43 -05:00
davyw 0d533f55df Split classes files into classes_attribute, classes_entity and classes_type. 2014-02-28 21:55:43 -05:00
davyw c6cfc06f4f Added import/export macro for sc_mkdir. 2014-02-28 21:55:43 -05:00
Mark Pictor d4a21dd654 const warning 2014-02-28 21:55:43 -05:00
Mark Pictor 166db7d178 use sc_mkdir 2014-02-28 21:55:43 -05:00
Mark Pictor 0bf73eece7 cross-platform mkdir 2014-02-28 21:55:43 -05:00
davyw 5a6b972e47 Moved type init code to type specific files. 2014-02-28 21:55:43 -05:00
davyw 9e6b419a53 Write enumeration and select types to their own files. 2014-02-28 21:55:43 -05:00
davyw 33b0629e1e Fixes to get generated files to build. 2014-02-28 21:55:43 -05:00
davyw 05ade5ca60 Split generated c++ code in a separate file for each entity. 2014-02-28 21:55:43 -05:00
Mark 0a46b861a5 Merge pull request #288 from stepcode/review/prettyprint_DIV
pretty print: integer and real division have different operators
2014-02-26 21:00:13 -05:00
Mark Pictor 2c8a05fa0a add exppp div/slash test to ensure this stays fixed 2014-02-25 18:48:13 -05:00
Mark Pictor eb9193038c commit 01f6e26 fixed integer division (DIV) but broke real division (/) 2014-02-25 17:36:00 -05:00
Mark Pictor d691bdf4d2 message for syntax error didn't actually say syntax error 2014-02-25 17:23:21 -05:00
Mark c686fc163b Merge pull request #287 from stepcode/review/prettyprint_VAR
don't omit 'VAR' keyword when prettyprinting
2014-02-24 21:02:04 -05:00
Mark Pictor 587ce0f16b use flags.var in exppp 2014-02-24 20:39:20 -05:00
Mark Pictor 7ccf768adf neaten up header 2014-02-24 20:37:55 -05:00
Mark Pictor 14c854e0df add flags.var to parser for procedure params marked VAR 2014-02-24 20:37:32 -05:00
Mark 9899ad937b Merge pull request #286 from stepcode/review/exppp_var_order
preserve EXPPP variable order
2014-02-23 14:58:34 -05:00
Mark 171671db1f Don't aggressively wrap SUBTYPEs - leave as before 2014-02-23 14:58:10 -05:00
Mark Pictor d4c7d1bf6f put each SUBTYPE/SUPERTYPE on its own line, indent ONEOF 2014-02-20 20:13:36 -05:00
Mark Pictor d10d955f74 when pretty-printing, order LOCAL vars the same way as in source file 2014-02-20 19:18:50 -05:00
Mark Pictor 626635b644 use Variable.offset to order LOCAL variables
previously, this was only used for attr order in Entity's

these two uses should not conflict
2014-02-20 19:16:03 -05:00
Mark f64d8f75ca Merge pull request #285 from stepcode/review/ap203min_regression
ap203min regression
2014-02-17 20:46:33 -05:00
Mark Pictor 4c13ff422f cleanup in selects.c 2014-02-17 19:52:46 -05:00
Mark Pictor caf887ed03 improve formatting of generated select class code 2014-02-17 19:32:41 -05:00
Mark Pictor 860d612086 test SDAI_Select assignment operator 2014-02-17 19:29:18 -05:00
Mark Pictor 2685dbcf31 generated code: in select assignment operator, call base class assignment operator 2014-02-17 19:27:53 -05:00
Mark Pictor 1ec21780c6 Add virtual assignment operator and copy constructor to SDAI_Select
Related to commit f43a106ac3 (removal of pure virtual assignment operator) -
that commit eliminated an MSVC linker error, but caused a regression on linux
2014-02-17 18:37:54 -05:00
Mark 58dd89044c Merge pull request #283 from stepcode/dw/msvc_linker_fixes
Msvc linker fixes + static libs
2014-02-09 19:50:41 -05:00
davyw 995a8a7fe9 Added libraries to SC_ADDEXEC libslist parameter.
When building static libs, all dependent libraries need to be provided to liblist.
When building shared libs, this is not needed, but does not break the build.
2014-02-09 22:56:07 +01:00
davyw e7bbcc0909 Split SC_ADDEXEC macro to handle static and shared libs build. 2014-02-05 22:30:55 +01:00
davyw bc298808dd Removed MSVC exclusion for SC_BUILD_STATIC_LIBS. 2014-02-05 22:29:55 +01:00
davyw 0c0ff74429 Removed duplicate definition of SchemaInit function.
SchemaInit is already declared in 'schema.h'.
2014-02-04 21:22:17 +01:00
davyw f3c56ceafc Added SC_SCHEMA_EXPORT macro's for generated types.
Fixes MSVC linker errors in user code.
2014-02-03 22:03:58 +01:00
Mark ca1a34a698 Merge pull request #281 from stepcode/review/ur-redecl
Redeclared attrs, qualifiers, and uniqueness rules
2014-01-19 09:31:58 -08:00
Mark Pictor ee86226f5e print warning rather than removing the qualifiers from redeclared attrs in URs 2014-01-08 20:00:53 -05:00
Mark Pictor 2fd8d1a0be don't print misleading redeclaration warning 2014-01-07 20:07:23 -05:00
Mark Pictor 98bc5049f7 exppp: redeclared attrs in URs shouldn't have qualifiers 2014-01-07 20:03:51 -05:00
Mark Pictor 5fa2ebb677 schema for redeclaration and UR 2014-01-07 20:02:50 -05:00
Mark f4369ba902 Merge pull request #280 from stepcode/review/msvc_linker_fixes
Review/msvc linker fixes
2013-12-30 08:18:28 -08:00
Mark e343668210 Merge pull request #279 from stepcode/review/lost-qualifiers
Lost qualifiers on inverse attributes and uniqueness rules
2013-12-30 08:18:14 -08:00
davyw 02ef60aee2 Added DEFINE_DLL_IMPORTS to add_schema_dependent_test macro.
Added stepcore to libraries of aggregate_bound_runtime test to fix linker error.
2013-12-29 18:23:55 +01:00
davyw 530c796284 Added SC_SCHEMA_EXPORT macro for each generated entity class. 2013-12-29 18:19:10 +01:00
davyw f43a106ac3 Removed pure virtual operator= reference from SDAI_Select class.
(Results in linking errors on windows otherwise)
2013-12-29 18:18:20 +01:00
davyw 46951e3b32 Added import/export macro's for STEPattribute operator==, operator!= and sameADesc(). 2013-12-28 08:26:00 +01:00
Mark Pictor 8f72192262 add inverse and unique qualifiers tests for exp2cxx 2013-12-27 14:12:09 -05:00
Mark Pictor 3ee5fc0ca8 clean up a bit 2013-12-27 14:12:09 -05:00
Mark Pictor d061b146d5 makes more sense to have these schemas under test/unitary_schemas 2013-12-27 14:12:09 -05:00
Mark Pictor b3a284a59a add exppp test for inverse qualifiers 2013-12-27 14:12:09 -05:00
Mark Pictor 4a4c39fae9 rename lost_qualifiers.*, modify files accordingly 2013-12-27 14:12:09 -05:00
Mark Pictor 29a15c5db9 in exppp, print inverse attrs as expressions 2013-12-27 14:12:09 -05:00
Mark Pictor 17c518cd12 use Expression for Unique rules in exp2cxx 2013-12-27 14:12:09 -05:00
Mark Pictor 49a6227103 add test for lost qualifiers on unique rules 2013-12-27 14:12:08 -05:00
Mark Pictor a8a7a723c8 actually build and test long string test 2013-12-27 14:12:08 -05:00
Mark Pictor 21e029c362 wrong variable name for testing 2013-12-27 14:12:08 -05:00
Mark Pictor c0e6d32290 fix compile error with exppp test for long strings 2013-12-27 14:12:08 -05:00
Mark Pictor d68b60fb39 change lost qualifiers test schema to match exppp output formatting exactly 2013-12-27 14:12:08 -05:00
Mark Pictor a379152c80 reformat a comment 2013-12-27 14:12:08 -05:00
Mark Pictor c56ee55128 update exppp to use Expression for Unique rules 2013-12-27 14:12:08 -05:00
Mark Pictor 9eba5b18dd sync generated files 2013-12-27 14:12:08 -05:00
Mark Pictor 701f90025c use Expression for Unique rules
this changes libexpress only - must change exppp, exp2cxx, exp2python
2013-12-27 14:12:08 -05:00
Mark Pictor 66d6406ed9 test schema for lost qualifiers - still need to automate the test 2013-12-27 14:12:08 -05:00
Mark Pictor 19e96fa6fa update generated parser files 2013-12-27 14:12:08 -05:00
Mark Pictor 0754642e31 attribute_decl comment 2013-12-27 14:12:07 -05:00
Mark Pictor 0c0714260a is it really this easy to do qualified inverse attrs right? 2013-12-27 14:11:51 -05:00
Mark Pictor 05333b3185 comment some productions in expparse.y 2013-12-23 15:24:34 -05:00
Mark 6772b3a64e Merge pull request #277 from stepcode/review/msvc_fixes
Review/msvc fixes
2013-12-15 13:28:16 -08:00
davyw 31f0644b26 Removed explicit exports of template class std::string.
(To resolve linker error on MSVC 2010)
2013-12-05 23:00:24 +01:00
davyw b9922e2e0a Added include files to make sure functions from pretty_subtype.c get exported properly on windows. 2013-12-05 22:59:06 +01:00
davyw 95597e8a71 Moved variable declaration to top of function to fix compiler errors on MSVC. 2013-12-05 22:58:16 +01:00
Mark Pictor a13481e543 update AP242 to v1.27 (N8324)
retrieved from
http://stepmod.cvs.sourceforge.net/viewvc/stepmod/stepmod/data/modules/ap242_managed_model_based_3d_engineering/mim_lf.exp?revision=1.27
2013-11-17 13:26:04 -05:00
215 changed files with 45241 additions and 49302 deletions
+87 -386
View File
@@ -32,427 +32,128 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# *******************************************************************
# *** SC's CMakeLists.txt ***
# *** STEPcode's CMakeLists.txt ***
# *******************************************************************
# This file contains the top level CMakeLists.txt logic for the
# SC software package.
# STEPcode software package.
PROJECT(SC)
project(SC)
# SC version
SET(SC_VERSION_MAJOR 0)
SET(SC_VERSION_MINOR 7-dev)
SET(SC_VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR})
set(SC_VERSION_MAJOR 0)
set(SC_VERSION_MINOR 7-dev)
set(SC_VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR})
# SC ABI version. SC_ABI_SOVERSION should be incremented
# for each release introducing API incompatibilities
SET(SC_ABI_SOVERSION 2)
SET(SC_ABI_VERSION ${SC_ABI_SOVERSION}.0.0)
set(SC_ABI_SOVERSION 2)
set(SC_ABI_VERSION ${SC_ABI_SOVERSION}.0.0)
# Minimum required version of CMake
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
IF(COMMAND CMAKE_POLICY)
cmake_minimum_required(VERSION 2.8.7)
if(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND CMAKE_POLICY)
IF( NOT DEFINED INCLUDE_INSTALL_DIR )
SET( INCLUDE_INSTALL_DIR include )
ENDIF( NOT DEFINED INCLUDE_INSTALL_DIR )
IF( NOT DEFINED LIB_INSTALL_DIR )
SET( LIB_INSTALL_DIR lib )
ENDIF( NOT DEFINED LIB_INSTALL_DIR )
IF( NOT DEFINED BIN_INSTALL_DIR )
SET( BIN_INSTALL_DIR bin )
ENDIF( NOT DEFINED BIN_INSTALL_DIR )
IF( NOT DEFINED SC_BUILD_TYPE )
SET( SC_BUILD_TYPE "Debug" CACHE STRING "Build type" ) # By default set debug build
ENDIF( NOT DEFINED SC_BUILD_TYPE )
IF(NOT SC_IS_SUBBUILD)
SET(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE} CACHE INTERNAL "Build type, immutable" FORCE )
ELSE(NOT SC_IS_SUBBUILD)
SET(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE} )
ENDIF(NOT SC_IS_SUBBUILD)
# Define helper macro OPTION_WITH_DEFAULT
MACRO( OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT )
IF( NOT DEFINED ${OPTION_NAME} )
SET( ${OPTION_NAME} ${OPTION_DEFAULT} )
ENDIF( NOT DEFINED ${OPTION_NAME} )
OPTION( ${OPTION_NAME} "${OPTION_STRING}" ${${OPTION_NAME}} )
ENDMACRO( OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT )
# build shared libs by default
OPTION_WITH_DEFAULT(SC_BUILD_SHARED_LIBS "Build shared libs" ON )
# don't build static libs by default
OPTION_WITH_DEFAULT(SC_BUILD_STATIC_LIBS "Build static libs" OFF)
OPTION_WITH_DEFAULT(SC_PYTHON_GENERATOR "Compile exp2python" ON)
OPTION_WITH_DEFAULT(SC_CPP_GENERATOR "Compile exp2cxx" ON)
OPTION_WITH_DEFAULT(SC_MEMMGR_ENABLE_CHECKS "Enable sc_memmgr's memory leak detection" OFF)
OPTION_WITH_DEFAULT(SC_TRACE_FPRINTF "Enable extra comments in generated code so the code's source in exp2cxx may be located" OFF)
if(NOT DEFINED SC_SDAI_ADDITIONAL_EXES_SRCS )
set( SC_SDAI_ADDITIONAL_EXES_SRCS "" CACHE STRING "Source files for additional executables to be linked with SDAI libs" )
endif(NOT DEFINED SC_SDAI_ADDITIONAL_EXES_SRCS )
if( NOT DEFINED SC_BUILD_SCHEMAS )
set( SCHEMAS_WARNING TRUE )
#this makes SC_BUILD_SCHEMAS show up in cmake-gui
SET(SC_BUILD_SCHEMAS "ALL" CACHE string "Semicolon-separated list of paths to EXPRESS schemas to be built" )
endif( NOT DEFINED SC_BUILD_SCHEMAS )
if ("${CMAKE_VERSION}" VERSION_GREATER 2.99)
CMAKE_POLICY(SET CMP0026 OLD)
endif ("${CMAKE_VERSION}" VERSION_GREATER 2.99)
endif(COMMAND CMAKE_POLICY)
# CMake derives much of its functionality from modules, typically
# stored in one directory - let CMake know where to find them.
SET(SC_CMAKE_DIR "${SC_SOURCE_DIR}/cmake")
set(SC_CMAKE_DIR "${SC_SOURCE_DIR}/cmake")
if(NOT IS_SUBBUILD)
SET(CMAKE_MODULE_PATH "${SC_CMAKE_DIR};${CMAKE_MODULE_PATH}")
set(CMAKE_MODULE_PATH "${SC_CMAKE_DIR};${CMAKE_MODULE_PATH}")
else(NOT IS_SUBBUILD)
SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${SC_CMAKE_DIR}")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${SC_CMAKE_DIR}")
endif(NOT IS_SUBBUILD)
INCLUDE(${SC_CMAKE_DIR}/SC_Utils.cmake)
# testing and compilation options, build output dirs, install dirs, uninstall, package creation, etc
include(${SC_CMAKE_DIR}/SC_Build_opts.cmake)
# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables and set them
# to "C" so things like date output are as expected
SET(_orig_lc_all $ENV{LC_ALL})
SET(_orig_lc_messages $ENV{LC_MESSAGES})
SET(_orig_lang $ENV{LANG})
IF(_orig_lc_all)
SET(ENV{LC_ALL} C)
ENDIF(_orig_lc_all)
IF(_orig_lc_messages)
SET(ENV{LC_MESSAGES} C)
ENDIF(_orig_lc_messages)
IF(_orig_lang)
SET(ENV{LANG} C)
ENDIF(_orig_lang)
# SC_ADDEXEC and SC_ADDLIB macros, dllimport/export, etc
include(${SC_CMAKE_DIR}/SC_Targets.cmake)
# Macros related to paths
include(${SC_CMAKE_DIR}/SC_Paths.cmake)
# locale stuff
include(${SC_CMAKE_DIR}/SC_Locale.cmake)
# logic related to regenerating the lexer and parser source code
include(${SC_CMAKE_DIR}/SC_Regenerate.cmake)
if(NOT DEFINED SC_SDAI_ADDITIONAL_EXES_SRCS)
set(SC_SDAI_ADDITIONAL_EXES_SRCS "" CACHE STRING "Source files for additional executables to be linked with SDAI libs")
endif(NOT DEFINED SC_SDAI_ADDITIONAL_EXES_SRCS)
if(NOT DEFINED SC_BUILD_SCHEMAS)
list(APPEND CONFIG_END_MESSAGES
"** CMake variable SC_BUILD_SCHEMAS was not set. Defaults to building ALL schemas, which will take a"
" while; see http://stepcode.org/mw/index.php?title=STEPcode_CMake_variables#SC_BUILD_SCHEMAS")
#this makes SC_BUILD_SCHEMAS show up in cmake-gui
set(SC_BUILD_SCHEMAS "ALL" CACHE string "Semicolon-separated list of paths to EXPRESS schemas to be built")
endif(NOT DEFINED SC_BUILD_SCHEMAS)
list(APPEND CONFIG_END_MESSAGES
".. Don't worry about any messages above about missing headers or failed tests, as long as"
" you see 'Configuring done' below. Headers and features vary by compiler."
".. Generating step can take a while if you are building several schemas.")
# create config headers sc_cf.h and sc_version_string.h
include(${SC_CMAKE_DIR}/SC_Config_Headers.cmake)
#---------------------------------------------------------------------
# Coverage option
OPTION_WITH_DEFAULT( SC_ENABLE_COVERAGE "Enable code coverage test" OFF )
IF(SC_ENABLE_COVERAGE)
SET(SC_ENABLE_TESTING ON CACHE BOOL "Testing enabled by coverage option" FORCE)
# build static libs, better coverage report
SET(SC_BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs" FORCE )
SET(SC_BUILD_STATIC_LIBS ON CACHE BOOL "Build static libs" FORCE )
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage" CACHE STRING "Extra linker flags required by code coverage" FORCE)
SET(SC_BUILD_TYPE "Debug" CACHE STRING "Build type required by testing framework" FORCE)
SET( SC_PYTHON_GENERATOR OFF ) #won't build with static libs
ENDIF(SC_ENABLE_COVERAGE)
#---------------------------------------------------------------------
# Testing option
OPTION_WITH_DEFAULT( SC_ENABLE_TESTING "Enable unittesting framework" OFF )
IF(SC_ENABLE_TESTING)
if( NOT DEFINED SC_BUILD_SCHEMAS )
set( SC_BUILD_SCHEMAS "ALL" ) #test all schemas, unless otherwise specified
endif()
INCLUDE(CTest)
ENABLE_TESTING()
ENDIF(SC_ENABLE_TESTING)
#---------------------------------------------------------------------
# The following logic is what allows binaries to run successfully in
# the build directory AND install directory. Thanks to plplot for
# identifying the necessity of setting CMAKE_INSTALL_NAME_DIR on OSX.
# Documentation of these options is available at
# http://www.cmake.org/Wiki/CMake_RPATH_handling
# use, i.e. don't skip the full RPATH for the build tree
set(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# the RPATH/INSTALL_NAME_DIR to be used when installing
if (NOT APPLE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:\$ORIGIN/../lib")
endif(NOT APPLE)
# On OSX, we need to set INSTALL_NAME_DIR instead of RPATH
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#variable:CMAKE_INSTALL_NAME_DIR
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
# add the automatically determined parts of the RPATH which point to
# directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
#-----------------------------------------------------------------------------
# Output directories.
# When this is a subbuild, assume that the parent project controls these
IF( NOT SC_IS_SUBBUILD )
IF(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
ENDIF(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
IF(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
ENDIF(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
IF(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
ENDIF(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
FOREACH(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES})
STRING(TOUPPER "${CFG_TYPE}" CFG_TYPE)
IF(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
SET("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
ENDIF(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
IF(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
SET("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
ENDIF(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
IF(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
ENDIF(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
ENDFOREACH()
ENDIF( NOT SC_IS_SUBBUILD )
#-----------------------------------------------------------------------------
# Configure install locations.
# The location in which to install SC. Need a good Debug location
# for Windows. Only do this if CMAKE_INSTALL_PREFIX hasn't been set
# already, to try and allow parent builds (if any) some control.
if(NOT SC_IS_SUBBUILD)
IF(NOT WIN32)
IF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
SET(SC_INSTALL_PREFIX "${SC_SOURCE_DIR}/../sc-install")
ELSE()
SET(SC_INSTALL_PREFIX "/usr/local")
ENDIF()
ENDIF(NOT WIN32)
SET( SC_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE
PATH "Install prefix prepended to target to create install location" )
SET( CMAKE_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE INTERNAL "Prefix prepended to install directories if target destination is not absolute, immutable" FORCE )
endif(NOT SC_IS_SUBBUILD)
OPTION(SC_BUILD_EXPRESS_ONLY "Only build express parser." OFF)
MARK_AS_ADVANCED(SC_BUILD_EXPRESS_ONLY)
# Take the sc config file template as the starting point for
# sc_cf.h.in - scripts may need to append to the template, so
# it is read into memory initially.
SET(CONFIG_H_FILE ${SC_BINARY_DIR}/include/sc_cf.h.in)
set_source_files_properties(${CONFIG_H_FILE} PROPERTIES GENERATED TRUE)
set(CMAKE_CURRENT_PROJECT SC)
define_property(GLOBAL PROPERTY SC_CONFIG_H_CONTENTS BRIEF_DOCS "config.h.in contents" FULL_DOCS "config.h.in contents for SC project")
if(NOT COMMAND CONFIG_H_APPEND)
macro(CONFIG_H_APPEND PROJECT_NAME NEW_CONTENTS)
if(PROJECT_NAME)
get_property(${PROJECT_NAME}_CONFIG_H_CONTENTS GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS)
set(${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS "${${PROJECT_NAME}_CONFIG_H_CONTENTS}${NEW_CONTENTS}")
set_property(GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS "${${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS}")
endif(PROJECT_NAME)
endmacro(CONFIG_H_APPEND NEW_CONTENTS)
endif(NOT COMMAND CONFIG_H_APPEND)
file(READ ${SC_SOURCE_DIR}/include/sc_cf_cmake.h.in CONFIG_H_FILE_CONTENTS)
CONFIG_H_APPEND(SC "${CONFIG_H_FILE_CONTENTS}")
# The Express parser uses the tools Perplex, RE2C and Lemon to generate code
# from higher level inputs. Depending on available tools and options, the
# SC build can either re-generate code as part of the build, or use cached
# files that are ready for compilation.
#
# SC_GENERATE_LEXER_PARSER is the "high level" control a user sets to determine
# how the SC build will interact (or not) with these tools. AUTO (the
# default) means it will search for the necessary tools, and use them only if
# everything is found. If not, it will fall back to the cached versions. If
# this option is set to ON and the necessary tools are not found, the
# configure step will fail. If it is set to OFF, SC will not even try to use
# the generators and will instead use the cached sources.
if(NOT SC_GENERATE_LEXER_PARSER)
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
else(NOT SC_GENERATE_LEXER_PARSER)
string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER)
endif(NOT SC_GENERATE_LEXER_PARSER)
set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS AUTO ON OFF)
if (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
message(WARNING "Unknown value ${SC_GENERATE_LEXER_PARSER} supplied for BRLCAD_WORD_SIZE - defaulting to AUTO")
message(WARNING "Valid options are AUTO, ON and OFF")
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
endif (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
# If the generators have not been turned off, we need to check for them
if(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
find_package(LEMON)
find_package(RE2C)
find_package(PERPLEX)
if(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
# Templates may be anywhere - make sure we have a stable path if a relative
# path was specified at CMake time
get_filename_component(lemon_template_fpath "${LEMON_TEMPLATE}" ABSOLUTE)
if(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
get_filename_component(LEMON_TEMPLATE "${CMAKE_BINARY_DIR}/${LEMON_TEMPLATE}" ABSOLUTE)
endif(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
get_filename_component(perplex_template_fpath "${PERPLEX_TEMPLATE}" ABSOLUTE)
if(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
get_filename_component(PERPLEX_TEMPLATE "${CMAKE_BINARY_DIR}/${PERPLEX_TEMPLATE}" ABSOLUTE)
endif(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
if(NOT COMMAND LEMON_TARGET)
include(${SC_CMAKE_DIR}/LEMON_Util.cmake)
endif(NOT COMMAND LEMON_TARGET)
if(NOT COMMAND PERPLEX_TARGET)
include(${SC_CMAKE_DIR}/PERPLEX_Util.cmake)
endif(NOT COMMAND PERPLEX_TARGET)
set(SC_GENERATE_LP_SOURCES 1)
else(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
if("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but one or more components of the Perplex/RE2C/Lemon toolchain were not found.\n")
else("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
set(SC_GENERATE_LP_SOURCES 0)
endif("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
endif(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
else(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
set(SC_GENERATE_LP_SOURCES 0)
endif(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
INCLUDE(CheckLibraryExists)
INCLUDE(CheckIncludeFile)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckTypeSize)
INCLUDE(CMakePushCheckState)
INCLUDE(CheckCXXSourceRuns)
CHECK_INCLUDE_FILE(ndir.h HAVE_NDIR_H)
CHECK_INCLUDE_FILE(stdarg.h HAVE_STDARG_H)
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILE(sysent.h HAVE_SYSENT_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
CHECK_INCLUDE_FILE(process.h HAVE_PROCESS_H)
CHECK_INCLUDE_FILE(io.h HAVE_IO_H)
CHECK_FUNCTION_EXISTS(abs HAVE_ABS)
CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
CHECK_FUNCTION_EXISTS(getopt HAVE_GETOPT)
CHECK_TYPE_SIZE("ssize_t" SSIZE_T)
set( TEST_STD_THREAD "
#include <iostream>
#include <thread>
void do_work() {
std::cout << \"thread\" << std::endl;
}
int main() {
std::thread t(do_work);
t.join();
}
" )
cmake_push_check_state()
if( UNIX )
set( CMAKE_REQUIRED_FLAGS "-pthread -std=c++0x" )
else( UNIX )
# vars probably need set for MSVC11, embarcadero, etc
endif( UNIX )
CHECK_CXX_SOURCE_RUNS( "${TEST_STD_THREAD}" HAVE_STD_THREAD ) #quotes are *required*!
cmake_pop_check_state()
# Now that all the tests are done, configure the sc_cf.h file:
get_property(CONFIG_H_FILE_CONTENTS GLOBAL PROPERTY SC_CONFIG_H_CONTENTS)
file(WRITE ${CONFIG_H_FILE} "${CONFIG_H_FILE_CONTENTS}")
configure_file(${CONFIG_H_FILE} ${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_cf.h)
################ create sc_version_string.h, http://stackoverflow.com/questions/3780667
# Using 'ver_string' instead of 'sc_version_string.h' is a trick to force the
# command to always execute when the custom target is built. It works because
# a file by that name never exists.
configure_file(${SC_CMAKE_DIR}/sc_version_string.cmake ${SC_BINARY_DIR}/sc_version_string.cmake @ONLY)
add_custom_target(version_string ALL DEPENDS ver_string )
# creates sc_version_string.h using cmake script
add_custom_command(OUTPUT ver_string ${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${SC_SOURCE_DIR}
-DBINARY_DIR=${SC_BINARY_DIR}
-P ${SC_BINARY_DIR}/sc_version_string.cmake)
# sc_version_string.h is a generated file
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
PROPERTIES GENERATED TRUE
HEADER_FILE_ONLY TRUE )
################
if(MSVC)
# add_definitions( -Wall )
add_definitions( -D__MSVC__ -D__WIN32__ )
add_definitions(-D__MSVC__ -D__WIN32__)
# Disable warning for preferred usage of secure functions (example strcpy should be strcpy_s, ...)
add_definitions( -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS )
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
elseif(BORLAND)
add_definitions( -D__BORLAND__ -D__WIN32__ )
add_definitions(-D__BORLAND__ -D__WIN32__)
else()
add_definitions( -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long )
add_definitions(-pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long)
endif()
include_directories(
${SC_SOURCE_DIR}/include
${SC_BINARY_DIR}/include
)
)
ADD_SUBDIRECTORY(src/base)
ADD_SUBDIRECTORY(src/express)
ADD_SUBDIRECTORY(src/exppp)
ADD_SUBDIRECTORY(src/exp2cxx)
ADD_SUBDIRECTORY(src/exp2python)
ADD_SUBDIRECTORY(src/clstepcore)
ADD_SUBDIRECTORY(src/cleditor)
ADD_SUBDIRECTORY(src/cldai)
ADD_SUBDIRECTORY(src/clutils)
if( NOT WIN32 ) # don't build cllazyfile on windows until export/import macros are in place
ADD_SUBDIRECTORY( src/cllazyfile )
endif( NOT WIN32 )
ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(data)
IF(SC_ENABLE_TESTING)
ADD_SUBDIRECTORY( test )
ENDIF(SC_ENABLE_TESTING)
ADD_SUBDIRECTORY(doc)
add_subdirectory(src/base)
add_subdirectory(src/express)
add_subdirectory(src/exppp)
add_subdirectory(src/exp2cxx)
add_subdirectory(src/exp2python)
add_subdirectory(src/clstepcore)
add_subdirectory(src/cleditor)
add_subdirectory(src/cldai)
add_subdirectory(src/clutils)
if(NOT WIN32) # don't build cllazyfile on windows until export/import macros are in place
add_subdirectory(src/cllazyfile)
endif(NOT WIN32)
add_subdirectory(include)
add_subdirectory(data)
if(SC_ENABLE_TESTING)
add_subdirectory(test)
endif(SC_ENABLE_TESTING)
add_subdirectory(doc)
if( SCHEMAS_WARNING )
message( "** CMake variable SC_BUILD_SCHEMAS was not set. Defaults to building ALL schemas, which will take a")
message(" while; see http://stepcode.org/mw/index.php?title=STEPcode_CMake_variables#SC_BUILD_SCHEMAS" )
endif( SCHEMAS_WARNING )
message( ".. Don't worry about any messages above about missing headers or failed tests, as long as\n you see '-- Configuring done' below. Headers and features vary by compiler." )
# 'make core' builds everything that isn't generated. for devs.
add_custom_target(core)
add_dependencies(core stepdai check-express stepeditor exp2cxx)
# this is for testing - 'make core' builds everything that isn't generated
add_custom_target( core )
add_dependencies( core stepdai check-express stepeditor exp2cxx )
# CONFIG_END_MESSAGES - list of messages to be printed after everything else is done.
# THIS MUST BE LAST to ensure that they are visible to the user without scrolling.
foreach(_msg ${CONFIG_END_MESSAGES})
message("${_msg}")
endforeach(_msg ${CONFIG_END_MESSAGES})
if(NOT SC_IS_SUBBUILD)
###############################################################################
# SC Packaging #
# $make package #
###############################################################################
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "STEPcode")
SET(CPACK_SET_DESTDIR "ON")
SET(CPACK_PACKAGE_VERSION_MAJOR ${SC_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${SC_VERSION_MINOR})
SET(CPACK_PACKAGE_NAME SC )
SET(CPACK_PACKAGE_CONTACT "SC Developers <scl-dev@googlegroups.com>")
INCLUDE(CPack)
########################################################################################
# Uninstall code #
# From http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F #
# ######################################################################################
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif(NOT SC_IS_SUBBUILD)
+8
View File
@@ -8,3 +8,11 @@ set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=StepClassLibrary")
set(CTEST_DROP_SITE_CDASH TRUE)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
-6
View File
@@ -1,6 +0,0 @@
(from BRL-CAD)
* rewrite express parser to not require lex/yacc
* verify/fix step parser generation with newer AP schemas, seems to be
outputting invalid syntax.
+51 -44
View File
@@ -24,61 +24,68 @@
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
MACRO(CHECK_C_FILE_RUNS SOURCE VAR)
IF("${VAR}" MATCHES "^${VAR}$")
SET(MACRO_CHECK_FUNCTION_DEFINITIONS
macro(CHECK_C_FILE_RUNS SOURCE VAR)
if("${VAR}" MATCHES "^${VAR}$")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
IF(CMAKE_REQUIRED_LIBRARIES)
SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
ELSE(CMAKE_REQUIRED_LIBRARIES)
SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
ENDIF(CMAKE_REQUIRED_LIBRARIES)
IF(CMAKE_REQUIRED_INCLUDES)
SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
ELSE(CMAKE_REQUIRED_INCLUDES)
SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
ENDIF(CMAKE_REQUIRED_INCLUDES)
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
else(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
endif(CMAKE_REQUIRED_LIBRARIES)
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else(CMAKE_REQUIRED_INCLUDES)
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
endif(CMAKE_REQUIRED_INCLUDES)
MESSAGE(STATUS "Performing Test ${VAR}")
TRY_RUN(${VAR}_EXITCODE ${VAR}_COMPILED
message(STATUS "Performing Test ${VAR}")
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${SOURCE}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${FILE_RUN_DEFINITIONS}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${FILE_RUN_DEFINITIONS}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
COMPILE_OUTPUT_VARIABLE OUTPUT)
# if it did not compile make the return value fail code of 1
IF(NOT ${VAR}_COMPILED)
SET(${VAR}_EXITCODE 1)
ENDIF(NOT ${VAR}_COMPILED)
if(NOT ${VAR}_COMPILED)
set(${VAR}_EXITCODE 1)
endif(NOT ${VAR}_COMPILED)
# if the return value was 0 then it worked
IF("${${VAR}_EXITCODE}" EQUAL 0)
SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
MESSAGE(STATUS "Performing Test ${VAR} - Success")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}}\n"
"Source file was:\n${SOURCE}\n")
ELSE("${${VAR}_EXITCODE}" EQUAL 0)
IF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
SET(${VAR} "${${VAR}_EXITCODE}")
ELSE(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
SET(${VAR} "" CACHE INTERNAL "Test ${VAR}")
ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
message(STATUS "Performing Test ${VAR} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}}\n"
"Source file was:\n${SOURCE}\n")
else("${${VAR}_EXITCODE}" EQUAL 0)
if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
set(${VAR} "${${VAR}_EXITCODE}")
else(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
endif(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
MESSAGE(STATUS "Performing Test ${VAR} - Failed")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}_EXITCODE}\n"
"Source file was:\n${SOURCE}\n")
message(STATUS "Performing Test ${VAR} - Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}_EXITCODE}\n"
"Source file was:\n${SOURCE}\n")
ENDIF("${${VAR}_EXITCODE}" EQUAL 0)
ENDIF("${VAR}" MATCHES "^${VAR}$")
ENDMACRO(CHECK_C_FILE_RUNS)
endif("${${VAR}_EXITCODE}" EQUAL 0)
endif("${VAR}" MATCHES "^${VAR}$")
endmacro(CHECK_C_FILE_RUNS)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+4 -4
View File
@@ -15,18 +15,18 @@
# Copyright 2009 Kitware, Inc.
# Copyright 2006 Tristan Carel
# All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#
# * The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
+4 -4
View File
@@ -15,18 +15,18 @@
# Copyright 2009 Kitware, Inc.
# Copyright 2006 Tristan Carel
# All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#
# * The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
+8
View File
@@ -8,3 +8,11 @@ mark_as_advanced(RE2C_EXECUTABLE)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(RE2C DEFAULT_MSG RE2C_EXECUTABLE)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+8 -8
View File
@@ -24,18 +24,18 @@
# Copyright 2009 Kitware, Inc.
# Copyright 2006 Tristan Carel
# All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#
# * The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
@@ -106,9 +106,9 @@ macro(LEMON_TARGET Name LemonInput LemonSource LemonHeader)
# rename generated outputs
if(NOT "${LemonSource}" STREQUAL "${LEMON_GEN_SOURCE}")
add_custom_command(
OUTPUT ${LemonSource}
OUTPUT ${LemonSource}
COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_SOURCE} ${LemonSource}
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_SOURCE}
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_SOURCE}
)
set(LEMON_${Name}_OUTPUTS ${LemonSource} ${LEMON_${Name}_OUTPUTS})
endif(NOT "${LemonSource}" STREQUAL "${LEMON_GEN_SOURCE}")
@@ -116,7 +116,7 @@ macro(LEMON_TARGET Name LemonInput LemonSource LemonHeader)
add_custom_command(
OUTPUT ${LemonHeader}
COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_HEADER} ${LemonHeader}
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_HEADER}
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_HEADER}
)
set(LEMON_${Name}_OUTPUTS ${LemonHeader} ${LEMON_${Name}_OUTPUTS})
endif(NOT "${LemonHeader}" STREQUAL "${LEMON_GEN_HEADER}")
@@ -125,7 +125,7 @@ macro(LEMON_TARGET Name LemonInput LemonSource LemonHeader)
# make sure we clean up generated output and copied input
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS}")
else("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS};${LEMON_BIN_INPUT}")
endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+6 -6
View File
@@ -1,5 +1,5 @@
# Defines two macros - PERPLEX_TARGET, which takes perplex inputs and
# runs both perplex and re2c to generate C source code/headers, and
# runs both perplex and re2c to generate C source code/headers, and
# ADD_PERPLEX_LEMON_DEPENDENCY which is used to set up dependencies between
# scanner and parser targets when necessary.
#
@@ -21,7 +21,7 @@
# ${PERPLEX_MyScanner_OUTPUTS}
# )
# ====================================================================
#
#
#=============================================================================
#
# Originally based off of FindBISON.cmake from Kitware's CMake distribution
@@ -31,18 +31,18 @@
# Copyright 2009 Kitware, Inc.
# Copyright 2006 Tristan Carel
# All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#
# * The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
+152
View File
@@ -0,0 +1,152 @@
# testing and compilation options, build output dirs, install dirs, etc
# included by root CMakeLists
if(NOT DEFINED INCLUDE_INSTALL_DIR)
set(INCLUDE_INSTALL_DIR include)
endif(NOT DEFINED INCLUDE_INSTALL_DIR)
if(NOT DEFINED LIB_INSTALL_DIR)
set(LIB_INSTALL_DIR lib)
endif(NOT DEFINED LIB_INSTALL_DIR)
if(NOT DEFINED BIN_INSTALL_DIR)
set(BIN_INSTALL_DIR bin)
endif(NOT DEFINED BIN_INSTALL_DIR)
if(NOT DEFINED SC_BUILD_TYPE)
set(SC_BUILD_TYPE "Debug" CACHE STRING "Build type") # By default set debug build
endif(NOT DEFINED SC_BUILD_TYPE)
if(NOT SC_IS_SUBBUILD)
set(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE} CACHE INTERNAL "Build type, immutable" FORCE)
else(NOT SC_IS_SUBBUILD)
set(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE})
endif(NOT SC_IS_SUBBUILD)
# Define helper macro OPTION_WITH_DEFAULT
macro(OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT)
if(NOT DEFINED ${OPTION_NAME})
set(${OPTION_NAME} ${OPTION_DEFAULT})
endif(NOT DEFINED ${OPTION_NAME})
option(${OPTION_NAME} "${OPTION_STRING}" ${${OPTION_NAME}})
endmacro(OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT)
# build shared libs by default
OPTION_WITH_DEFAULT(SC_BUILD_SHARED_LIBS "Build shared libs" ON)
# don't build static libs by default
OPTION_WITH_DEFAULT(SC_BUILD_STATIC_LIBS "Build static libs" OFF)
OPTION_WITH_DEFAULT(SC_PYTHON_GENERATOR "Compile exp2python" ON)
OPTION_WITH_DEFAULT(SC_CPP_GENERATOR "Compile exp2cxx" ON)
OPTION_WITH_DEFAULT(SC_MEMMGR_ENABLE_CHECKS "Enable sc_memmgr's memory leak detection" OFF)
OPTION_WITH_DEFAULT(SC_TRACE_FPRINTF "Enable extra comments in generated code so the code's source in exp2cxx may be located" OFF)
option(SC_BUILD_EXPRESS_ONLY "Only build express parser." OFF)
mark_as_advanced(SC_BUILD_EXPRESS_ONLY)
#---------------------------------------------------------------------
# Coverage option
OPTION_WITH_DEFAULT(SC_ENABLE_COVERAGE "Enable code coverage test" OFF)
if(SC_ENABLE_COVERAGE)
set(SC_ENABLE_TESTING ON CACHE BOOL "Testing enabled by coverage option" FORCE)
# build static libs, better coverage report
set(SC_BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs" FORCE)
set(SC_BUILD_STATIC_LIBS ON CACHE BOOL "Build static libs" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
set(CMAKE_C_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage" CACHE STRING "Extra linker flags required by code coverage" FORCE)
set(SC_BUILD_TYPE "Debug" CACHE STRING "Build type required by testing framework" FORCE)
set(SC_PYTHON_GENERATOR OFF) #won't build with static libs
endif(SC_ENABLE_COVERAGE)
#---------------------------------------------------------------------
# Testing option
OPTION_WITH_DEFAULT(SC_ENABLE_TESTING "Enable unittesting framework" OFF)
if(SC_ENABLE_TESTING)
if(NOT DEFINED SC_BUILD_SCHEMAS)
set(SC_BUILD_SCHEMAS "ALL") #test all schemas, unless otherwise specified
endif()
include(CTest)
ENABLE_TESTING()
endif(SC_ENABLE_TESTING)
#---------------------------------------------------------------------
# The following logic is what allows binaries to run successfully in
# the build directory AND install directory. Thanks to plplot for
# identifying the necessity of setting CMAKE_INSTALL_NAME_DIR on OSX.
# Documentation of these options is available at
# http://www.cmake.org/Wiki/CMake_RPATH_handling
# use, i.e. don't skip the full RPATH for the build tree
set(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# the RPATH/INSTALL_NAME_DIR to be used when installing
if (NOT APPLE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:\$ORIGIN/../lib")
endif(NOT APPLE)
# On OSX, we need to set INSTALL_NAME_DIR instead of RPATH
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#variable:CMAKE_INSTALL_NAME_DIR
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
# add the automatically determined parts of the RPATH which point to
# directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# When this is a subbuild, assume that the parent project controls all of the following
#======================================================================================
if(NOT SC_IS_SUBBUILD)
# Output directories. In a separate file so it can be used by the schema scanner CMake as well.
include(${SC_CMAKE_DIR}/SC_Outdirs.cmake)
#-----------------------------------------------------------------------------
# Configure install locations. Only do this if CMAKE_INSTALL_PREFIX hasn't
# been set already, to try and allow parent builds (if any) some control.
#
# Need a good Debug location for Windows.
if(NOT WIN32)
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(SC_INSTALL_PREFIX "${SC_SOURCE_DIR}/../sc-install")
else()
set(SC_INSTALL_PREFIX "/usr/local")
endif()
endif(NOT WIN32)
set(SC_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE
PATH "Install prefix prepended to target to create install location")
set(CMAKE_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE INTERNAL "Prefix prepended to install directories if target destination is not absolute, immutable" FORCE)
#-----------------------------------------------------------------------------
# SC Packaging
# $make package
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "STEPcode")
set(CPACK_SET_DESTDIR "ON")
set(CPACK_PACKAGE_VERSION_MAJOR ${SC_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${SC_VERSION_MINOR})
set(CPACK_PACKAGE_NAME SC)
set(CPACK_PACKAGE_CONTACT "SC Developers <scl-dev@googlegroups.com>")
include(CPack)
#-----------------------------------------------------------------------------
# Uninstall target
# From http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif(NOT SC_IS_SUBBUILD)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+125
View File
@@ -0,0 +1,125 @@
# macros to be used in the CMakeLists generated by the schema scanner
# uses SC_GENERATE_CXX_ONESHOT - if true, files will only be generated once. this is useful when debugging and modifying code, not otherwise. TODO: print a warning when set
if(NOT DEFINED SC_GENERATE_CXX_ONESHOT)
set(SC_GENERATE_CXX_ONESHOT FALSE)
endif(NOT DEFINED SC_GENERATE_CXX_ONESHOT)
# find all part 21 files in schema dir, add a test for each one
macro(P21_TESTS sfile)
get_filename_component(SCHEMA_DIR ${sfile} PATH)
file(GLOB_RECURSE P21_FILES ${SCHEMA_DIR}/*.stp ${SCHEMA_DIR}/*.step ${SCHEMA_DIR}/*.p21 ${SCHEMA_DIR}/*.ifc)
foreach(TEST_FILE ${P21_FILES})
get_filename_component(FNAME ${TEST_FILE} NAME_WE)
add_test(NAME read_write_cpp_${PROJECT_NAME}_${FNAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND p21read_${PROJECT_NAME} ${TEST_FILE})
set_tests_properties(read_write_cpp_${PROJECT_NAME}_${FNAME} PROPERTIES DEPENDS build_cpp_${PROJECT_NAME} LABELS cpp_schema_rw)
if(NOT WIN32)
add_test(NAME read_lazy_cpp_${PROJECT_NAME}_${FNAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND lazy_${PROJECT_NAME} ${TEST_FILE})
set_tests_properties(read_lazy_cpp_${PROJECT_NAME}_${FNAME} PROPERTIES DEPENDS build_lazy_cpp_${PROJECT_NAME} LABELS cpp_schema_rw)
endif(NOT WIN32)
endforeach()
endmacro(P21_TESTS sfile)
# create p21read_sdai_*, lazy_sdai_*, any exes listed in SC_SDAI_ADDITIONAL_EXES_SRCS
macro(SCHEMA_EXES)
RELATIVE_PATH_TO_TOPLEVEL(${CMAKE_CURRENT_SOURCE_DIR} RELATIVE_PATH_COMPONENT)
SC_ADDEXEC(p21read_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc" "${PROJECT_NAME};stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
#add_dependencies(p21read_${PROJECT_NAME} version_string)
if(HAVE_STD_THREAD)
set_target_properties(p21read_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
endif(HAVE_STD_THREAD)
if(NOT WIN32)
SC_ADDEXEC(lazy_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc" "${PROJECT_NAME};steplazyfile;stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
#add_dependencies(lazy_${PROJECT_NAME} version_string)
if(HAVE_STD_THREAD)
set_target_properties(lazy_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
endif(HAVE_STD_THREAD)
endif(NOT WIN32)
#add user-defined executables
foreach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
get_filename_component(name ${src} NAME_WE)
get_filename_component(path ${src} ABSOLUTE)
SC_ADDEXEC(${name}_${PROJECT_NAME} "${src}" "${PROJECT_NAME};stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
add_dependencies(${name}_${PROJECT_NAME} version_string)
#set_target_properties(${name}_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${${PROJECT_NAME}_COMPILE_FLAGS} -I${path}")
endforeach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
ENDMACRO(SCHEMA_EXES)
# label the tests and set dependencies
macro(SCHEMA_TESTS)
add_test(NAME generate_cpp_${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target generate_cpp_${PROJECT_NAME}
--config $<CONFIGURATION>)
set_tests_properties(generate_cpp_${PROJECT_NAME} PROPERTIES LABELS cpp_schema_gen)
add_test(NAME build_cpp_${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target p21read_${PROJECT_NAME}
--config $<CONFIGURATION>)
set_tests_properties(build_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${PROJECT_NAME} LABELS cpp_schema_build)
if(NOT WIN32)
add_test(NAME build_lazy_cpp_${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target lazy_${PROJECT_NAME}
--config $<CONFIGURATION>)
set_tests_properties(build_lazy_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${PROJECT_NAME} LABELS cpp_schema_build)
endif(NOT WIN32)
endmacro(SCHEMA_TESTS)
# SCHEMA_TARGETS macro -
# expFile: path to express file
# schemaName: name of the schema
# sourceFiles: list of .cc and .h files
#
# create targets for the schema(s) in expFile
# targets include gen_cxx_*, sdai_cxx_*, p21read_*, lazyp21_*, ...
macro(SCHEMA_TARGETS expFile schemaName sourceFiles)
# schema scanner comes up with a short schema name for PROJECT() (which sets ${PROJECT_NAME})
message(STATUS "Will generate ${${PROJECT_NAME}_file_count} C++ files for ${PROJECT_NAME}.")
add_custom_target(generate_cpp_${PROJECT_NAME} DEPENDS exp2cxx ${expFile} ${sourceFiles} SOURCES ${sourceFiles})
# this calls a cmake script because it doesn't seem to be possible
# to divert stdout, stderr in cmake except via execute_process
add_custom_command(OUTPUT ${sourceFiles}
COMMAND ${CMAKE_COMMAND} -DEXE=\"$<TARGET_FILE:exp2cxx>\" -DEXP=\"${expFile}\"
-DONESHOT=\"${SC_GENERATE_CXX_ONESHOT}\" -DSDIR=\"${CMAKE_CURRENT_LIST_DIR}\"
-P ${SC_CMAKE_DIR}/SC_Run_exp2cxx.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMENT "[exp2cxx] Generating ${${PROJECT_NAME}_file_count} C++ files for ${PROJECT_NAME}."
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR} ${SC_SOURCE_DIR}/src/cldai ${SC_SOURCE_DIR}/src/cleditor
${SC_SOURCE_DIR}/src/clutils ${SC_SOURCE_DIR}/src/clstepcore ${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/base/judy/src
)
# if testing is enabled, "TESTABLE" sets property EXCLUDE_FROM_ALL and prevents installation
SC_ADDLIB(${PROJECT_NAME} "${sourceFiles}" "stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
add_dependencies(${PROJECT_NAME} generate_cpp_${PROJECT_NAME})
if(HAVE_STD_THREAD)
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
endif(HAVE_STD_THREAD)
SCHEMA_EXES()
SCHEMA_TESTS()
P21_TESTS(${expFile})
# TODO add test to verify that schema scanner output matches fedex_plus output
endmacro(SCHEMA_TARGETS expFile schemaName sourceFiles)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+96
View File
@@ -0,0 +1,96 @@
# create sc_cf.h and sc_version_string.h
# Take the sc config file template as the starting point for
# sc_cf.h.in - scripts may need to append to the template, so
# it is read into memory initially.
set(CONFIG_H_FILE ${SC_BINARY_DIR}/include/sc_cf.h.in)
set_source_files_properties(${CONFIG_H_FILE} PROPERTIES GENERATED TRUE)
set(CMAKE_CURRENT_PROJECT SC)
define_property(GLOBAL PROPERTY SC_CONFIG_H_CONTENTS BRIEF_DOCS "config.h.in contents" FULL_DOCS "config.h.in contents for SC project")
if(NOT COMMAND CONFIG_H_APPEND)
macro(CONFIG_H_APPEND PROJECT_NAME NEW_CONTENTS)
if(PROJECT_NAME)
get_property(${PROJECT_NAME}_CONFIG_H_CONTENTS GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS)
set(${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS "${${PROJECT_NAME}_CONFIG_H_CONTENTS}${NEW_CONTENTS}")
set_property(GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS "${${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS}")
endif(PROJECT_NAME)
endmacro(CONFIG_H_APPEND NEW_CONTENTS)
endif(NOT COMMAND CONFIG_H_APPEND)
file(READ ${SC_SOURCE_DIR}/include/sc_cf_cmake.h.in CONFIG_H_FILE_CONTENTS)
CONFIG_H_APPEND(SC "${CONFIG_H_FILE_CONTENTS}")
include(CheckLibraryExists)
include(CheckIncludeFile)
include(CheckFunctionExists)
include(CheckTypeSize)
include(CMakePushCheckState)
include(CheckCXXSourceRuns)
CHECK_INCLUDE_FILE(ndir.h HAVE_NDIR_H)
CHECK_INCLUDE_FILE(stdarg.h HAVE_STDARG_H)
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILE(sysent.h HAVE_SYSENT_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
CHECK_INCLUDE_FILE(process.h HAVE_PROCESS_H)
CHECK_INCLUDE_FILE(io.h HAVE_IO_H)
CHECK_FUNCTION_EXISTS(abs HAVE_ABS)
CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
CHECK_FUNCTION_EXISTS(getopt HAVE_GETOPT)
CHECK_TYPE_SIZE("ssize_t" SSIZE_T)
set( TEST_STD_THREAD "
#include <iostream>
#include <thread>
void do_work() {
std::cout << \"thread\" << std::endl;
}
int main() {
std::thread t(do_work);
t.join();
}
" )
cmake_push_check_state()
if( UNIX )
set( CMAKE_REQUIRED_FLAGS "-pthread -std=c++0x" )
else( UNIX )
# vars probably need set for MSVC11, embarcadero, etc
endif( UNIX )
CHECK_CXX_SOURCE_RUNS( "${TEST_STD_THREAD}" HAVE_STD_THREAD ) #quotes are *required*!
cmake_pop_check_state()
# Now that all the tests are done, configure the sc_cf.h file:
get_property(CONFIG_H_FILE_CONTENTS GLOBAL PROPERTY SC_CONFIG_H_CONTENTS)
file(WRITE ${CONFIG_H_FILE} "${CONFIG_H_FILE_CONTENTS}")
configure_file(${CONFIG_H_FILE} ${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_cf.h)
# ------------------------
# create sc_version_string.h, http://stackoverflow.com/questions/3780667
# Using 'ver_string' instead of 'sc_version_string.h' is a trick to force the
# command to always execute when the custom target is built. It works because
# a file by that name never exists.
configure_file(${SC_CMAKE_DIR}/sc_version_string.cmake ${SC_BINARY_DIR}/sc_version_string.cmake @ONLY)
add_custom_target(version_string ALL DEPENDS ver_string )
# creates sc_version_string.h using cmake script
add_custom_command(OUTPUT ver_string ${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${SC_SOURCE_DIR}
-DBINARY_DIR=${SC_BINARY_DIR}
-P ${SC_BINARY_DIR}/sc_version_string.cmake)
# sc_version_string.h is a generated file
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
PROPERTIES GENERATED TRUE
HEADER_FILE_ONLY TRUE )
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+22
View File
@@ -0,0 +1,22 @@
# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables and set them
# to "C" so things like date output are as expected
set(_orig_lc_all $ENV{LC_ALL})
set(_orig_lc_messages $ENV{LC_MESSAGES})
set(_orig_lang $ENV{LANG})
if(_orig_lc_all)
set(ENV{LC_ALL} C)
endif(_orig_lc_all)
if(_orig_lc_messages)
set(ENV{LC_MESSAGES} C)
endif(_orig_lc_messages)
if(_orig_lang)
set(ENV{LANG} C)
endif(_orig_lang)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+30
View File
@@ -0,0 +1,30 @@
# in its own file so that it can be used by the schema scanner as well
if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
endif(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
endif(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
endif(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER "${CFG_TYPE}" CFG_TYPE)
if(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
set("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
endif(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
if(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
set("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
endif(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
if(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
set("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
endif(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
endforeach()
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+93
View File
@@ -0,0 +1,93 @@
macro(REVERSE_PATH in_path out_path drive_path)
set(reversed_path)
set(tmp_subpath "${in_path}")
while(NOT "${tmp_subpath}" STREQUAL "" AND NOT "${tmp_subpath}" STREQUAL "/")
get_filename_component(piece "${tmp_subpath}" NAME)
get_filename_component(tmp_subpath "${tmp_subpath}" PATH)
if(piece)
set(reversed_path "${reversed_path}/${piece}")
else(piece)
set(${drive_path} ${tmp_subpath})
set(tmp_subpath)
endif(piece)
endwhile(NOT "${tmp_subpath}" STREQUAL "" AND NOT "${tmp_subpath}" STREQUAL "/")
set("${out_path}" "${reversed_path}")
endmacro(REVERSE_PATH)
macro(GET_COMMON_ROOT_PATH dir1 dir2 common_subpath)
get_filename_component(testpath "${dir1}" REALPATH)
set(dir1_rev)
set(dir2_rev)
REVERSE_PATH("${dir1}" dir1_rev drive_name_1)
REVERSE_PATH("${dir2}" dir2_rev drive_name_2)
if("${drive_name_1}" STREQUAL "${drive_name_2}")
set(component_same 1)
set(${common_subpath})
while(component_same)
get_filename_component(piece1 "${dir1_rev}" NAME)
get_filename_component(dir1_rev "${dir1_rev}" PATH)
get_filename_component(piece2 "${dir2_rev}" NAME)
get_filename_component(dir2_rev "${dir2_rev}" PATH)
if("${piece1}" STREQUAL "${piece2}")
set(${common_subpath} "${${common_subpath}}/${piece1}")
else("${piece1}" STREQUAL "${piece2}")
set(component_same 0)
endif("${piece1}" STREQUAL "${piece2}")
endwhile(component_same)
if(drive_name_1)
set(${common_subpath} "${drive_name_1}${${common_subpath}}")
string(REPLACE "//" "/" ${common_subpath} "${${common_subpath}}")
endif(drive_name_1)
endif("${drive_name_1}" STREQUAL "${drive_name_2}")
endmacro(GET_COMMON_ROOT_PATH)
macro(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
set(common_root_path)
GET_COMMON_ROOT_PATH("${SC_SOURCE_DIR}" "${current_dir}" common_root_path)
string(REPLACE "${common_root_path}" "" subpath "${current_dir}")
string(REPLACE "${common_root_path}" "" needed_src_path "${SC_SOURCE_DIR}")
string(REGEX REPLACE "^/" "" subpath "${subpath}")
string(REGEX REPLACE "^/" "" needed_src_path "${needed_src_path}")
string(LENGTH "${subpath}" PATH_LENGTH)
if(PATH_LENGTH GREATER 0)
set(${rel_path} "..")
get_filename_component(subpath "${subpath}" PATH)
string(LENGTH "${subpath}" PATH_LENGTH)
while(PATH_LENGTH GREATER 0)
set(${rel_path} "${${rel_path}}/..")
get_filename_component(subpath "${subpath}" PATH)
string(LENGTH "${subpath}" PATH_LENGTH)
endwhile(PATH_LENGTH GREATER 0)
endif(PATH_LENGTH GREATER 0)
set(${rel_path} "${${rel_path}}/${needed_src_path}")
string(REPLACE "//" "/" ${rel_path} "${${rel_path}}")
endmacro(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
macro(LOCATE_SCHEMA SCHEMA_FILE _res_var)
if(EXISTS "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}") #is it a path relative to build dir?
set(${_res_var} "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}")
elseif(EXISTS "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}") # path relative to STEPcode/data?
set(${_res_var} "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}")
elseif(EXISTS ${SCHEMA_FILE}) # already an absolute path
set(${_res_var} ${SCHEMA_FILE})
else()
message(FATAL_ERROR "Cannot find ${CMAKE_BINARY_DIR}/${SCHEMA_FILE} or ${SC_SOURCE_DIR}/data/${SCHEMA_FILE}/*.exp or ${SCHEMA_FILE}")
endif()
if(IS_DIRECTORY ${${_res_var}}) #if it is a dir, look for one .exp file inside
file(GLOB ${_res_var} ${${_res_var}}/*.exp)
endif()
if(NOT EXISTS ${${_res_var}})
message(FATAL_ERROR "Expected one express file. Found '${${_res_var}}' instead.")
endif()
endmacro(LOCATE_SCHEMA SCHEMA_FILE _res_var)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+68
View File
@@ -0,0 +1,68 @@
# The Express parser uses the tools Perplex, RE2C and Lemon to generate code
# from higher level inputs. Depending on available tools and options, the
# SC build can either re-generate code as part of the build, or use cached
# files that are ready for compilation.
#
# SC_GENERATE_LEXER_PARSER is the "high level" control a user sets to determine
# how the SC build will interact (or not) with these tools. AUTO (the
# default) means it will search for the necessary tools, and use them only if
# everything is found. If not, it will fall back to the cached versions. If
# this option is set to ON and the necessary tools are not found, the
# configure step will fail. If it is set to OFF, SC will not even try to use
# the generators and will instead use the cached sources.
if(NOT DEFINED SC_GENERATE_LEXER_PARSER)
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
set(_verbosity "QUIET")
else(NOT DEFINED SC_GENERATE_LEXER_PARSER)
string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER)
endif(NOT DEFINED SC_GENERATE_LEXER_PARSER)
set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS AUTO ON OFF)
if (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
message(WARNING "Unknown value ${SC_GENERATE_LEXER_PARSER} supplied for SC_GENERATE_LEXER_PARSER - defaulting to AUTO")
message(WARNING "Valid options are AUTO, ON and OFF")
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
endif (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
# If the generators have not been turned off, we need to check for them
if(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
find_package(LEMON ${_verbosity})
find_package(RE2C ${_verbosity})
find_package(PERPLEX ${_verbosity})
if(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
# Templates may be anywhere - make sure we have a stable path if a relative
# path was specified at CMake time
get_filename_component(lemon_template_fpath "${LEMON_TEMPLATE}" ABSOLUTE)
if(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
get_filename_component(LEMON_TEMPLATE "${CMAKE_BINARY_DIR}/${LEMON_TEMPLATE}" ABSOLUTE)
endif(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
get_filename_component(perplex_template_fpath "${PERPLEX_TEMPLATE}" ABSOLUTE)
if(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
get_filename_component(PERPLEX_TEMPLATE "${CMAKE_BINARY_DIR}/${PERPLEX_TEMPLATE}" ABSOLUTE)
endif(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
if(NOT COMMAND LEMON_TARGET)
include(${SC_CMAKE_DIR}/LEMON_Util.cmake)
endif(NOT COMMAND LEMON_TARGET)
if(NOT COMMAND PERPLEX_TARGET)
include(${SC_CMAKE_DIR}/PERPLEX_Util.cmake)
endif(NOT COMMAND PERPLEX_TARGET)
set(SC_GENERATE_LP_SOURCES 1)
message(".. Found perplex, re2c, and lemon - can regenerate lexer/parser if necessary")
else(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
if("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but one or more components of the Perplex/RE2C/Lemon toolchain were not found.\n")
else("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
set(SC_GENERATE_LP_SOURCES 0)
endif("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
endif(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
else(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
set(SC_GENERATE_LP_SOURCES 0)
endif(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+25
View File
@@ -0,0 +1,25 @@
# if oneshot is true, don't run exp2cxx if source files exist. if schema.cc exists, assume others do
if(ONESHOT AND EXISTS "${SDIR}/schema.cc")
message("WARNING: SC_GENERATE_CXX_ONESHOT is enabled. If generated code has been modified, it will NOT be rewritten!")
message("This is ONLY for debugging STEPcode internals!")
else()
execute_process(COMMAND ${EXE} ${EXP}
WORKING_DIRECTORY ${SDIR}
RESULT_VARIABLE _res
OUTPUT_FILE exp2cxx_stdout.txt
ERROR_FILE exp2cxx_stderr.txt
)
if(NOT "${_res}" STREQUAL "0")
message(FATAL_ERROR "${EXE} reported an error for ${EXP}.\nsee exp2cxx_stdout.txt and exp2cxx_stderr.txt in ${SDIR} for details.")
endif(NOT "${_res}" STREQUAL "0")
# TODO count number of lines in stdout/stderr and tell user?
endif()
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+168
View File
@@ -0,0 +1,168 @@
# set compile definitions for dll exports on windows
macro(DEFINE_DLL_EXPORTS libname)
if(MSVC OR BORLAND)
if(${libname} MATCHES "sdai_.*")
set(export "SC_SCHEMA_DLL_EXPORTS")
else()
string(REGEX REPLACE "lib" "" shortname "${libname}")
string(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
string(TOUPPER ${LOWERCORE} UPPER_CORE)
set(export "SC_${UPPER_CORE}_DLL_EXPORTS")
endif()
get_target_property(defs ${libname} COMPILE_DEFINITIONS)
if(defs) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
set(defs "${defs};${export}")
else(defs)
set(defs "${export}")
endif(defs)
set_target_properties(${libname} PROPERTIES COMPILE_DEFINITIONS "${defs}")
endif(MSVC OR BORLAND)
endmacro(DEFINE_DLL_EXPORTS libname)
# set compile definitions for dll imports on windows
macro(DEFINE_DLL_IMPORTS tgt libs)
if(MSVC OR BORLAND)
get_target_property(defs ${tgt} COMPILE_DEFINITIONS)
if(NOT defs) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
set(defs "")
endif(NOT defs)
foreach(lib ${libs})
string(REGEX REPLACE "lib" "" shortname "${lib}")
string(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
string(TOUPPER ${LOWERCORE} UPPER_CORE)
list(APPEND defs "SC_${UPPER_CORE}_DLL_IMPORTS")
endforeach(lib ${libs})
if(DEFINED defs)
if(defs)
set_target_properties(${tgt} PROPERTIES COMPILE_DEFINITIONS "${defs}")
endif(defs)
endif(DEFINED defs)
endif(MSVC OR BORLAND)
endmacro(DEFINE_DLL_IMPORTS tgt libs)
#EXCLUDE_OR_INSTALL(target destination ARGV3)
# installs ${target} in ${destination} unless testing is enabled AND ${arg_3} == "TESTABLE",
# in which case the EXCLUDE_FROM_ALL property is set for testing.
# EXCLUDE_FROM_ALL cannot be set on targets that are to be installed,
# so either test the target or install it - but not both
macro(EXCLUDE_OR_INSTALL target dest arg_3)
if(NOT ((SC_ENABLE_TESTING) AND ("${arg_3}" STREQUAL "TESTABLE")))
INSTALL(TARGETS ${target} DESTINATION ${dest})
else(NOT ((SC_ENABLE_TESTING) AND ("${arg_3}" STREQUAL "TESTABLE")))
set_target_properties(${target} PROPERTIES EXCLUDE_FROM_ALL ON)
endif(NOT ((SC_ENABLE_TESTING) AND ("${arg_3}" STREQUAL "TESTABLE")))
endmacro(EXCLUDE_OR_INSTALL target dest arg_3)
#SC_ADDEXEC(execname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
# optional args can also be used by MSVC-specific code, but it looks like these two uses
# will not conflict because the MSVC args must contain "STRICT"
macro(SC_ADDEXEC execname srcslist libslist)
if(SC_BUILD_SHARED_LIBS)
add_executable(${execname} ${srcslist})
target_link_libraries(${execname} ${libslist})
DEFINE_DLL_IMPORTS(${execname} "${libslist}") #add import definitions for all libs that the executable is linked to
EXCLUDE_OR_INSTALL(${execname} "bin" "${ARGV3}")
# Enable extra compiler flags if local executables and/or global options dictate
set(LOCAL_COMPILE_FLAGS "")
foreach(extraarg ${ARGN})
if(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
set(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
endif(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
endforeach(extraarg ${ARGN})
if(LOCAL_COMPILE_FLAGS)
set_target_properties(${execname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
endif(LOCAL_COMPILE_FLAGS)
endif(SC_BUILD_SHARED_LIBS)
if(SC_BUILD_STATIC_LIBS)
if(NOT SC_BUILD_SHARED_LIBS)
set(staticexecname "${execname}")
else()
set(staticexecname "${execname}-static")
endif(NOT SC_BUILD_SHARED_LIBS)
add_executable(${staticexecname} ${srcslist})
target_link_libraries(${staticexecname} ${libslist})
EXCLUDE_OR_INSTALL(${staticexecname} "bin" "${ARGV3}")
# Enable extra compiler flags if local executables and/or global options dictate
set(LOCAL_COMPILE_FLAGS "")
foreach(extraarg ${ARGN})
if(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
set(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
endif(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
endforeach(extraarg ${ARGN})
if(LOCAL_COMPILE_FLAGS)
set_target_properties(${staticexecname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
endif(LOCAL_COMPILE_FLAGS)
endif(SC_BUILD_STATIC_LIBS)
endmacro(SC_ADDEXEC execname srcslist libslist)
#SC_ADDLIB(libname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
# optional args can also be used by MSVC-specific code, but it looks like these two uses
# will not conflict because the MSVC args must contain "STRICT"
macro(SC_ADDLIB libname srcslist libslist)
string(REGEX REPLACE "-framework;" "-framework " libslist "${libslist1}")
if(SC_BUILD_SHARED_LIBS)
add_library(${libname} SHARED ${srcslist})
DEFINE_DLL_EXPORTS(${libname})
if(NOT "${libs}" MATCHES "NONE")
target_link_libraries(${libname} ${libslist})
DEFINE_DLL_IMPORTS(${libname} "${libslist}")
endif(NOT "${libs}" MATCHES "NONE")
set_target_properties(${libname} PROPERTIES VERSION ${SC_ABI_VERSION} SOVERSION ${SC_ABI_SOVERSION})
EXCLUDE_OR_INSTALL(${libname} "lib" "${ARGV3}")
if(APPLE)
set_target_properties(${libname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
endif(APPLE)
endif(SC_BUILD_SHARED_LIBS)
if(SC_BUILD_STATIC_LIBS)
if(NOT SC_BUILD_SHARED_LIBS)
set(staticlibname "${libname}")
else()
set(staticlibname "${libname}-static")
endif(NOT SC_BUILD_SHARED_LIBS)
add_library(${staticlibname} STATIC ${srcslist})
DEFINE_DLL_EXPORTS(${staticlibname})
if(NOT ${libs} MATCHES "NONE")
target_link_libraries(${staticlibname} "${libslist}")
DEFINE_DLL_IMPORTS(${staticlibname} ${libslist})
endif(NOT ${libs} MATCHES "NONE")
if(NOT WIN32)
set_target_properties(${staticlibname} PROPERTIES OUTPUT_NAME "${libname}")
endif(NOT WIN32)
if(WIN32)
# We need the lib prefix on win32, so add it even if our add_library
# wrapper function has removed it due to the target name - see
# http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_make_my_shared_and_static_libraries_have_the_same_root_name.2C_but_different_suffixes.3F
set_target_properties(${staticlibname} PROPERTIES PREFIX "lib")
endif(WIN32)
EXCLUDE_OR_INSTALL(${staticlibname} "lib" "${ARGV3}")
if(APPLE)
set_target_properties(${staticlibname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
endif(APPLE)
endif(SC_BUILD_STATIC_LIBS)
# Enable extra compiler flags if local libraries and/or global options dictate
set(LOCAL_COMPILE_FLAGS "")
foreach(extraarg ${ARGN})
if(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
set(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
endif(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
endforeach(extraarg ${ARGN})
if(LOCAL_COMPILE_FLAGS)
if(BUILD_SHARED_LIBS)
set_target_properties(${libname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
endif(BUILD_SHARED_LIBS)
if(BUILD_STATIC_LIBS)
set_target_properties(${staticlibname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
endif(BUILD_STATIC_LIBS)
endif(LOCAL_COMPILE_FLAGS)
endmacro(SC_ADDLIB libname srcslist libslist)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
-138
View File
@@ -1,138 +0,0 @@
# set compile definitions for dll exports on windows
MACRO(DEFINE_DLL_EXPORTS libname)
IF( MSVC OR BORLAND )
if( ${libname} MATCHES "sdai_.*" )
set( export "SC_SCHEMA_DLL_EXPORTS" )
else()
STRING(REGEX REPLACE "lib" "" shortname "${libname}")
STRING(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
STRING(TOUPPER ${LOWERCORE} UPPER_CORE)
set( export "SC_${UPPER_CORE}_DLL_EXPORTS" )
endif()
get_target_property(defs ${libname} COMPILE_DEFINITIONS )
if( defs ) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
set( defs "${defs};${export}")
else( defs )
set( defs "${export}")
endif( defs )
set_target_properties(${libname} PROPERTIES COMPILE_DEFINITIONS "${defs}" )
ENDIF( MSVC OR BORLAND )
ENDMACRO(DEFINE_DLL_EXPORTS libname)
# set compile definitions for dll imports on windows
MACRO( DEFINE_DLL_IMPORTS tgt libs )
IF( MSVC OR BORLAND )
get_target_property(defs ${tgt} COMPILE_DEFINITIONS )
if( NOT defs ) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
set( defs "")
endif( NOT defs )
foreach( lib ${libs} )
STRING(REGEX REPLACE "lib" "" shortname "${lib}")
STRING(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
STRING(TOUPPER ${LOWERCORE} UPPER_CORE)
list( APPEND defs "SC_${UPPER_CORE}_DLL_IMPORTS" )
endforeach( lib ${libs} )
if( DEFINED defs )
if( defs )
set_target_properties( ${tgt} PROPERTIES COMPILE_DEFINITIONS "${defs}" )
endif( defs )
endif( DEFINED defs )
ENDIF( MSVC OR BORLAND )
ENDMACRO( DEFINE_DLL_IMPORTS tgt libs )
#EXCLUDE_OR_INSTALL(target destination ARGV3)
# installs ${target} in ${destination} unless testing is enabled AND ${arg_3} == "TESTABLE",
# in which case the EXCLUDE_FROM_ALL property is set for testing.
# EXCLUDE_FROM_ALL cannot be set on targets that are to be installed,
# so either test the target or install it - but not both
MACRO(EXCLUDE_OR_INSTALL target dest arg_3 )
if( NOT ( ( SC_ENABLE_TESTING ) AND ( "${arg_3}" STREQUAL "TESTABLE" ) ) )
INSTALL(TARGETS ${target} DESTINATION ${dest})
else( NOT ( ( SC_ENABLE_TESTING ) AND ( "${arg_3}" STREQUAL "TESTABLE" ) ) )
set_target_properties( ${target} PROPERTIES EXCLUDE_FROM_ALL ON )
endif( NOT ( ( SC_ENABLE_TESTING ) AND ( "${arg_3}" STREQUAL "TESTABLE" ) ) )
ENDMACRO(EXCLUDE_OR_INSTALL target dest arg_3 )
#SC_ADDEXEC( execname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
# optional args can also be used by MSVC-specific code, but it looks like these two uses
# will not conflict because the MSVC args must contain "STRICT"
MACRO(SC_ADDEXEC execname srcslist libslist)
add_executable(${execname} ${srcslist})
target_link_libraries(${execname} ${libslist})
DEFINE_DLL_IMPORTS(${execname} "${libslist}") #add import definitions for all libs that the executable is linked to
EXCLUDE_OR_INSTALL( ${execname} "bin" "${ARGV3}" )
# Enable extra compiler flags if local executables and/or global options dictate
SET(LOCAL_COMPILE_FLAGS "")
FOREACH(extraarg ${ARGN})
IF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
SET(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
ENDIF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
ENDFOREACH(extraarg ${ARGN})
IF(LOCAL_COMPILE_FLAGS)
SET_TARGET_PROPERTIES(${execname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
ENDIF(LOCAL_COMPILE_FLAGS)
ENDMACRO(SC_ADDEXEC execname srcslist libslist)
#SC_ADDLIB( libname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
# optional args can also be used by MSVC-specific code, but it looks like these two uses
# will not conflict because the MSVC args must contain "STRICT"
MACRO(SC_ADDLIB libname srcslist libslist)
STRING(REGEX REPLACE "-framework;" "-framework " libslist "${libslist1}")
IF(SC_BUILD_SHARED_LIBS)
add_library(${libname} SHARED ${srcslist})
DEFINE_DLL_EXPORTS(${libname})
if(NOT "${libs}" MATCHES "NONE")
target_link_libraries(${libname} ${libslist})
DEFINE_DLL_IMPORTS(${libname} "${libslist}" )
endif(NOT "${libs}" MATCHES "NONE")
SET_TARGET_PROPERTIES(${libname} PROPERTIES VERSION ${SC_ABI_VERSION} SOVERSION ${SC_ABI_SOVERSION} )
EXCLUDE_OR_INSTALL( ${libname} "lib" "${ARGV3}" )
if(APPLE)
set_target_properties(${libname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
endif(APPLE)
ENDIF(SC_BUILD_SHARED_LIBS)
IF(SC_BUILD_STATIC_LIBS AND NOT MSVC)
if( NOT SC_BUILD_SHARED_LIBS )
set( staticlibname "${libname}" )
else()
set( staticlibname "${libname}-static" )
endif( NOT SC_BUILD_SHARED_LIBS )
add_library(${staticlibname} STATIC ${srcslist})
DEFINE_DLL_EXPORTS(${staticlibname})
if(NOT ${libs} MATCHES "NONE")
target_link_libraries(${staticlibname} "${libslist}")
DEFINE_DLL_IMPORTS(${staticlibname} ${libslist} )
endif(NOT ${libs} MATCHES "NONE")
IF(NOT WIN32)
SET_TARGET_PROPERTIES(${staticlibname} PROPERTIES OUTPUT_NAME "${libname}")
ENDIF(NOT WIN32)
IF(WIN32)
# We need the lib prefix on win32, so add it even if our add_library
# wrapper function has removed it due to the target name - see
# http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_make_my_shared_and_static_libraries_have_the_same_root_name.2C_but_different_suffixes.3F
SET_TARGET_PROPERTIES(${staticlibname} PROPERTIES PREFIX "lib")
ENDIF(WIN32)
EXCLUDE_OR_INSTALL( ${staticlibname} "lib" "${ARGV3}" )
if(APPLE)
set_target_properties(${staticlibname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
endif(APPLE)
ENDIF(SC_BUILD_STATIC_LIBS AND NOT MSVC)
# Enable extra compiler flags if local libraries and/or global options dictate
SET(LOCAL_COMPILE_FLAGS "")
FOREACH(extraarg ${ARGN})
IF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
SET(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
ENDIF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
ENDFOREACH(extraarg ${ARGN})
IF(LOCAL_COMPILE_FLAGS)
IF(BUILD_SHARED_LIBS)
SET_TARGET_PROPERTIES(${libname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
ENDIF(BUILD_SHARED_LIBS)
IF(BUILD_STATIC_LIBS AND NOT MSVC)
SET_TARGET_PROPERTIES(${staticlibname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
ENDIF(BUILD_STATIC_LIBS AND NOT MSVC)
ENDIF(LOCAL_COMPILE_FLAGS)
ENDMACRO(SC_ADDLIB libname srcslist libslist)
+23 -15
View File
@@ -1,22 +1,30 @@
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
list(REVERSE files)
foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif (NOT ${rm_retval} EQUAL 0)
else (EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif (EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif (NOT ${rm_retval} EQUAL 0)
else (EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif (EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+55 -48
View File
@@ -4,7 +4,6 @@
# http://stackoverflow.com/questions/3780667
# http://www.cmake.org/pipermail/cmake/2009-February/027014.html
set(SC_IS_SUBBUILD "@SC_IS_SUBBUILD@")
#---------- find commit id ------------------
@@ -13,68 +12,76 @@ set(SC_IS_SUBBUILD "@SC_IS_SUBBUILD@")
#create a tag with 'git tag <name>' and 'git push --tags'
#if git can't be found, uses contents of SC_VERSION.txt
set(VERS_FILE ${SOURCE_DIR}/SC_VERSION.txt )
if( EXISTS ${SOURCE_DIR}/.git )
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags WORKING_DIRECTORY ${SOURCE_DIR}
RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COMMIT_ID )
if( NOT ${res_var} EQUAL 0 )
file( READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255 )
if(NOT SC_IS_SUBBUILD)
message( WARNING "Git failed (probably no tags in repo). Build will contain revision info from ${VERS_FILE}." )
endif(NOT SC_IS_SUBBUILD)
endif()
else(GIT_FOUND)
file( READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255 )
set(VERS_FILE ${SOURCE_DIR}/SC_VERSION.txt)
if(EXISTS ${SOURCE_DIR}/.git)
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags WORKING_DIRECTORY ${SOURCE_DIR}
RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COMMIT_ID)
if(NOT ${res_var} EQUAL 0)
file(READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255)
if(NOT SC_IS_SUBBUILD)
message(WARNING "Git failed (probably no tags in repo). Build will contain revision info from ${VERS_FILE}.")
endif(NOT SC_IS_SUBBUILD)
endif()
else(GIT_FOUND)
file(READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255)
if(NOT SC_IS_SUBBUILD)
message( WARNING "Git not found. Build will contain revision info from ${VERS_FILE}." )
message(WARNING "Git not found. Build will contain revision info from ${VERS_FILE}.")
endif(NOT SC_IS_SUBBUILD)
endif(GIT_FOUND)
endif(GIT_FOUND)
else()
file( READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255 )
if(NOT SC_IS_SUBBUILD)
message( WARNING "Git failed ('.git' not found). Build will contain revision info from ${VERS_FILE}." )
endif(NOT SC_IS_SUBBUILD)
file(READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255)
if(NOT SC_IS_SUBBUILD)
message(WARNING "Git failed ('.git' not found). Build will contain revision info from ${VERS_FILE}.")
endif(NOT SC_IS_SUBBUILD)
endif()
string( REPLACE "\n" "" GIT_COMMIT_ID ${GIT_COMMIT_ID} )
string(REPLACE "\n" "" GIT_COMMIT_ID ${GIT_COMMIT_ID})
#-------------- date and time ---------------
#once cmake_minimum_required is >= 2.8.11, we can use TIMESTAMP:
#string( TIMESTAMP date_time_string )
#string(TIMESTAMP date_time_string)
if( UNIX )
execute_process( COMMAND date "+%d %b %Y %H:%M" OUTPUT_VARIABLE date_time_string OUTPUT_STRIP_TRAILING_WHITESPACE )
elseif( WIN32 )
execute_process( COMMAND cmd /c date /t OUTPUT_VARIABLE currentDate OUTPUT_STRIP_TRAILING_WHITESPACE )
execute_process( COMMAND cmd /c time /t OUTPUT_VARIABLE currentTime OUTPUT_STRIP_TRAILING_WHITESPACE )
set ( date_time_string "${currentDate} ${currentTime}" )
if(UNIX)
execute_process(COMMAND date "+%d %b %Y %H:%M" OUTPUT_VARIABLE date_time_string OUTPUT_STRIP_TRAILING_WHITESPACE)
elseif(WIN32)
execute_process(COMMAND cmd /c date /t OUTPUT_VARIABLE currentDate OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND cmd /c time /t OUTPUT_VARIABLE currentTime OUTPUT_STRIP_TRAILING_WHITESPACE)
set (date_time_string "${currentDate} ${currentTime}")
else()
set( date_time_string "\" __DATE__ \" \" __TIME__ \" " )
if( NOT SC_IS_SUBBUILD )
message( STATUS "Unknown platform - using date from preprocessor" )
endif( NOT SC_IS_SUBBUILD )
set(date_time_string "\" __DATE__ \" \" __TIME__ \" ")
if(NOT SC_IS_SUBBUILD)
message(STATUS "Unknown platform - using date from preprocessor")
endif(NOT SC_IS_SUBBUILD)
endif()
set( header_string "/* sc_version_string.h - written by cmake. Changes will be lost! */\n"
"#ifndef SC_VERSION_STRING\n"
"#define SC_VERSION_STRING\n\n"
"/*\n** The git commit id looks like \"test-1-g5e1fb47\", where test is the\n"
"** name of the last tagged git revision, 1 is the number of commits since that tag,\n"
"** 'g' is unknown, and 5e1fb47 is the first 7 chars of the git sha1 commit id.\n"
"** timestamp is created from date/time commands on known platforms, and uses\n"
"** preprocessor macros elsewhere.\n*/\n\n"
"static char sc_version[512] = {\n"
" \"git commit id: ${GIT_COMMIT_ID}, build timestamp ${date_time_string}\"\n"
"}\;\n\n"
"#endif\n"
)
set(header_string "/* sc_version_string.h - written by cmake. Changes will be lost! */\n"
"#ifndef SC_VERSION_STRING\n"
"#define SC_VERSION_STRING\n\n"
"/*\n** The git commit id looks like \"test-1-g5e1fb47\", where test is the\n"
"** name of the last tagged git revision, 1 is the number of commits since that tag,\n"
"** 'g' is unknown, and 5e1fb47 is the first 7 chars of the git sha1 commit id.\n"
"** timestamp is created from date/time commands on known platforms, and uses\n"
"** preprocessor macros elsewhere.\n*/\n\n"
"static char sc_version[512] = {\n"
" \"git commit id: ${GIT_COMMIT_ID}, build timestamp ${date_time_string}\"\n"
"}\;\n\n"
"#endif\n"
)
file(WRITE sc_version_string.h.txt ${header_string} )
file(WRITE sc_version_string.h.txt ${header_string})
# copy the file to the final header only if the version changes
# reduces needless rebuilds
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
sc_version_string.h.txt ${BINARY_DIR}/include/sc_version_string.h)
sc_version_string.h.txt ${BINARY_DIR}/include/sc_version_string.h)
if(NOT SC_IS_SUBBUILD)
message("-- sc_version_string.h is up-to-date.")
endif(NOT SC_IS_SUBBUILD)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+77
View File
@@ -0,0 +1,77 @@
project(SC_SUBPROJECT_SCHEMA_SCANNER)
cmake_minimum_required(VERSION 2.8.7)
if(NOT ("${CALLED_FROM}" STREQUAL "STEPCODE_CMAKELISTS" AND DEFINED SC_ROOT AND DEFINED SC_BUILDDIR))
message(" ${CALLED_FROM} ${SC_ROOT} ${SC_BUILDDIR}")
message(FATAL_ERROR "This is not a truly independent project; it should be built during the STEPcode configuration stage.")
endif()
# SC_ROOT: SC root dir
# SC_BUILDDIR: SC build dir, so generated headers can be found
set(CMAKE_BUILD_TYPE Debug)
# set all target location variables so that MSVC will put the executable the same place as other compilers
set(SC_BINARY_DIR ${SC_BUILDDIR})
include(${CMAKE_CURRENT_SOURCE_DIR}/../SC_Outdirs.cmake)
set(schema_scanner_src
${SC_ROOT}/src/base/sc_mkdir.c
${SC_ROOT}/src/exp2cxx/genCxxFilenames.c
${SC_ROOT}/src/exp2cxx/class_strings.c
${SC_ROOT}/src/express/generated/expparse.c
${SC_ROOT}/src/express/generated/expscan.c
${SC_ROOT}/src/express/alg.c
${SC_ROOT}/src/express/caseitem.c
${SC_ROOT}/src/express/dict.c
${SC_ROOT}/src/express/entity.c
${SC_ROOT}/src/express/error.c
${SC_ROOT}/src/express/exp_kw.c
${SC_ROOT}/src/express/expr.c
${SC_ROOT}/src/express/express.c
${SC_ROOT}/src/express/hash.c
${SC_ROOT}/src/express/lexact.c
${SC_ROOT}/src/express/linklist.c
${SC_ROOT}/src/express/memory.c
${SC_ROOT}/src/express/object.c
${SC_ROOT}/src/express/info.c
${SC_ROOT}/src/express/resolve.c
${SC_ROOT}/src/express/schema.c
${SC_ROOT}/src/express/scope.c
${SC_ROOT}/src/express/stmt.c
${SC_ROOT}/src/express/symbol.c
${SC_ROOT}/src/express/type.c
${SC_ROOT}/src/express/variable.c
${CMAKE_CURRENT_SOURCE_DIR}/schemaScanner.cc
)
include_directories(
${SC_ROOT}/include/
${SC_ROOT}/src/express/
${SC_ROOT}/src/express/generated
${SC_ROOT}/src/base
${SC_ROOT}/src/exp2cxx
${SC_BUILDDIR}/include
)
if(MSVC)
add_definitions(-D__MSVC__ -D__WIN32__)
# Disable warning for preferred usage of secure functions (example strcpy should be strcpy_s, ...)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
elseif(BORLAND)
add_definitions(-D__BORLAND__ -D__WIN32__)
else()
add_definitions(-pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long)
endif()
add_definitions(-DSCHEMA_SCANNER)
add_executable(schema_scanner ${schema_scanner_src})
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+10
View File
@@ -0,0 +1,10 @@
README for STEPcode schema scanner
--------------
The files in this directory are for a schema scanner executable, built by CMake during the configuration stage.
This scanner is used to determine the file names that exp2cxx will use. In CMake, all file names must be known before
configuration finishes - so it is necessary to parse the schemas early.
This appears to be a standalone project to CMake, but it is intended to be built only as part of STEPcode. It is configured,
built, and executed during the configuration stage of STEPcode.
+336
View File
@@ -0,0 +1,336 @@
/** \file schemaScanner.cc
* This file, along with part of libexpress, are compiled (at configure time)
* into a static executable. This executable is a schema scanner that is used
* by CMake to determine what files exp2cxx will create. Otherwise, we'd need
* to use a few huge files - there is no other way to tell CMake what the
* generated files will be called.
*/
/* WARNING
* If you modify this file, you must re-run cmake. It doesn't seem to be possible
* to re-run cmake automatically, as CMake's configure_file() gets confused by
* the '${' and '}' in writeLists() below.
*/
extern "C" {
# include "expparse.h"
# include "expscan.h"
# include "express/scope.h"
# include "genCxxFilenames.h"
# include "sc_mkdir.h"
# include <string.h>
# if defined( _WIN32 ) || defined ( __WIN32__ )
# include <direct.h>
# define getcwd _getcwd
# else
# include <unistd.h>
# endif
}
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
int multiple_inheritance = 0;
using std::string;
using std::stringstream;
using std::endl;
using std::ofstream;
using std::cerr;
using std::cout;
/** \return true for types that exp2cxx won't generate code for */
bool notGenerated( const Type t ) {
switch( TYPEget_body( t )->type ) {
case integer_:
case real_:
case string_:
case binary_:
case boolean_:
case number_:
case logical_:
case aggregate_:
case bag_:
case set_:
case list_:
case array_:
return true;
default:
break;
}
/* from addRenameTypedefs() in multpass.c - check for renamed
* enums and selects - exp2cxx prints typedefs for them */
if( ( TYPEis_enumeration( t ) || TYPEis_select( t ) ) && ( TYPEget_head( t ) ) ) {
return true;
}
return false;
}
/** \return a short name for the schema
* this name is intended to be unique, but no special care is put into its generation
* the official schema name seems most likely to not be unique, but it is generally the longest
*
* picks the shortest of:
* * the name of the dir containing the file (if in sc/data),
* * the name of the file containing the schema (minus extension),
* * the official name of the schema, passed in arg 'longName'
*
* TODO: maybe also consider an acronym, such that 'test_array_bounds_expr' becomes 'tabe', 'TABE', 'T_A_B_E', or similar
*/
string makeShortName( const char * longName ) {
//input_filename is path to file. we will extract dir name and file name from it.
string dirname = input_filename, filename = input_filename, schname = longName;
const char slash = '/';
//for filename, get rid of dir name(s), if any, as well as the extension
size_t sl = filename.rfind( slash );
if( sl != string::npos ) {
filename.erase( 0, sl + 1 );
}
size_t dot = filename.rfind( '.' );
if( dot != string::npos ) {
filename.erase( dot );
}
//for dirname, get rid of the filename and ensure it's in data/
sl = dirname.rfind( slash );
if( sl != string::npos ) {
dirname.erase( sl );
}
const char * dat = "data";
size_t data = dirname.find( dat );
if( ( data == string::npos ) || ( dirname[ data + strlen( dat ) ] != slash ) ) {
//doesn't contain 'data/'. clear it so it'll be ignored.
dirname.clear();
} else {
//get rid of all but last dir name
dirname.erase( 0, dirname.rfind( slash ) + 1 );
}
//use dir name if it's at least 3 chars and shorter than file name
//length requirement gets rid of short, undescriptive dir names - including '.' and '..'
if( ( dirname.size() > 2 ) && ( dirname.size() < filename.size() ) ) {
filename = dirname;
}
if( strlen( longName ) < filename.size() ) {
filename = longName;
}
filename.insert( 0, "sdai_" );
return filename;
}
/** write a CMakeLists.txt file for the schema; print its directory to stdout for CMake's add_subdirectory() command */
void writeLists( const char * schemaName, stringstream & eh, stringstream & ei, int ecount,
stringstream & th, stringstream & ti, int tcount ) {
string shortName = makeShortName( schemaName );
if( mkDirIfNone( shortName.c_str() ) < 0 ) {
cerr << "Error creating directory " << shortName << " at " << __FILE__ << ":" << __LINE__;
perror( 0 );
exit( EXIT_FAILURE );
}
size_t nameLen = strlen( schemaName );
string schema_upper( nameLen, char() );
for( size_t i = 0; i < nameLen; ++i) {
schema_upper[i] = toupper(schemaName[i]);
}
string cmListsPath = shortName;
cmListsPath += "/CMakeLists.txt";
ofstream cmLists;
cmLists.open( cmListsPath.c_str() );
if( !cmLists.good() ) {
cerr << "error opening file " << cmListsPath << " - exiting." << endl;
exit( EXIT_FAILURE );
}
cmLists << "# ----- GENERATED FILE -----" << endl;
cmLists << "# ----- Do not edit! -----" << endl << endl;
cmLists << "# schema name: " << schemaName << endl;
cmLists << "# (short name: " << shortName << ")" << endl;
cmLists << "# " << ecount << " entities, " << tcount << " types" << endl << endl;
cmLists << "# targets, logic, etc are within a set of macros shared by all schemas" << endl;
cmLists << "include(${SC_CMAKE_DIR}/SC_CXX_schema_macros.cmake)" << endl;
// * 2 for headers, + 10 other files
cmLists << "set(" << shortName << "_file_count " << ( ( ecount + tcount ) * 2 ) + 10 << ")" << endl << endl;
cmLists << "PROJECT(" << shortName << ")" << endl;
cmLists << "# list headers so they can be installed - entity, type, misc" << endl;
cmLists << "set(" << shortName << "_entity_hdrs" << endl;
cmLists << eh.str();
cmLists << " )" << endl << endl;
cmLists << "set(" << shortName << "_type_hdrs" << endl;
cmLists << th.str();
cmLists << " )" << endl << endl;
cmLists << "set(" << shortName << "_misc_hdrs" << endl;
cmLists << " Sdaiclasses.h schema.h" << endl;
cmLists << " Sdai" << schema_upper << "Names.h" << endl;
cmLists << " Sdai" << schema_upper << ".h" << endl;
cmLists << " )" << endl << endl;
cmLists << "# install all headers" << endl;
cmLists << "set(all_headers ${" << shortName << "_entity_hdrs} ${" << shortName << "_type_hdrs} ${" << shortName << "_misc_hdrs})" << endl;
cmLists << "foreach( header_file ${all_headers} )" << endl;
cmLists << " set(curr_dir)" << endl;
cmLists << " get_filename_component(curr_dir ${header_file} PATH)" << endl;
cmLists << " get_filename_component(curr_name ${header_file} NAME)" << endl;
cmLists << " if (curr_dir)" << endl;
cmLists << " install( FILES ${header_file} DESTINATION \"include/schemas/" << shortName << "/${curr_dir}\" )" << endl;
cmLists << " else (curr_dir)" << endl;
cmLists << " install( FILES ${header_file} DESTINATION \"include/schemas/" << shortName << "\" )" << endl;
cmLists << " endif (curr_dir)" << endl;
cmLists << "endforeach()" << endl;
cmLists << "# implementation files - 3 lists" << endl << endl;
cmLists << "# unity build: #include small .cc files to reduce the number" << endl;
cmLists << "# of translation units that must be compiled" << endl;
cmLists << "if(SC_UNITY_BUILD)" << endl << " # turns off include statements within type and entity .cc's - the unity T.U.'s include a unity header" << endl;
cmLists << " add_definitions( -DSC_SDAI_UNITY_BUILD)" << endl;
cmLists << " set(" << shortName << "_entity_impls Sdai" << schema_upper << "_unity_entities.cc)" << endl;
cmLists << " set(" << shortName << "_type_impls Sdai" << schema_upper << "_unity_types.cc)" << endl;
cmLists << "else(SC_UNITY_BUILD)" << endl;
cmLists << " set(" << shortName << "_entity_impls" << endl;
cmLists << ei.str();
cmLists << " )" << endl << endl;
cmLists << " set(" << shortName << "_type_impls" << endl;
cmLists << ti.str();
cmLists << " )" << endl;
cmLists << "endif(SC_UNITY_BUILD)" << endl << endl;
cmLists << "set( " << shortName << "_misc_impls" << endl;
cmLists << " SdaiAll.cc compstructs.cc schema.cc" << endl;
cmLists << " Sdai" << schema_upper << ".cc" << endl;
cmLists << " Sdai" << schema_upper << ".init.cc )" << endl << endl;
cmLists << "set(schema_target_files ${" << shortName << "_entity_impls} " << "${" << shortName << "_type_impls} " << "${" << shortName << "_misc_impls})" << endl;
cmLists << "SCHEMA_TARGETS(\"" << input_filename << "\" \"" << schemaName << "\"" << endl;
cmLists << " \"${schema_target_files}\")" << endl;
cmLists.close();
char pwd[BUFSIZ] = {0};
if( getcwd( pwd, BUFSIZ ) ) {
cout << pwd << "/" << shortName << endl;
} else {
cerr << "Error encountered by getcwd() for " << shortName << " - exiting. Error was ";
perror( 0 );
exit( EXIT_FAILURE );
}
}
void printSchemaFilenames( Schema sch ){
const int numColumns = 2;
const int colWidth = 75;
const char * tab = " ";
stringstream typeHeaders, typeImpls, entityHeaders, entityImpls;
typeHeaders << tab;
typeImpls << tab;
entityHeaders << tab;
entityImpls << tab;
int ecount = 0, tcount = 0;
DictionaryEntry de;
Generic x;
filenames_t fn;
DICTdo_init( sch->symbol_table, &de );
while( 0 != ( x = DICTdo( &de ) ) ) {
switch( DICT_type ) {
case OBJ_ENTITY:
fn = getEntityFilenames( ( Entity ) x );
entityHeaders << std::left << std::setw( colWidth ) << fn.header << " ";
entityImpls << std::left << std::setw( colWidth ) << fn.impl << " ";
++ecount;
if( ( ecount % numColumns ) == 0 ) {
// columns
entityHeaders << endl << tab;
entityImpls << endl << tab;
}
break;
case OBJ_TYPE: {
Type t = ( Type ) x;
if( TYPEis_enumeration( t ) && ( TYPEget_head( t ) ) ) {
/* t is a renamed enum type, for which exp2cxx
* will print a typedef in an existing file */
break;
}
if( notGenerated( t ) ) {
/* skip builtin types */
break;
}
fn = getTypeFilenames( t );
typeHeaders << std::left << std::setw( colWidth ) << fn.header << " ";
typeImpls << std::left << std::setw( colWidth ) << fn.impl << " ";
++tcount;
if( ( tcount % numColumns ) == 0 ) {
typeHeaders << endl << tab;
typeImpls << endl << tab;
}
break;
}
/* case OBJ_FUNCTION:
* case OBJ_PROCEDURE:
* case OBJ_RULE: */
default:
/* ignore everything else */
/* TODO: if DEBUG is defined, print the names of these to stderr */
break;
}
}
//write the CMakeLists.txt
writeLists( sch->symbol.name, entityHeaders, entityImpls, ecount, typeHeaders, typeImpls, tcount );
}
int main( int argc, char ** argv ) {
/* TODO init globals! */
Schema schema;
DictionaryEntry de;
/* copied from fedex.c */
Express model;
if( ( argc != 2 ) || ( strlen( argv[1] ) < 1 ) ) {
fprintf( stderr, "\nUsage: %s file.exp\nOutput: a CMakeLists.txt to build the schema,", argv[0] );
fprintf( stderr, " containing file names for entities, types, etc\n" );
fprintf( stderr, "also prints (to stdout) the absolute path to the directory CMakeLists.txt was created in\n" );
exit( EXIT_FAILURE );
}
EXPRESSprogram_name = argv[0];
input_filename = argv[1];
EXPRESSinitialize();
model = EXPRESScreate();
EXPRESSparse( model, ( FILE * )0, input_filename );
if( ERRORoccurred ) {
EXPRESSdestroy( model );
exit( EXIT_FAILURE );
}
EXPRESSresolve( model );
if( ERRORoccurred ) {
int result = EXPRESS_fail( model );
EXPRESScleanup();
EXPRESSdestroy( model );
exit( result );
}
DICTdo_type_init( model->symbol_table, &de, OBJ_SCHEMA );
while( 0 != ( schema = ( Schema )DICTdo( &de ) ) ) {
printSchemaFilenames( schema );
}
EXPRESSdestroy( model );
exit( EXIT_SUCCESS );
}
+110
View File
@@ -0,0 +1,110 @@
# this file should be included from data/CMakeLists.txt
#
# at configure time, this builds a small program
# which will parse express schemas to determine
# what files exp2cxx will create for that schema.
#
# The SCHEMA_CMLIST macro is to be used to run this
# program. It will set variables for schema name(s),
# headers, and implementation files.
# in a unity build, many small .cc files are #included to create a few large translation units
# this makes compilation faster, but sometimes runs into compiler limitations
if(NOT DEFINED SC_UNITY_BUILD)
if(BORLAND)
message(".. Will not do unity build for this compiler.")
set(SC_UNITY_BUILD FALSE)
else()
message(".. Assuming compiler is capable of unity build.")
set(SC_UNITY_BUILD TRUE)
endif(BORLAND)
message(".. Override by setting SC_UNITY_BUILD; TRUE will result in *huge* translation units, higher memory use in compilation, and faster build times.")
else(NOT DEFINED SC_UNITY_BUILD)
message(".. Respecting user-defined SC_UNITY_BUILD value of ${SC_UNITY_BUILD}.")
endif(NOT DEFINED SC_UNITY_BUILD)
# --- variables ---
# SC_ROOT: SC root dir
# SC_BUILDDIR: SC build dir, so generated headers can be found
# SCANNER_SRC_DIR: dir this file is in
# SCANNER_OUT_DIR: location of binary, same dir as SC uses
# SCANNER_BUILD_DIR: location scanner is built
set(SCANNER_SRC_DIR ${SC_CMAKE_DIR}/schema_scanner)
set(SCANNER_BUILD_DIR ${SC_BINARY_DIR}/schema_scanner CACHE INTERNAL "location for scanner build, config files (copied schemas)")
set(SCANNER_OUT_DIR ${SC_BINARY_DIR}/bin CACHE INTERNAL "location for schema_scanner executable")
#write a cmake file for the cache. the alternative is a very long
# command line - and the command line can't have newlines in it
set(initial_scanner_cache ${SCANNER_BUILD_DIR}/initial_scanner_cache.cmake)
file(WRITE ${initial_scanner_cache} "
set(SC_ROOT \"${SC_SOURCE_DIR}\" CACHE STRING \"root dir\")
set(SC_BUILDDIR \"${SC_BINARY_DIR}\" CACHE PATH \"build dir\")
set(CALLED_FROM \"STEPCODE_CMAKELISTS\" CACHE STRING \"verification\")
set(CMAKE_BUILD_TYPE \"Debug\" CACHE STRING \"build type\")
set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE STRING \"compiler\")
set(CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\" CACHE STRING \"compiler\")
")
message("-- Compiling schema scanner...")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${SC_BINARY_DIR}/schemas)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${SCANNER_BUILD_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -C ${initial_scanner_cache} ${SCANNER_SRC_DIR} -G ${CMAKE_GENERATOR}
WORKING_DIRECTORY ${SCANNER_BUILD_DIR}
TIMEOUT 60
OUTPUT_VARIABLE _ss_config_out
RESULT_VARIABLE _ss_config_stat
ERROR_VARIABLE _ss_config_err
)
if(NOT ${_ss_config_stat} STREQUAL "0")
message(FATAL_ERROR "Scanner config status: ${_ss_config_stat}. stdout:\n${_ss_config_out}\nstderr:\n${_ss_config_err}")
endif(NOT ${_ss_config_stat} STREQUAL "0")
execute_process(COMMAND ${CMAKE_COMMAND} --build ${SCANNER_BUILD_DIR} --config Debug --clean-first
WORKING_DIRECTORY ${SCANNER_BUILD_DIR}
TIMEOUT 120 # should take far less than 2m
OUTPUT_VARIABLE _ss_build_out
RESULT_VARIABLE _ss_build_stat
ERROR_VARIABLE _ss_build_err
)
if(NOT ${_ss_build_stat} STREQUAL "0")
message(FATAL_ERROR "Scanner build status: ${_ss_build_stat}. stdout:\n${_ss_build_out}\nstderr:\n${_ss_build_err}")
endif(NOT ${_ss_build_stat} STREQUAL "0")
message("-- Schema scanner built. Running it...")
# not sure if it makes sense to install this or not...
if(WIN32)
install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner.exe DESTINATION ${BIN_INSTALL_DIR})
else(WIN32)
install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner DESTINATION ${BIN_INSTALL_DIR})
endif(WIN32)
# macro SCHEMA_CMLIST
# runs the schema scanner on one express file, creating a CMakeLists.txt file for each schema found. Those files are added via add_subdirectory().
#
# SCHEMA_FILE - path to the schema
# TODO should we have a result variable to return schema name(s) found?
macro(SCHEMA_CMLIST SCHEMA_FILE)
execute_process(COMMAND ${SCANNER_OUT_DIR}/schema_scanner ${SCHEMA_FILE}
WORKING_DIRECTORY ${SC_BINARY_DIR}/schemas
RESULT_VARIABLE _ss_stat
OUTPUT_VARIABLE _ss_out
ERROR_VARIABLE _ss_err
)
if(NOT "${_ss_stat}" STREQUAL "0")
#check size of output, put in file if large?
message(FATAL_ERROR "Schema scan for '${SCHEMA_FILE}'\nexited with error code '${_ss_stat}'\nstdout:\n${_ss_out}\nstderr:\n${_ss_err}\n")
endif(NOT "${_ss_stat}" STREQUAL "0")
# scanner output format: each line contains an absolute path. each path is a dir containing a CMakeLists for one schema
# there will usually be a single line of output, but it is not illegal for multiple schemas to exist in one .exp file
string(STRIP "${_ss_out}" _ss_stripped)
string(REGEX REPLACE "\\\n" ";" _list ${_ss_stripped})
foreach(_dir ${_list})
add_subdirectory(${_dir} ${_dir}) #specify source and binary dirs as the same
endforeach(_dir ${_ss_out})
# configure_file forces cmake to run again if the schema has been modified
#if multiple schemas in one file, _schema is the last one printed.
configure_file(${SCHEMA_FILE} ${SCANNER_BUILD_DIR}/${_schema})
endmacro(SCHEMA_CMLIST SCHEMA_FILE)
+2 -2
View File
@@ -69,8 +69,8 @@ if(NOT DEBUGGING_GENERATED_SOURCES)
endforeach(outf ${output_files})
endif(NOT LOCKED_SOURCE_DIR)
else (NOT DEBUGGING_GENERATED_SOURCES)
else(NOT DEBUGGING_GENERATED_SOURCES)
message("\nNote: DEBUGGING_GENERATED_SOURCES is enabled - generated outputs will contain configuration-specific debugging information, so syncing cached output files is not possible. To restore normal behavior, disable DEBUGGING_GENERATED_SOURCES.\n")
endif(NOT DEBUGGING_GENERATED_SOURCES)
+4 -4
View File
@@ -1,15 +1,15 @@
# Inherit the parent CMake setting
set(DEBUGGING_GENERATED_SOURCES @DEBUGGING_GENERATED_SOURCES@)
set(CURRENT_SOURCE_DIR @CMAKE_CURRENT_SOURCE_DIR@)
set(CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
# Include the file the provides the baseline against which
# current files will be compared
if(NOT DEBUGGING_GENERATED_SOURCES)
include(@BASELINE_INFORMATION_FILE@)
include("@BASELINE_INFORMATION_FILE@")
# Define a variety of convenience routines
include(@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake)
include("@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake")
# Individually verify all of the files in question.
set(filelist "@CACHED_FILELIST@")
@@ -20,7 +20,7 @@ if(NOT DEBUGGING_GENERATED_SOURCES)
message(FATAL_ERROR "Generated sources have been modified. These files should never be modified directly except when debugging faulty output from the generators - changes to lexer and parser logic should be made to the generator input files. If this is a debugging situation, set the variable DEBUGGING_GENERATED_SOURCES to ON during the CMake configure.")
endif(srcs_pass)
# If we got by that test, see if it looks like these
# If we got by that test, see if it looks like these
# sources came from the current input files. It's not
# a failure condition if they didn't, but warn about it.
set(filelist "@INPUT_FILELIST@")
+18 -10
View File
@@ -1,11 +1,11 @@
# run_ctest.cmake
# `ctest -S run_ctest.cmake`
set( CTEST_SOURCE_DIRECTORY . )
set( CTEST_BINARY_DIRECTORY build_matrix )
set( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
set( CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind )
set( CTEST_INITIAL_CACHE "
set(CTEST_SOURCE_DIRECTORY .)
set(CTEST_BINARY_DIRECTORY build_matrix)
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind)
set(CTEST_INITIAL_CACHE "
SITE:STRING=${CTEST_SITE}
BUILDNAME:STRING=${CTEST_BUILD_NAME}
SC_ENABLE_TESTING:BOOL=ON
@@ -15,11 +15,19 @@ SC_BUILD_TYPE:STRING=Debug
ctest_start(matrix)
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS -DSC_ENABLE_TESTING=ON )
ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}" )
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS -DSC_ENABLE_TESTING=ON)
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
message("running tests")
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE_LABEL "cpp_schema_....*" )
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE_LABEL "cpp_schema_....*")
message("running python script")
execute_process( COMMAND python ../misc/wiki-scripts/update-matrix.py
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} )
execute_process(COMMAND python ../misc/wiki-scripts/update-matrix.py
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY})
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+30 -175
View File
@@ -1,181 +1,36 @@
# To build one or more schemas, configure with
# 'cmake -DSC_BUILD_SCHEMAS="path/to/schema.exp;path/to/schema2.exp"
# you can specify a schema in 3 ways:
# * path relative to build dir
# * path relative to sc/data (this dir)
# * absolute path
#
# cmake goes through the above options in order until it finds one
# that exists. if ${path} is a dir, cmake expects to find a single
# .exp file inside, which it uses. otherwise, ${path} is assumed to
# be an express file.
MACRO(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
string(REPLACE "${SC_SOURCE_DIR}" "" subpath "${current_dir}")
string(REGEX REPLACE "^/" "" subpath "${subpath}")
string(LENGTH "${subpath}" PATH_LENGTH)
if(PATH_LENGTH GREATER 0)
set(${rel_path} "..")
get_filename_component(subpath "${subpath}" PATH)
string(LENGTH "${subpath}" PATH_LENGTH)
while(PATH_LENGTH GREATER 0)
set(${rel_path} "${${rel_path}}/..")
get_filename_component(subpath "${subpath}" PATH)
string(LENGTH "${subpath}" PATH_LENGTH)
endwhile(PATH_LENGTH GREATER 0)
endif(PATH_LENGTH GREATER 0)
ENDMACRO(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
if(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "")
include(${SC_CMAKE_DIR}/schema_scanner/schemaScanner.cmake)
foreach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
get_filename_component(name ${src} NAME_WE)
message(STATUS "Additional SDAI executable: ${name}")
endforeach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
# This function runs fedex on one express file. The generated source goes in a dir
# in the build dir, and it is compiled into a library. A p21read executable is
# compiled and linked to the lib. p21read is used to test the lib.
FUNCTION(BUILD_A_SCHEMA SCHEMA_FILE)
if( EXISTS "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}" ) #is it a path relative to build dir?
set( SCHEMA_FILE "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}" )
elseif( EXISTS "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}" ) # path relative to STEPcode/data?
set( SCHEMA_FILE "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}" )
elseif( NOT EXISTS ${SCHEMA_FILE} ) # absolute path
message( FATAL_ERROR "Cannot find ${CMAKE_BINARY_DIR}/${SCHEMA_FILE} or ${SC_SOURCE_DIR}/data/${SCHEMA_FILE} or ${SCHEMA_FILE}" )
endif()
if(SC_BUILD_SCHEMAS STREQUAL "ALL")
file(GLOB_RECURSE SC_BUILD_SCHEMAS ${SC_SOURCE_DIR}/data/*.exp)
endif()
foreach(FILE ${SC_BUILD_SCHEMAS})
# figure out an absolute path to the file
LOCATE_SCHEMA(${FILE} abspath)
SCHEMA_CMLIST(${abspath})
endforeach()
endif(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "")
if( IS_DIRECTORY ${SCHEMA_FILE} ) #if it is a dir, look for one .exp file inside
file(GLOB SCHEMA_FILE ${SCHEMA_FILE}/*.exp )
endif()
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
if( NOT EXISTS ${SCHEMA_FILE} )
message(FATAL_ERROR "Expected one express file. Found '${SCHEMA_FILE}' instead.")
endif()
# read the schema name from a line like 'SCHEMA AUTOMOTIVE_DESIGN;'
file(STRINGS ${SCHEMA_FILE} SCHEMA_STATEMENT LIMIT_COUNT 1 REGEX "^SCHEMA .*")
string(REGEX REPLACE "^SCHEMA \(.*\)\;$" "\\1" SCHEMA_N ${SCHEMA_STATEMENT} )
string(TOUPPER ${SCHEMA_N} SCHEMA_LONG_NAME) #exp2cxx always uses upper case for file names
get_filename_component( SCHEMA_SN ${SCHEMA_FILE} NAME )
string( REGEX REPLACE "\(.*\).[Ee][Xx][Pp]" "\\1" SCHEMA_SHORT_NAME ${SCHEMA_SN} )
project( sdai_${SCHEMA_SHORT_NAME} )
message( STATUS "Generating code for ${SCHEMA_SHORT_NAME}.")
set( SCHEMA_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_SHORT_NAME} )
#the names of the files that will be generated
set( FEDEX_HEADERS ${SCHEMA_OUTPUT_DIR}/Sdaiclasses.h ${SCHEMA_OUTPUT_DIR}/schema.h
${SCHEMA_OUTPUT_DIR}/Sdai${SCHEMA_LONG_NAME}.h )
set( FEDEX_OUT ${SCHEMA_OUTPUT_DIR}/compstructs.cc ${SCHEMA_OUTPUT_DIR}/schema.cc
${SCHEMA_OUTPUT_DIR}/Sdai${SCHEMA_LONG_NAME}.cc ${SCHEMA_OUTPUT_DIR}/SdaiAll.cc
${SCHEMA_OUTPUT_DIR}/Sdai${SCHEMA_LONG_NAME}.init.cc ${FEDEX_HEADERS} )
install( FILES ${FEDEX_HEADERS} DESTINATION include/${SCHEMA_SHORT_NAME} )
# *cannot* use include_directories() because the includes keep piling up - if building
# multiple schemas, each one will use the include dirs from all previous schemas. Since
# one header (schema.h) is always named the same, this will not work. only workaround
# seems to be set_target_properties( <target> PROPERTIES COMPILE_FLAGS <flags> )
set( ${PROJECT_NAME}_COMPILE_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR} -I${SC_SOURCE_DIR}/src/cldai -I${SC_SOURCE_DIR}/src/cleditor -I${SC_SOURCE_DIR}/src/clutils -I${SCHEMA_OUTPUT_DIR} -I${SC_SOURCE_DIR}/src/clstepcore -I${SC_SOURCE_DIR}/src/base" )
add_custom_command( OUTPUT ${SCHEMA_OUTPUT_DIR}
COMMAND ${CMAKE_COMMAND} ARGS -E make_directory ${SCHEMA_OUTPUT_DIR}
COMMENT "Creating ${SCHEMA_OUTPUT_DIR} for schema ${SCHEMA_SHORT_NAME}")
add_custom_command( OUTPUT ${FEDEX_OUT}
COMMAND exp2cxx ARGS ${SCHEMA_FILE}
DEPENDS ${SCHEMA_FILE} ${SCHEMA_OUTPUT_DIR}
WORKING_DIRECTORY ${SCHEMA_OUTPUT_DIR}
COMMENT "Running exp2cxx for ${SCHEMA_SHORT_NAME}..."
VERBATIM )
add_custom_target( generate_cpp_${SCHEMA_SHORT_NAME} DEPENDS ${FEDEX_OUT} SOURCES ${FEDEX_OUT} )
if( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
# Coverage will always be sparse on schema libs. Compiling the libs with the -fprofile-arcs and
# -ftest-coverage is extremely slow. We can avoid that by temporarily changing build type to release.
set( PREV_BUILD_TYPE ${CMAKE_BUILD_TYPE} )
set( CMAKE_BUILD_TYPE "Release" )
endif( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
# if testing is enabled, "TESTABLE" sets property EXCLUDE_FROM_ALL and prevents installation
SC_ADDLIB( ${PROJECT_NAME} "${FEDEX_OUT}" "stepdai;stepcore;stepeditor;steputils;base" "TESTABLE" )
add_dependencies( ${PROJECT_NAME} generate_cpp_${SCHEMA_SHORT_NAME} )
set_target_properties( ${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
${${PROJECT_NAME}_COMPILE_FLAGS} )
if( TARGET ${PROJECT_NAME}-static )
set_target_properties( ${PROJECT_NAME}-static PROPERTIES COMPILE_FLAGS
${${PROJECT_NAME}_COMPILE_FLAGS} )
endif( TARGET ${PROJECT_NAME}-static )
if( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
set( CMAKE_BUILD_TYPE ${PREV_BUILD_TYPE} )
endif( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
add_test( NAME generate_cpp_${SCHEMA_SHORT_NAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target generate_cpp_${SCHEMA_SHORT_NAME}
--config $<CONFIGURATION> )
add_test( NAME build_cpp_${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target p21read_${PROJECT_NAME}
--config $<CONFIGURATION> )
if(NOT WIN32)
add_test( NAME build_lazy_cpp_${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target lazy_${PROJECT_NAME}
--config $<CONFIGURATION> )
endif(NOT WIN32)
# label the tests and set dependencies
set_tests_properties( generate_cpp_${SCHEMA_SHORT_NAME} PROPERTIES LABELS cpp_schema_gen )
if(NOT WIN32)
set_tests_properties( build_lazy_cpp_${PROJECT_NAME} build_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${SCHEMA_SHORT_NAME} LABELS cpp_schema_build )
endif(NOT WIN32)
RELATIVE_PATH_TO_TOPLEVEL(${CMAKE_CURRENT_SOURCE_DIR} RELATIVE_PATH_COMPONENT)
SC_ADDEXEC( p21read_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc" "${PROJECT_NAME};base" "TESTABLE" )
if(NOT WIN32)
SC_ADDEXEC( lazy_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc" "${PROJECT_NAME};steplazyfile;stepeditor" "TESTABLE" )
endif(NOT WIN32)
add_dependencies( p21read_${PROJECT_NAME} version_string )
if(NOT WIN32)
add_dependencies( lazy_${PROJECT_NAME} version_string )
endif(NOT WIN32)
set_target_properties( p21read_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
${${PROJECT_NAME}_COMPILE_FLAGS} )
if(NOT WIN32)
set_target_properties( lazy_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${${PROJECT_NAME}_COMPILE_FLAGS} -I${SC_SOURCE_DIR}/src/base/judy/src" )
endif(NOT WIN32)
#add user-defined executables
foreach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
get_filename_component( name ${src} NAME_WE )
get_filename_component( path ${src} ABSOLUTE )
SC_ADDEXEC( ${name}_${PROJECT_NAME} "${src}" "${PROJECT_NAME};base" "TESTABLE" )
add_dependencies( ${name}_${PROJECT_NAME} version_string )
set_target_properties( ${name}_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
"${${PROJECT_NAME}_COMPILE_FLAGS} -I${path}" )
endforeach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
#find all part 21 files in schema dir, add a test for each one
get_filename_component( SCHEMA_DIR ${SCHEMA_FILE} PATH )
file( GLOB_RECURSE P21_FILES ${SCHEMA_DIR}/*.stp ${SCHEMA_DIR}/*.step ${SCHEMA_DIR}/*.p21 ${SCHEMA_DIR}/*.ifc )
foreach( TEST_FILE ${P21_FILES} )
get_filename_component( FNAME ${TEST_FILE} NAME_WE )
add_test( NAME read_write_cpp_${SCHEMA_SHORT_NAME}_${FNAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND p21read_${PROJECT_NAME} ${TEST_FILE} )
set_tests_properties( read_write_cpp_${SCHEMA_SHORT_NAME}_${FNAME} PROPERTIES DEPENDS build_cpp_${PROJECT_NAME} LABELS cpp_schema_rw )
if(NOT WIN32)
add_test( NAME read_lazy_cpp_${SCHEMA_SHORT_NAME}_${FNAME}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND lazy_${PROJECT_NAME} ${TEST_FILE} )
set_tests_properties( read_lazy_cpp_${SCHEMA_SHORT_NAME}_${FNAME} PROPERTIES DEPENDS build_lazy_cpp_${PROJECT_NAME} LABELS cpp_schema_rw )
endif(NOT WIN32)
endforeach()
ENDFUNCTION(BUILD_A_SCHEMA)
#----------------------------------------------------------------------------------------------------
if( DEFINED SC_BUILD_SCHEMAS )
foreach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
get_filename_component( name ${src} NAME_WE )
message( STATUS "Additional SDAI executable: ${name}" )
endforeach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
if( SC_BUILD_SCHEMAS STREQUAL "ALL" )
file( GLOB_RECURSE SC_BUILD_SCHEMAS ${SC_SOURCE_DIR}/data/*.exp )
endif()
foreach( ap ${SC_BUILD_SCHEMAS} )
BUILD_A_SCHEMA( ${ap} )
endforeach()
endif()
+4 -1
View File
@@ -1,6 +1,6 @@
(* This is a MODIFIED version of AP203 Amd. 1.
The change was to remove a useless IF...ELSE...ENDIF statement that always evaluated
the same way. Statements in the branch that was never executed caused problems with
the same way. Statements in the branch that were never executed caused problems with
libexpress, and it was easier to modify the schema than to come up with a generic
fix for libexpress. This change does *not* affect the behavior of the schema.
@@ -14,6 +14,9 @@
SCHEMA config_control_design;
CONSTANT
(* FIXME: gcc error on next statement with c99/POSIX:
Syntax error: "(" unexpected
*)
dummy_gri : geometric_representation_item := representation_item('') ||
geometric_representation_item();
dummy_tri : topological_representation_item := representation_item('')
+33007 -38333
View File
File diff suppressed because it is too large Load Diff
+15 -7
View File
@@ -1,12 +1,20 @@
SET(sc_MANS
man/man1/fedex.1
man/man1/exp2cxx.1
)
set(sc_MANS
man/man1/fedex.1
man/man1/exp2cxx.1
)
if(NOT DEFINED MAN_DIR)
set(MAN_DIR share/man)
endif(NOT DEFINED MAN_DIR)
IF(NOT WIN32)
INSTALL(FILES ${sc_MANS} DESTINATION ${MAN_DIR}/man1)
ENDIF(NOT WIN32)
if(NOT WIN32)
install(FILES ${sc_MANS} DESTINATION ${MAN_DIR}/man1)
endif(NOT WIN32)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+55 -51
View File
@@ -5,87 +5,91 @@
# freely copied in part or in full for any purpose. No acknowledgment is required
# for the use of this file.
#
PROJECT( AP203Minimum )
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
project(AP203Minimum)
cmake_minimum_required(VERSION 2.8)
# Set STEPCODE_ROOT_DIR to point to the root of the STEPcode source tree.
if( NOT DEFINED STEPCODE_ROOT_DIR )
message( FATAL_ERROR "STEPCODE_ROOT_DIR is not defined! Set via cmake-gui or on command line:\n cmake .. -DSTEPCODE_ROOT_DIR=/path/to/sc" )
endif( NOT DEFINED STEPCODE_ROOT_DIR )
if(NOT DEFINED STEPCODE_ROOT_DIR)
message(FATAL_ERROR "STEPCODE_ROOT_DIR is not defined! Set via cmake-gui or on command line:\n cmake .. -DSTEPCODE_ROOT_DIR=/path/to/sc")
endif(NOT DEFINED STEPCODE_ROOT_DIR)
# STEPCODE_ROOT_DIR is relative or absolute path?
if( EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
set( STEPCODE_ROOT_DIR "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}" )
message( "** STEPCODE_ROOT_DIR is a relative path; converted to absolute path: ${STEPCODE_ROOT_DIR}." )
if(EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
set(STEPCODE_ROOT_DIR "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}")
message("** STEPCODE_ROOT_DIR is a relative path; converted to absolute path: ${STEPCODE_ROOT_DIR}.")
else()
if( NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
message( FATAL_ERROR "**** Cannot locate STEPCODE_ROOT_DIR - try an absolute path." )
endif( NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
endif( EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
if(NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
message(FATAL_ERROR "**** Cannot locate STEPCODE_ROOT_DIR - try an absolute path.")
endif(NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
endif(EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
# Use STEPcode as library, but build from this build process.
set( SC_IS_SUBBUILD TRUE )
set(SC_IS_SUBBUILD TRUE)
# Build type, DEBUG or RELEASE
if( NOT DEFINED CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Debug )
endif( NOT DEFINED CMAKE_BUILD_TYPE )
set( SC_BUILD_TYPE ${CMAKE_BUILD_TYPE} )
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif(NOT DEFINED CMAKE_BUILD_TYPE)
set(SC_BUILD_TYPE ${CMAKE_BUILD_TYPE})
# Path to STEPcode
set( STEPCODE_BUILD_DIR ${CMAKE_BINARY_DIR}/sc CACHE PATH "STEPcode build subdir" )
set(STEPCODE_BUILD_DIR ${CMAKE_BINARY_DIR}/sc CACHE PATH "STEPcode build subdir")
# STEP schema to build and link against.
set( SCHEMA ap203 )
set( SC_BUILD_SCHEMAS ${SCHEMA} CACHE INTERNAL "Schema, internal, immutable" FORCE )
set(SCHEMA ap203)
set(SC_BUILD_SCHEMAS ${SCHEMA} CACHE INTERNAL "Schema, internal, immutable" FORCE)
# Parse out schema name and library.
set( SCHEMA_PATH "${STEPCODE_ROOT_DIR}/data/${SCHEMA}/*.exp" )
file( GLOB SCHEMA_FILE "${SCHEMA_PATH}" )
set(SCHEMA_PATH "${STEPCODE_ROOT_DIR}/data/${SCHEMA}/*.exp")
file(GLOB SCHEMA_FILE "${SCHEMA_PATH}")
if( NOT EXISTS ${SCHEMA_FILE} )
message( FATAL_ERROR "Cannot find the schema; cannot continue. Looked for ${SCHEMA_PATH} from ${CMAKE_CURRENT_LIST_DIR}" )
endif( NOT EXISTS ${SCHEMA_FILE} )
if(NOT EXISTS ${SCHEMA_FILE})
message(FATAL_ERROR "Cannot find the schema; cannot continue. Looked for ${SCHEMA_PATH} from ${CMAKE_CURRENT_LIST_DIR}")
endif(NOT EXISTS ${SCHEMA_FILE})
get_filename_component( SCHEMA_SN ${SCHEMA_FILE} NAME )
string( REGEX REPLACE "\(.*\).[Ee][Xx][Pp]" "\\1" SCHEMA_LINK_NAME ${SCHEMA_SN} )
set( STEPCODE_LIBRARIES base stepcore stepeditor stepdai steputils sdai_${SCHEMA_LINK_NAME} )
get_filename_component(SCHEMA_SN ${SCHEMA_FILE} NAME)
string(REGEX REPLACE "\(.*\).[Ee][Xx][Pp]" "sdai_\\1" SCHEMA_LINK_NAME ${SCHEMA_SN})
set(STEPCODE_LIBRARIES base stepcore stepeditor stepdai steputils ${SCHEMA_LINK_NAME})
# Add STEPCode project to CMake build.
add_subdirectory( ${STEPCODE_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/sc" EXCLUDE_FROM_ALL )
add_subdirectory(${STEPCODE_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/sc" EXCLUDE_FROM_ALL)
# Set up STEPcode include directories.
set( STEPCODE_INCLUDE_DIR
${STEPCODE_ROOT_DIR}/src/base
${STEPCODE_ROOT_DIR}/src/clstepcore
${STEPCODE_ROOT_DIR}/src/cldai
${STEPCODE_ROOT_DIR}/src/clutils
${STEPCODE_ROOT_DIR}/src/cleditor
${STEPCODE_BUILD_DIR}/include
${STEPCODE_ROOT_DIR}/include
${CMAKE_BINARY_DIR}
)
set(STEPCODE_INCLUDE_DIR
${STEPCODE_ROOT_DIR}/src/base
${STEPCODE_ROOT_DIR}/src/clstepcore
${STEPCODE_ROOT_DIR}/src/cldai
${STEPCODE_ROOT_DIR}/src/clutils
${STEPCODE_ROOT_DIR}/src/cleditor
${STEPCODE_BUILD_DIR}/include
${STEPCODE_ROOT_DIR}/include
${CMAKE_BINARY_DIR}
${STEPCODE_BUILD_DIR}/schemas/${SCHEMA_LINK_NAME}
)
# Reset sane values for build destination. Otherwise, everything ends up in ${CMAKE_BINARY_DIR}/sc
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories(
${STEPCODE_INCLUDE_DIR}
)
${STEPCODE_INCLUDE_DIR}
)
# Application sources and headers
set( SRCS
ap203min.cpp
)
set(SRCS ap203min.cpp)
set( HDRS
)
set(HDRS )
add_executable( ${PROJECT_NAME} ${SRCS} ${HDRS} )
add_executable(${PROJECT_NAME} ${SRCS} ${HDRS})
target_link_libraries( ${PROJECT_NAME} ${STEPCODE_LIBRARIES} )
target_link_libraries(${PROJECT_NAME} ${STEPCODE_LIBRARIES})
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
set_target_properties( ${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-I${STEPCODE_BUILD_DIR}/data/${SCHEMA_LINK_NAME}" )
-4
View File
@@ -49,10 +49,6 @@
// $./AP203Minimum
// AP203Minimum outfile.stp
extern void
SchemaInit( class Registry & );
#include <STEPfile.h>
#include <sdai.h>
#include <STEPattribute.h>
+19 -11
View File
@@ -1,4 +1,4 @@
SET(express_HDRS
set(express_HDRS
express/alg.h
express/basic.h
express/caseitem.h
@@ -20,21 +20,29 @@ SET(express_HDRS
express/symbol.h
express/type.h
express/variable.h
)
)
install(FILES ${express_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/express)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/express)
SET(exppp_HDRS
set(exppp_HDRS
exppp/exppp.h
)
)
install(FILES ${exppp_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/exppp)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/exppp)
install(FILES ordered_attrs.h
sc_export.h
sc_stdbool.h
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
sc_export.h
sc_stdbool.h
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
install(FILES ${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_cf.h
${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+1 -1
View File
@@ -69,7 +69,7 @@ struct tag {
/** location of fulltext of algorithm in source file */
struct FullText {
char * filename;
const char * filename;
unsigned int start, end;
};
+1 -1
View File
@@ -83,7 +83,7 @@ typedef struct Error_Warning_ {
/********************/
extern SC_EXPRESS_EXPORT bool __ERROR_buffer_errors;
extern SC_EXPRESS_EXPORT char * current_filename;
extern SC_EXPRESS_EXPORT const char * current_filename;
/* flag to remember whether non-warning errors have occurred */
extern SC_EXPRESS_EXPORT bool ERRORoccurred;
+127
View File
@@ -0,0 +1,127 @@
#ifndef EXP_KW_H
#define EXP_KW_H
#include "sc_export.h"
extern SC_EXPRESS_EXPORT char * KW_ABS;
extern SC_EXPRESS_EXPORT char * KW_ABSTRACT;
extern SC_EXPRESS_EXPORT char * KW_ACOS;
extern SC_EXPRESS_EXPORT char * KW_AGGREGATE;
extern SC_EXPRESS_EXPORT char * KW_ALIAS;
extern SC_EXPRESS_EXPORT char * KW_AND;
extern SC_EXPRESS_EXPORT char * KW_ANDOR;
extern SC_EXPRESS_EXPORT char * KW_ARRAY;
extern SC_EXPRESS_EXPORT char * KW_AS;
extern SC_EXPRESS_EXPORT char * KW_ASIN;
extern SC_EXPRESS_EXPORT char * KW_ATAN;
extern SC_EXPRESS_EXPORT char * KW_BAG;
extern SC_EXPRESS_EXPORT char * KW_BEGIN;
extern SC_EXPRESS_EXPORT char * KW_BINARY;
extern SC_EXPRESS_EXPORT char * KW_BLENGTH;
extern SC_EXPRESS_EXPORT char * KW_BOOLEAN;
extern SC_EXPRESS_EXPORT char * KW_BY;
extern SC_EXPRESS_EXPORT char * KW_CASE;
extern SC_EXPRESS_EXPORT char * KW_CONST_E;
extern SC_EXPRESS_EXPORT char * KW_CONSTANT;
extern SC_EXPRESS_EXPORT char * KW_CONTEXT;
extern SC_EXPRESS_EXPORT char * KW_COS;
extern SC_EXPRESS_EXPORT char * KW_DERIVE;
extern SC_EXPRESS_EXPORT char * KW_DIV;
extern SC_EXPRESS_EXPORT char * KW_ELSE;
extern SC_EXPRESS_EXPORT char * KW_END;
extern SC_EXPRESS_EXPORT char * KW_END_ALIAS;
extern SC_EXPRESS_EXPORT char * KW_END_CASE;
extern SC_EXPRESS_EXPORT char * KW_END_CONSTANT;
extern SC_EXPRESS_EXPORT char * KW_END_CONTEXT;
extern SC_EXPRESS_EXPORT char * KW_END_ENTITY;
extern SC_EXPRESS_EXPORT char * KW_END_FUNCTION;
extern SC_EXPRESS_EXPORT char * KW_END_IF;
extern SC_EXPRESS_EXPORT char * KW_END_LOCAL;
extern SC_EXPRESS_EXPORT char * KW_END_MODEL;
extern SC_EXPRESS_EXPORT char * KW_END_PROCEDURE;
extern SC_EXPRESS_EXPORT char * KW_END_REPEAT;
extern SC_EXPRESS_EXPORT char * KW_END_RULE;
extern SC_EXPRESS_EXPORT char * KW_END_SCHEMA;
extern SC_EXPRESS_EXPORT char * KW_END_TYPE;
extern SC_EXPRESS_EXPORT char * KW_ENTITY;
extern SC_EXPRESS_EXPORT char * KW_ENUMERATION;
extern SC_EXPRESS_EXPORT char * KW_ESCAPE;
extern SC_EXPRESS_EXPORT char * KW_EXISTS;
extern SC_EXPRESS_EXPORT char * KW_EXP;
extern SC_EXPRESS_EXPORT char * KW_FALSE;
extern SC_EXPRESS_EXPORT char * KW_FIXED;
extern SC_EXPRESS_EXPORT char * KW_FOR;
extern SC_EXPRESS_EXPORT char * KW_FORMAT;
extern SC_EXPRESS_EXPORT char * KW_FROM;
extern SC_EXPRESS_EXPORT char * KW_FUNCTION;
extern SC_EXPRESS_EXPORT char * KW_GENERIC;
extern SC_EXPRESS_EXPORT char * KW_HIBOUND;
extern SC_EXPRESS_EXPORT char * KW_HIINDEX;
extern SC_EXPRESS_EXPORT char * KW_IF;
extern SC_EXPRESS_EXPORT char * KW_IN;
extern SC_EXPRESS_EXPORT char * KW_INCLUDE;
extern SC_EXPRESS_EXPORT char * KW_INSERT;
extern SC_EXPRESS_EXPORT char * KW_INTEGER;
extern SC_EXPRESS_EXPORT char * KW_INVERSE;
extern SC_EXPRESS_EXPORT char * KW_LENGTH;
extern SC_EXPRESS_EXPORT char * KW_LIKE;
extern SC_EXPRESS_EXPORT char * KW_LIST;
extern SC_EXPRESS_EXPORT char * KW_LOBOUND;
extern SC_EXPRESS_EXPORT char * KW_LOCAL;
extern SC_EXPRESS_EXPORT char * KW_LOG;
extern SC_EXPRESS_EXPORT char * KW_LOG10;
extern SC_EXPRESS_EXPORT char * KW_LOG2;
extern SC_EXPRESS_EXPORT char * KW_LOGICAL;
extern SC_EXPRESS_EXPORT char * KW_LOINDEX;
extern SC_EXPRESS_EXPORT char * KW_MOD;
extern SC_EXPRESS_EXPORT char * KW_MODEL;
extern SC_EXPRESS_EXPORT char * KW_NOT;
extern SC_EXPRESS_EXPORT char * KW_NUMBER;
extern SC_EXPRESS_EXPORT char * KW_NVL;
extern SC_EXPRESS_EXPORT char * KW_ODD;
extern SC_EXPRESS_EXPORT char * KW_OF;
extern SC_EXPRESS_EXPORT char * KW_ONEOF;
extern SC_EXPRESS_EXPORT char * KW_OPTIONAL;
extern SC_EXPRESS_EXPORT char * KW_OR;
extern SC_EXPRESS_EXPORT char * KW_OTHERWISE;
extern SC_EXPRESS_EXPORT char * KW_PI;
extern SC_EXPRESS_EXPORT char * KW_PROCEDURE;
extern SC_EXPRESS_EXPORT char * KW_QUERY;
extern SC_EXPRESS_EXPORT char * KW_REAL;
extern SC_EXPRESS_EXPORT char * KW_REFERENCE;
extern SC_EXPRESS_EXPORT char * KW_REMOVE;
extern SC_EXPRESS_EXPORT char * KW_REPEAT;
extern SC_EXPRESS_EXPORT char * KW_RETURN;
extern SC_EXPRESS_EXPORT char * KW_ROLESOF;
extern SC_EXPRESS_EXPORT char * KW_RULE;
extern SC_EXPRESS_EXPORT char * KW_SCHEMA;
extern SC_EXPRESS_EXPORT char * KW_SELECT;
extern SC_EXPRESS_EXPORT char * KW_SELF;
extern SC_EXPRESS_EXPORT char * KW_SET;
extern SC_EXPRESS_EXPORT char * KW_SIN;
extern SC_EXPRESS_EXPORT char * KW_SIZEOF;
extern SC_EXPRESS_EXPORT char * KW_SKIP;
extern SC_EXPRESS_EXPORT char * KW_SQRT;
extern SC_EXPRESS_EXPORT char * KW_STRING;
extern SC_EXPRESS_EXPORT char * KW_SUBTYPE;
extern SC_EXPRESS_EXPORT char * KW_SUPERTYPE;
extern SC_EXPRESS_EXPORT char * KW_TAN;
extern SC_EXPRESS_EXPORT char * KW_THEN;
extern SC_EXPRESS_EXPORT char * KW_TO;
extern SC_EXPRESS_EXPORT char * KW_TRUE;
extern SC_EXPRESS_EXPORT char * KW_TYPE;
extern SC_EXPRESS_EXPORT char * KW_TYPEOF;
extern SC_EXPRESS_EXPORT char * KW_UNIQUE;
extern SC_EXPRESS_EXPORT char * KW_UNKNOWN;
extern SC_EXPRESS_EXPORT char * KW_UNTIL;
extern SC_EXPRESS_EXPORT char * KW_USE;
extern SC_EXPRESS_EXPORT char * KW_USEDIN;
extern SC_EXPRESS_EXPORT char * KW_VALUE;
extern SC_EXPRESS_EXPORT char * KW_VALUE_IN;
extern SC_EXPRESS_EXPORT char * KW_VALUE_UNIQUE;
extern SC_EXPRESS_EXPORT char * KW_VAR;
extern SC_EXPRESS_EXPORT char * KW_WHERE;
extern SC_EXPRESS_EXPORT char * KW_WHILE;
extern SC_EXPRESS_EXPORT char * KW_XOR;
#endif /* EXP_KW_H */
+2 -125
View File
@@ -115,127 +115,6 @@ extern SC_EXPRESS_EXPORT Error ERROR_warn_small_real;
extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_NVL;
extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_USEDIN;
extern SC_EXPRESS_EXPORT char * KW_ABS;
extern SC_EXPRESS_EXPORT char * KW_ABSTRACT;
extern SC_EXPRESS_EXPORT char * KW_ACOS;
extern SC_EXPRESS_EXPORT char * KW_AGGREGATE;
extern SC_EXPRESS_EXPORT char * KW_ALIAS;
extern SC_EXPRESS_EXPORT char * KW_AND;
extern SC_EXPRESS_EXPORT char * KW_ANDOR;
extern SC_EXPRESS_EXPORT char * KW_ARRAY;
extern SC_EXPRESS_EXPORT char * KW_AS;
extern SC_EXPRESS_EXPORT char * KW_ASIN;
extern SC_EXPRESS_EXPORT char * KW_ATAN;
extern SC_EXPRESS_EXPORT char * KW_BAG;
extern SC_EXPRESS_EXPORT char * KW_BEGIN;
extern SC_EXPRESS_EXPORT char * KW_BINARY;
extern SC_EXPRESS_EXPORT char * KW_BLENGTH;
extern SC_EXPRESS_EXPORT char * KW_BOOLEAN;
extern SC_EXPRESS_EXPORT char * KW_BY;
extern SC_EXPRESS_EXPORT char * KW_CASE;
extern SC_EXPRESS_EXPORT char * KW_CONST_E;
extern SC_EXPRESS_EXPORT char * KW_CONSTANT;
extern SC_EXPRESS_EXPORT char * KW_CONTEXT;
extern SC_EXPRESS_EXPORT char * KW_COS;
extern SC_EXPRESS_EXPORT char * KW_DERIVE;
extern SC_EXPRESS_EXPORT char * KW_DIV;
extern SC_EXPRESS_EXPORT char * KW_ELSE;
extern SC_EXPRESS_EXPORT char * KW_END;
extern SC_EXPRESS_EXPORT char * KW_END_ALIAS;
extern SC_EXPRESS_EXPORT char * KW_END_CASE;
extern SC_EXPRESS_EXPORT char * KW_END_CONSTANT;
extern SC_EXPRESS_EXPORT char * KW_END_CONTEXT;
extern SC_EXPRESS_EXPORT char * KW_END_ENTITY;
extern SC_EXPRESS_EXPORT char * KW_END_FUNCTION;
extern SC_EXPRESS_EXPORT char * KW_END_IF;
extern SC_EXPRESS_EXPORT char * KW_END_LOCAL;
extern SC_EXPRESS_EXPORT char * KW_END_MODEL;
extern SC_EXPRESS_EXPORT char * KW_END_PROCEDURE;
extern SC_EXPRESS_EXPORT char * KW_END_REPEAT;
extern SC_EXPRESS_EXPORT char * KW_END_RULE;
extern SC_EXPRESS_EXPORT char * KW_END_SCHEMA;
extern SC_EXPRESS_EXPORT char * KW_END_TYPE;
extern SC_EXPRESS_EXPORT char * KW_ENTITY;
extern SC_EXPRESS_EXPORT char * KW_ENUMERATION;
extern SC_EXPRESS_EXPORT char * KW_ESCAPE;
extern SC_EXPRESS_EXPORT char * KW_EXISTS;
extern SC_EXPRESS_EXPORT char * KW_EXP;
extern SC_EXPRESS_EXPORT char * KW_FALSE;
extern SC_EXPRESS_EXPORT char * KW_FIXED;
extern SC_EXPRESS_EXPORT char * KW_FOR;
extern SC_EXPRESS_EXPORT char * KW_FORMAT;
extern SC_EXPRESS_EXPORT char * KW_FROM;
extern SC_EXPRESS_EXPORT char * KW_FUNCTION;
extern SC_EXPRESS_EXPORT char * KW_GENERIC;
extern SC_EXPRESS_EXPORT char * KW_HIBOUND;
extern SC_EXPRESS_EXPORT char * KW_HIINDEX;
extern SC_EXPRESS_EXPORT char * KW_IF;
extern SC_EXPRESS_EXPORT char * KW_IN;
extern SC_EXPRESS_EXPORT char * KW_INCLUDE;
extern SC_EXPRESS_EXPORT char * KW_INSERT;
extern SC_EXPRESS_EXPORT char * KW_INTEGER;
extern SC_EXPRESS_EXPORT char * KW_INVERSE;
extern SC_EXPRESS_EXPORT char * KW_LENGTH;
extern SC_EXPRESS_EXPORT char * KW_LIKE;
extern SC_EXPRESS_EXPORT char * KW_LIST;
extern SC_EXPRESS_EXPORT char * KW_LOBOUND;
extern SC_EXPRESS_EXPORT char * KW_LOCAL;
extern SC_EXPRESS_EXPORT char * KW_LOG;
extern SC_EXPRESS_EXPORT char * KW_LOG10;
extern SC_EXPRESS_EXPORT char * KW_LOG2;
extern SC_EXPRESS_EXPORT char * KW_LOGICAL;
extern SC_EXPRESS_EXPORT char * KW_LOINDEX;
extern SC_EXPRESS_EXPORT char * KW_MOD;
extern SC_EXPRESS_EXPORT char * KW_MODEL;
extern SC_EXPRESS_EXPORT char * KW_NOT;
extern SC_EXPRESS_EXPORT char * KW_NUMBER;
extern SC_EXPRESS_EXPORT char * KW_NVL;
extern SC_EXPRESS_EXPORT char * KW_ODD;
extern SC_EXPRESS_EXPORT char * KW_OF;
extern SC_EXPRESS_EXPORT char * KW_ONEOF;
extern SC_EXPRESS_EXPORT char * KW_OPTIONAL;
extern SC_EXPRESS_EXPORT char * KW_OR;
extern SC_EXPRESS_EXPORT char * KW_OTHERWISE;
extern SC_EXPRESS_EXPORT char * KW_PI;
extern SC_EXPRESS_EXPORT char * KW_PROCEDURE;
extern SC_EXPRESS_EXPORT char * KW_QUERY;
extern SC_EXPRESS_EXPORT char * KW_REAL;
extern SC_EXPRESS_EXPORT char * KW_REFERENCE;
extern SC_EXPRESS_EXPORT char * KW_REMOVE;
extern SC_EXPRESS_EXPORT char * KW_REPEAT;
extern SC_EXPRESS_EXPORT char * KW_RETURN;
extern SC_EXPRESS_EXPORT char * KW_ROLESOF;
extern SC_EXPRESS_EXPORT char * KW_RULE;
extern SC_EXPRESS_EXPORT char * KW_SCHEMA;
extern SC_EXPRESS_EXPORT char * KW_SELECT;
extern SC_EXPRESS_EXPORT char * KW_SELF;
extern SC_EXPRESS_EXPORT char * KW_SET;
extern SC_EXPRESS_EXPORT char * KW_SIN;
extern SC_EXPRESS_EXPORT char * KW_SIZEOF;
extern SC_EXPRESS_EXPORT char * KW_SKIP;
extern SC_EXPRESS_EXPORT char * KW_SQRT;
extern SC_EXPRESS_EXPORT char * KW_STRING;
extern SC_EXPRESS_EXPORT char * KW_SUBTYPE;
extern SC_EXPRESS_EXPORT char * KW_SUPERTYPE;
extern SC_EXPRESS_EXPORT char * KW_TAN;
extern SC_EXPRESS_EXPORT char * KW_THEN;
extern SC_EXPRESS_EXPORT char * KW_TO;
extern SC_EXPRESS_EXPORT char * KW_TRUE;
extern SC_EXPRESS_EXPORT char * KW_TYPE;
extern SC_EXPRESS_EXPORT char * KW_TYPEOF;
extern SC_EXPRESS_EXPORT char * KW_UNIQUE;
extern SC_EXPRESS_EXPORT char * KW_UNKNOWN;
extern SC_EXPRESS_EXPORT char * KW_UNTIL;
extern SC_EXPRESS_EXPORT char * KW_USE;
extern SC_EXPRESS_EXPORT char * KW_USEDIN;
extern SC_EXPRESS_EXPORT char * KW_VALUE;
extern SC_EXPRESS_EXPORT char * KW_VALUE_IN;
extern SC_EXPRESS_EXPORT char * KW_VALUE_UNIQUE;
extern SC_EXPRESS_EXPORT char * KW_VAR;
extern SC_EXPRESS_EXPORT char * KW_WHERE;
extern SC_EXPRESS_EXPORT char * KW_WHILE;
extern SC_EXPRESS_EXPORT char * KW_XOR;
/******************************/
/* macro function definitions */
/******************************/
@@ -255,11 +134,9 @@ extern SC_EXPRESS_EXPORT void EXPRESSparse PROTO( ( Express, FILE *, ch
extern SC_EXPRESS_EXPORT void EXPRESSinitialize PROTO( ( void ) );
extern SC_EXPRESS_EXPORT void EXPRESScleanup PROTO( ( void ) );
extern SC_EXPRESS_EXPORT void EXPRESSresolve PROTO( ( Express ) );
extern SC_EXPRESS_EXPORT char * EXPRESSversion PROTO( ( void ) );
extern SC_EXPRESS_EXPORT int EXPRESS_fail PROTO( ( Express ) );
extern SC_EXPRESS_EXPORT int EXPRESS_succeed PROTO( ( Express ) );
extern SC_EXPRESS_EXPORT int EXPRESS_fail( Express model );
extern SC_EXPRESS_EXPORT int EXPRESS_succeed( Express model );
extern void EXPRESSinit_init PROTO( ( void ) );
extern SC_EXPRESS_EXPORT void EXPRESSusage( int _exit ); /**< exit unless _exit is non-zero */
extern SC_EXPRESS_EXPORT void build_complex( Express );
#endif /*EXPRESS_H*/
+14
View File
@@ -0,0 +1,14 @@
#ifndef INFO_H
#define INFO_H
#include "sc_export.h"
/** \file info.h
* informative functions that were in express.c/express.h
*/
extern SC_EXPRESS_EXPORT char * EXPRESSversion( void );
/** print usage message, then exit if _exit is non-zero */
extern SC_EXPRESS_EXPORT void EXPRESSusage( int _exit );
#endif /* INFO_H */
+1 -1
View File
@@ -58,7 +58,7 @@ typedef struct Scan_Buffer {
#endif
char * savedPos;
FILE * file;
char * filename;
const char * filename;
bool readEof;
int lineno;
int bol;
+2
View File
@@ -129,6 +129,8 @@ extern SC_EXPRESS_EXPORT void LISTinitialize PROTO( ( void ) );
extern SC_EXPRESS_EXPORT void LISTcleanup PROTO( ( void ) );
extern SC_EXPRESS_EXPORT Linked_List LISTcreate PROTO( ( void ) );
extern SC_EXPRESS_EXPORT Linked_List LISTcopy PROTO( ( Linked_List ) );
extern SC_EXPRESS_EXPORT void LISTsort PROTO( ( Linked_List, int (*comp)(void*, void*) ) );
extern SC_EXPRESS_EXPORT void LISTswap PROTO( ( Link, Link ) );
extern SC_EXPRESS_EXPORT Generic LISTadd_first PROTO( ( Linked_List, Generic ) );
extern SC_EXPRESS_EXPORT Generic LISTadd_last PROTO( ( Linked_List, Generic ) );
extern SC_EXPRESS_EXPORT Generic LISTadd_after PROTO( ( Linked_List, Link, Generic ) );
+2 -2
View File
@@ -59,7 +59,7 @@ typedef struct Symbol_ Symbol;
struct Symbol_ {
char * name;
char * filename;
const char * filename;
int line;
char resolved;
};
@@ -89,6 +89,6 @@ extern SC_EXPRESS_EXPORT struct freelist_head SYMBOL_fl;
/***********************/
extern SC_EXPRESS_EXPORT void SYMBOLinitialize PROTO( ( void ) );
SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int line, char * filename );
SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int line, const char * filename );
#endif /* SYMBOL_H */
+1
View File
@@ -164,6 +164,7 @@ struct TypeBody_ {
* element = expression [ ':' repetition ] .
* TODO exp2cxx and exp2py do not use this! Are all use cases handled by libexppp?
*/
unsigned var : 1; /** denotes variable marked 'VAR' - i.e. one where changes are propagated back to the caller */
unsigned encoded : 1; /**< encoded string */
} flags;
Type base; /**< underlying base type if any can also contain true type if this type is a type reference */
+1 -1
View File
@@ -79,7 +79,7 @@ struct Variable_ {
Expression name; /**< Symbol is inside of 'name' */
Type type;
Expression initializer; /**< or 'derived' */
int offset;
int offset; /**< used for attr order in Entitys, and for decl order in LOCAL vars. these two uses should never conflict! */
struct {
unsigned int optional : 1; /**< OPTIONAL keyword */
+37 -29
View File
@@ -1,15 +1,15 @@
# lcov.cmake
# `ctest -S lcov.cmake`
if( NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
message( FATAL_ERROR "LCOV is Linux-only" )
endif( NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
message(FATAL_ERROR "LCOV is Linux-only")
endif(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set( CTEST_SOURCE_DIRECTORY . )
set( CTEST_BINARY_DIRECTORY build_lcov )
set( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
set( CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind )
set( CTEST_INITIAL_CACHE "
set(CTEST_SOURCE_DIRECTORY .)
set(CTEST_BINARY_DIRECTORY build_lcov)
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind)
set(CTEST_INITIAL_CACHE "
SITE:STRING=${CTEST_SITE}
BUILDNAME:STRING=${CTEST_BUILD_NAME}
SC_ENABLE_TESTING:BOOL=ON
@@ -18,42 +18,50 @@ SC_BUILD_SCHEMAS:STRING=ALL
SC_BUILD_TYPE:STRING=Debug
")
set( LCOV_OUT "${CTEST_BINARY_DIRECTORY}/lcov_html" )
set(LCOV_OUT "${CTEST_BINARY_DIRECTORY}/lcov_html")
ctest_start(lcov)
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
message("configuring...")
ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS "-DSC_BUILD_SCHEMAS=ALL;-DSC_ENABLE_COVERAGE=ON;-SC_PYTHON_GENERATOR=OFF" )
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS "-DSC_BUILD_SCHEMAS=ALL;-DSC_ENABLE_COVERAGE=ON;-SC_PYTHON_GENERATOR=OFF")
message("lcov: resetting counters...")
execute_process( COMMAND lcov -z -d .
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET )
execute_process(COMMAND lcov -z -d .
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET)
# copy files so lcov won't complain
execute_process( COMMAND ${CMAKE_COMMAND} -E copy src/express/expparse.y ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir )
execute_process( COMMAND ${CMAKE_COMMAND} -E copy src/express/expscan.l ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir )
execute_process(COMMAND ${CMAKE_COMMAND} -E copy src/express/expparse.y ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy src/express/expscan.l ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir)
message("building...")
ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}" )
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
message("running tests...")
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" PARALLEL_LEVEL 1 )
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" PARALLEL_LEVEL 1)
message( "analyzing profiling data using lcov..." )
execute_process( COMMAND lcov -c -d . -o stepcode.lcov
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET )
message("analyzing profiling data using lcov...")
execute_process(COMMAND lcov -c -d . -o stepcode.lcov
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET)
message("removing system headers...")
execute_process( COMMAND lcov -r stepcode.lcov "/usr/include/*" -o stepcode_no_usr.lcov
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET )
execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${LCOV_OUT} )
execute_process(COMMAND lcov -r stepcode.lcov "/usr/include/*" -o stepcode_no_usr.lcov
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${LCOV_OUT})
message( "creating html files..." )
execute_process( COMMAND genhtml ../stepcode_no_usr.lcov
WORKING_DIRECTORY ${LCOV_OUT} OUTPUT_QUIET ERROR_QUIET )
message("creating html files...")
execute_process(COMMAND genhtml ../stepcode_no_usr.lcov
WORKING_DIRECTORY ${LCOV_OUT} OUTPUT_QUIET ERROR_QUIET)
message( "html files are located in ${LCOV_OUT}" )
execute_process( COMMAND ${CMAKE_COMMAND} -E tar czf ${LCOV_OUT}.tgz ${LCOV_OUT} WORKING_DIRECTORY ${CTEST_SOURCE_DIRECTORY} )
message("html files are located in ${LCOV_OUT}")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar czf ${LCOV_OUT}.tgz ${LCOV_OUT} WORKING_DIRECTORY ${CTEST_SOURCE_DIRECTORY})
message( "tarball at ${LCOV_OUT}.tgz" )
message("tarball at ${LCOV_OUT}.tgz")
message("================================================ Success! ================================================")
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
message( "================================================ Success! ================================================" )
+66 -58
View File
@@ -1,11 +1,11 @@
# run_ctest.cmake
# `ctest -S run_ctest.cmake`
set( CTEST_SOURCE_DIRECTORY . )
set( CTEST_BINARY_DIRECTORY build_ctest )
set( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
set( CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind )
set( CTEST_INITIAL_CACHE "
set(CTEST_SOURCE_DIRECTORY .)
set(CTEST_BINARY_DIRECTORY build_ctest)
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind)
set(CTEST_INITIAL_CACHE "
SITE:STRING=${CTEST_SITE}
BUILDNAME:STRING=${CTEST_BUILD_NAME}
SC_ENABLE_TESTING:BOOL=ON
@@ -14,11 +14,11 @@ SC_BUILD_TYPE:STRING=Debug
if( EXISTS "../.SC_CTEST_PREFS.cmake" )
include( "../.SC_CTEST_PREFS.cmake" )
if(EXISTS "../.SC_CTEST_PREFS.cmake")
include("../.SC_CTEST_PREFS.cmake")
else()
message( WARNING "Did not find ../.SC_CTEST_PREFS.cmake, containing config variables - result submission disabled" )
set( SKIP_SUBMISSION TRUE )
message(WARNING "Did not find ../.SC_CTEST_PREFS.cmake, containing config variables - result submission disabled")
set(SKIP_SUBMISSION TRUE)
endif()
######################################################
@@ -26,8 +26,8 @@ endif()
# use config variables such as these in
# ../.SC_CTEST_PREFS.cmake
#
#set( CTEST_SITE "username")
#set( CTEST_BUILD_NAME "build type, os, arch")
#set(CTEST_SITE "username")
#set(CTEST_BUILD_NAME "build type, os, arch")
#
#
# setting any of these to true causes that set of tests
@@ -44,11 +44,11 @@ endif()
######################################################
function( SUBMIT_TEST part )
if( NOT SKIP_SUBMISSION )
ctest_submit( PARTS ${part} )
endif()
endfunction( SUBMIT_TEST part )
function(SUBMIT_TEST part)
if(NOT SKIP_SUBMISSION)
ctest_submit(PARTS ${part})
endif()
endfunction(SUBMIT_TEST part)
######################################################
##### To disable reporting of a set of tests, comment
@@ -56,65 +56,73 @@ endfunction( SUBMIT_TEST part )
##### the set you wish to disable.
#####
##### To do this for all tests:
##### set( SKIP_SUBMISSION TRUE )
##### set(SKIP_SUBMISSION TRUE)
######################################################
ctest_start(Experimental)
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
file(WRITE "${CTEST_BINARY_DIRECTORY}/CTestCustom.cmake" "
set( CTEST_CUSTOM_ERROR_EXCEPTION \"{standard input}:[0-9][0-9]*: WARNING: \")
set(CTEST_CUSTOM_ERROR_EXCEPTION \"{standard input}:[0-9][0-9]*: WARNING: \")
")
ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND OPTIONS -DSC_ENABLE_TESTING=ON )
SUBMIT_TEST( Configure )
ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND )
SUBMIT_TEST( Build )
# ctest_memcheck( BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res )
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND OPTIONS -DSC_ENABLE_TESTING=ON)
SUBMIT_TEST(Configure)
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
SUBMIT_TEST(Build)
# ctest_memcheck(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
if(NOT SKIP_TEST_UNITARY_SCHEMAS )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "unitary_schemas" )
SUBMIT_TEST( Test )
if(NOT SKIP_TEST_UNITARY_SCHEMAS)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "unitary_schemas")
SUBMIT_TEST(Test)
endif()
if(NOT SKIP_CPP_TEST_SCHEMA_GEN )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_gen" )
SUBMIT_TEST( Test )
if(NOT SKIP_CPP_TEST_SCHEMA_BUILD )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_build" )
SUBMIT_TEST( Test )
if(NOT SKIP_CPP_TEST_SCHEMA_RW )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_rw" )
SUBMIT_TEST( Test )
endif()
if(NOT SKIP_CPP_TEST_SCHEMA_GEN)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_gen")
SUBMIT_TEST(Test)
if(NOT SKIP_CPP_TEST_SCHEMA_BUILD)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_build")
SUBMIT_TEST(Test)
if(NOT SKIP_CPP_TEST_SCHEMA_RW)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_rw")
SUBMIT_TEST(Test)
endif()
endif()
endif()
if(NOT SKIP_TEST_EXCHANGE_FILE )
if( SKIP_CPP_TEST_SCHEMA_BUILD )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE "build_cpp_sdai_AP214E3_2010" )
SUBMIT_TEST( Test )
endif()
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "exchange_file" )
SUBMIT_TEST( Test )
if(NOT SKIP_TEST_EXCHANGE_FILE)
if(SKIP_CPP_TEST_SCHEMA_BUILD)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE "build_cpp_sdai_AP214E3_2010")
SUBMIT_TEST(Test)
endif()
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "exchange_file")
SUBMIT_TEST(Test)
endif()
if(NOT SKIP_TEST_CPP_SCHEMA_SPECIFIC )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_specific" )
SUBMIT_TEST( Test )
if(NOT SKIP_TEST_CPP_SCHEMA_SPECIFIC)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_schema_specific")
SUBMIT_TEST(Test)
endif()
if(NOT SKIP_TEST_CPP_UNIT )
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_unit_....*" )
SUBMIT_TEST( Test )
if(NOT SKIP_TEST_CPP_UNIT)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
INCLUDE_LABEL "cpp_unit_....*")
SUBMIT_TEST(Test)
endif()
# ctest_coverage( )
# ctest_coverage()
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+37 -27
View File
@@ -1,45 +1,55 @@
set(SC_BASE_SOURCES
sc_memmgr.cc
sc_trace_fprintf.c
sc_getopt.cc
sc_benchmark.cc
)
sc_memmgr.cc
sc_trace_fprintf.c
sc_getopt.cc
sc_benchmark.cc
sc_mkdir.c
)
set(SC_BASE_HDRS
sc_benchmark.h
sc_memmgr.h
sc_getopt.h
sc_trace_fprintf.h
sc_stdbool.h
)
sc_benchmark.h
sc_memmgr.h
sc_getopt.h
sc_trace_fprintf.h
sc_stdbool.h
sc_mkdir.h
)
if(MINGW OR MSVC OR BORLAND)
add_definitions( -DSC_BASE_DLL_EXPORTS )
add_definitions(-DSC_BASE_DLL_EXPORTS)
endif()
if (${SC_MEMMGR_ENABLE_CHECKS})
add_definitions( -DSC_MEMMGR_ENABLE_CHECKS )
add_definitions(-DSC_MEMMGR_ENABLE_CHECKS)
endif()
SC_ADDLIB(base "${SC_BASE_SOURCES}" "")
if(MINGW OR MSVC OR BORLAND)
target_link_libraries(base psapi.lib)
target_link_libraries(base psapi.lib)
endif()
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src" )
message( "Judy array source code not found. Downloading (don't sweat, it's public domain)..." )
file( DOWNLOAD "http://github.com/mpictor/judy-template/archive/master.tar.gz"
"${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz" SHOW_PROGRESS )
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
)
file( RENAME judy-template-master judy )
file( REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz" )
message( "Judy array source code extracted." )
endif(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src" )
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src")
message("Judy array source code not found. Downloading (don't sweat, it's public domain)...")
file(DOWNLOAD "http://github.com/mpictor/judy-template/archive/master.tar.gz"
"${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz" SHOW_PROGRESS)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
)
file(RENAME judy-template-master judy)
file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz")
message("Judy array source code extracted.")
endif(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src")
install(FILES ${SC_BASE_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/base)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/base)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+42 -34
View File
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8)
project( JudyTemplates )
if( NOT DEFINED CMAKE_BUILD_TYPE )
# set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) #optimize, but include debug info
set( CMAKE_BUILD_TYPE "Release" )
# set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) #optimize, but include debug info
set( CMAKE_BUILD_TYPE "Release" )
endif( NOT DEFINED CMAKE_BUILD_TYPE )
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
@@ -12,29 +12,29 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
if( NOT DEFINED JUDY_OPTIMIZE_FLAGS )
if( CMAKE_COMPILER_IS_GNUCC )
set( JUDY_OPTIMIZE_FLAGS "-march=native" )
if( CMAKE_COMPILER_IS_GNUCC )
set( JUDY_OPTIMIZE_FLAGS "-march=native" )
#test for LTO; this uses an internal variable so it may break
if( DEFINED CMAKE_C_COMPILER_VERSION )
if( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 )
set( JUDY_OPTIMIZE_FLAGS "${JUDY_OPTIMIZE_FLAGS} -flto" )
message( " -- GCC version: ${CMAKE_C_COMPILER_VERSION}. Enabling link-time optimization." )
endif( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 )
endif( DEFINED CMAKE_C_COMPILER_VERSION )
#test for LTO; this uses an internal variable so it may break
if( DEFINED CMAKE_C_COMPILER_VERSION )
if( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 )
set( JUDY_OPTIMIZE_FLAGS "${JUDY_OPTIMIZE_FLAGS} -flto" )
message( " -- GCC version: ${CMAKE_C_COMPILER_VERSION}. Enabling link-time optimization." )
endif( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 )
endif( DEFINED CMAKE_C_COMPILER_VERSION )
#elseif( MSVC )
# set( JUDY_OPTIMIZE_FLAGS "..." ) # <--- set MSVC flags here <---
else()
message( "Unrecognized compiler - no optimization flags set. Edit CMakeLists.txt or set JUDY_OPTIMIZE_FLAGS." )
set( JUDY_OPTIMIZE_FLAGS "" )
endif( CMAKE_COMPILER_IS_GNUCC )
else()
message( "Unrecognized compiler - no optimization flags set. Edit CMakeLists.txt or set JUDY_OPTIMIZE_FLAGS." )
set( JUDY_OPTIMIZE_FLAGS "" )
endif( CMAKE_COMPILER_IS_GNUCC )
endif( NOT DEFINED JUDY_OPTIMIZE_FLAGS )
add_definitions( ${JUDY_OPTIMIZE_FLAGS} )
set( JUDYS_SOURCES src/judy.c src/judy.h )
if( CMAKE_COMPILER_IS_GNUCC )
add_definitions( -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long )
add_definitions( -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long )
endif( CMAKE_COMPILER_IS_GNUCC )
add_library( judy_lib STATIC ${JUDYS_SOURCES} )
@@ -42,29 +42,37 @@ add_library( judy_lib STATIC ${JUDYS_SOURCES} )
include_directories( src )
if( ENABLE_TESTING )
include( CTest )
include_directories( test )
enable_testing()
include( CTest )
include_directories( test )
enable_testing()
add_executable( pennysort test/pennySort.c test/sort.c ${JUDYS_SOURCES} )
add_executable( hexsort test/hexSort.c test/sort.c ${JUDYS_SOURCES} )
set_target_properties( pennysort hexsort PROPERTIES COMPILE_FLAGS "-DSTANDALONE" )
add_executable( pennysort test/pennySort.c test/sort.c ${JUDYS_SOURCES} )
add_executable( hexsort test/hexSort.c test/sort.c ${JUDYS_SOURCES} )
set_target_properties( pennysort hexsort PROPERTIES COMPILE_FLAGS "-DSTANDALONE" )
add_executable( judyLtest test/judyLtest.cc )
target_link_libraries( judyLtest judy_lib )
add_test( judyLtest judyLtest )
add_executable( judyLtest test/judyLtest.cc )
target_link_libraries( judyLtest judy_lib )
add_test( judyLtest judyLtest )
add_executable( judyL2test test/judyL2test.cc )
target_link_libraries( judyL2test judy_lib )
add_test( judyL2test judyL2test )
add_executable( judyL2test test/judyL2test.cc )
target_link_libraries( judyL2test judy_lib )
add_test( judyL2test judyL2test )
add_executable( judyStest test/judyStest.cc )
target_link_libraries( judyStest judy_lib )
add_test( judyStest judyStest )
add_executable( judyStest test/judyStest.cc )
target_link_libraries( judyStest judy_lib )
add_test( judyStest judyStest )
add_executable( judyS2test test/judyS2test.cc )
target_link_libraries( judyS2test judy_lib )
add_test( judyS2test judyS2test )
add_executable( judyS2test test/judyS2test.cc )
target_link_libraries( judyS2test judy_lib )
add_test( judyS2test judyS2test )
endif( ENABLE_TESTING )
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+1
View File
@@ -18,6 +18,7 @@
#include <iomanip>
#include <string>
#include <sstream>
#include <ios>
/// mem values in kb, times in ms (granularity may be higher than 1ms)
benchVals getMemAndTime( ) {
-5
View File
@@ -38,11 +38,6 @@ extern "C" {
* depends on getMemAndTime() above - may not work on all platforms.
*/
#ifdef _WIN32
template class SC_BASE_EXPORT std::allocator<char>;
template class SC_BASE_EXPORT std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
#endif
class SC_BASE_EXPORT benchmark {
protected:
benchVals initialVals, laterVals;
+32
View File
@@ -0,0 +1,32 @@
#include "sc_mkdir.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#ifdef _WIN32
# include <direct.h>
#endif /* _WIN32 */
/* cross-platform mkdir */
int sc_mkdir( const char * path ) {
#ifdef _WIN32
return mkdir( path );
#else
return mkdir( path, 0777 );
#endif /* _WIN32 */
}
/* return -1 if error, 0 if created, 1 if dir existed already */
int mkDirIfNone( const char * path ) {
struct stat s;
if( stat( path, &s ) != 0 ) {
if( errno == ENOENT ) {
return sc_mkdir( path );
}
} else if( s.st_mode & S_IFDIR ) {
return 1;
}
/* either stat returned an error other than ENOENT, or 'path' exists but isn't a dir */
return -1;
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef SC_MKDIR
#define SC_MKDIR
#include <sc_export.h>
/** cross-platform mkdir() */
SC_BASE_EXPORT int sc_mkdir( const char * path );
/** create a dir 'path' if 'path' doesn't exist
* \return -1 if error, 0 if created, 1 if dir existed already
* if it returns -1, check errno
*/
SC_BASE_EXPORT int mkDirIfNone( const char * path );
#endif /* SC_MKDIR */
+11
View File
@@ -0,0 +1,11 @@
#ifndef SC_STRTOULL_H
#define SC_STRTOULL_H
#include <limits.h>
#ifdef _WIN32
# define strtoull _strtoui64
# define ULLONG_MAX _UI64_MAX
#endif
#endif /* SC_STRTOULL_H */
+44 -30
View File
@@ -1,40 +1,54 @@
set(LIBSTEPDAI_SRCS
sdaiApplication_instance_set.cc
sdaiBinary.cc
sdaiDaObject.cc
sdaiEntity_extent.cc
sdaiEntity_extent_set.cc
sdaiEnum.cc
sdaiModel_contents.cc
sdaiModel_contents_list.cc
sdaiObject.cc
sdaiSession_instance.cc
sdaiString.cc
)
sdaiApplication_instance_set.cc
sdaiBinary.cc
sdaiDaObject.cc
sdaiEntity_extent.cc
sdaiEntity_extent_set.cc
sdaiEnum.cc
sdaiModel_contents.cc
sdaiModel_contents_list.cc
sdaiObject.cc
sdaiSession_instance.cc
sdaiSet.cc
sdaiString.cc
)
SET(SC_CLDAI_HDRS
sdaiApplication_instance_set.h
sdaiBinary.h
sdaiDaObject.h
sdaiEntity_extent.h
sdaiEntity_extent_set.h
sdaiEnum.h
sdaiModel_contents.h
sdaiModel_contents_list.h
sdaiObject.h
sdaiSession_instance.h
sdaiString.h
)
sdaiApplication_instance_set.h
sdaiBinary.h
sdaiDaObject.h
sdaiEntity_extent.h
sdaiEntity_extent_set.h
sdaiEnum.h
sdaiModel_contents.h
sdaiModel_contents_list.h
sdaiObject.h
sdaiSession_instance.h
sdaiSet.h
sdaiString.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/clstepcore
${SC_SOURCE_DIR}/src/clutils
)
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/clstepcore
${SC_SOURCE_DIR}/src/clutils
)
SC_ADDLIB(stepdai "${LIBSTEPDAI_SRCS}" "steputils;base")
if(HAVE_STD_THREAD)
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
set_target_properties(stepdai PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
endif(HAVE_STD_THREAD)
install(FILES ${SC_CLDAI_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cldai)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cldai)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+2 -88
View File
@@ -41,99 +41,13 @@ extern "C"
/*****************************************************************************/
SDAI_Application_instance__set::SDAI_Application_instance__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new SDAI_Application_instance_ptr[_bufsize];
_count = 0;
SDAI_Application_instance__set::SDAI_Application_instance__set( int defaultSize ) : SDAI__set( defaultSize ) {
}
SDAI_Application_instance__set::~SDAI_Application_instance__set() {
delete _buf;
}
void SDAI_Application_instance__set::Check( int index ) {
SDAI_Application_instance_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new SDAI_Application_instance_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( SDAI_Application_instance_ptr ) );
delete _buf;
_buf = newbuf;
}
}
void SDAI_Application_instance__set::Insert( SDAI_Application_instance_ptr v, int index ) {
SDAI_Application_instance_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Application_instance_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_Application_instance__set::Append( SDAI_Application_instance_ptr v ) {
int index = _count;
SDAI_Application_instance_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Application_instance_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_Application_instance__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
SDAI_Application_instance_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_Application_instance_ptr ) );
}
}
void SDAI_Application_instance__set::Remove( SDAI_Application_instance_ptr a ) {
int index = Index( a );
if( !( index < 0 ) ) {
Remove( index );
}
}
int SDAI_Application_instance__set::Index( SDAI_Application_instance_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
SDAI_Application_instance_ptr & SDAI_Application_instance__set::operator[]( int index ) {
Check( index );
// _count = max(_count, index+1);
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
return ( SDAI_Application_instance_ptr & )SDAI__set::operator[]( index );
}
int
SDAI_Application_instance__set::Count() {
return _count;
}
void
SDAI_Application_instance__set::Clear() {
_count = 0;
}
+1 -15
View File
@@ -37,26 +37,12 @@ class SDAI_Application_instance__set;
typedef SDAI_Application_instance__set * SDAI_Application_instance__set_ptr;
typedef SDAI_Application_instance__set_ptr SDAI_Application_instance__set_var;
class SC_DAI_EXPORT SDAI_Application_instance__set {
class SC_DAI_EXPORT SDAI_Application_instance__set : public SDAI__set {
public:
SDAI_Application_instance__set( int = 16 );
~SDAI_Application_instance__set();
SDAI_Application_instance *& operator[]( int index );
void Insert( SDAI_Application_instance *, int index );
void Append( SDAI_Application_instance * );
void Remove( int index );
void Remove( SDAI_Application_instance * );
int Index( SDAI_Application_instance * );
int Count();
void Clear();
private:
void Check( int index );
private:
SDAI_Application_instance ** _buf;
int _bufsize;
int _count;
};
#endif
+2 -94
View File
@@ -78,83 +78,10 @@ SDAI_DAObject_SDAI::~SDAI_DAObject_SDAI() {
/*****************************************************************************/
SDAI_DAObject__set::SDAI_DAObject__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new SDAI_DAObject_ptr[_bufsize];
_count = 0;
SDAI_DAObject__set::SDAI_DAObject__set( int defaultSize ) : SDAI__set( defaultSize ){
}
SDAI_DAObject__set::~SDAI_DAObject__set() {
delete _buf;
}
void SDAI_DAObject__set::Check( int index ) {
SDAI_DAObject_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new SDAI_DAObject_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( SDAI_DAObject_ptr ) );
delete _buf;
_buf = newbuf;
}
}
void
SDAI_DAObject__set::Insert( SDAI_DAObject_ptr v, int index ) {
SDAI_DAObject_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_DAObject_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_DAObject__set::Append( SDAI_DAObject_ptr v ) {
int index = _count;
SDAI_DAObject_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_DAObject_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_DAObject__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
SDAI_DAObject_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_DAObject_ptr ) );
}
}
int SDAI_DAObject__set::Index( SDAI_DAObject_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
SDAI_DAObject_ptr
@@ -163,24 +90,5 @@ SDAI_DAObject__set::retrieve( int index ) {
}
SDAI_DAObject_ptr & SDAI_DAObject__set::operator[]( int index ) {
Check( index );
// _count = max(_count, index+1);
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int
SDAI_DAObject__set::Count() {
return _count;
}
int
SDAI_DAObject__set::is_empty() {
return _count;
}
void
SDAI_DAObject__set::Clear() {
_count = 0;
return ( SDAI_DAObject_ptr & )SDAI__set::operator[]( index );
}
+1 -22
View File
@@ -489,34 +489,13 @@ class SC_DAI_EXPORT SDAI_DAObject_SDAI : public SDAI_DAObject {
typedef SDAI_DAObject_SDAI * SDAI_DAObject_SDAI_ptr;
typedef SDAI_DAObject_SDAI_ptr SDAI_DAObject_SDAI_var;
class SC_DAI_EXPORT SDAI_DAObject__set {
class SC_DAI_EXPORT SDAI_DAObject__set : public SDAI__set {
public:
SDAI_DAObject__set( int = 16 );
~SDAI_DAObject__set();
SDAI_DAObject_ptr retrieve( int index );
int is_empty();
SDAI_DAObject_ptr & operator[]( int index );
void Insert( SDAI_DAObject_ptr, int index );
void Append( SDAI_DAObject_ptr );
void Remove( int index );
int Index( SDAI_DAObject_ptr );
void Clear();
int Count();
private:
void Check( int index );
private:
SDAI_DAObject_ptr * _buf;
int _bufsize;
int _count;
public:
};
typedef SDAI_DAObject__set * SDAI_DAObject__set_ptr;
+1 -1
View File
@@ -114,7 +114,7 @@ SDAI_Entity_extent::AddInstance( const SDAI_DAObject_ptr & appInst ) {
void
SDAI_Entity_extent::RemoveInstance( const SDAI_DAObject_ptr & appInst ) {
_instances.Remove( _instances.Index( appInst ) );
_instances.Remove( appInst );
}
///////// END_ENTITY SDAI_Entity_extent
+2 -93
View File
@@ -44,83 +44,10 @@ extern "C"
/*****************************************************************************/
SDAI_Entity_extent__set::SDAI_Entity_extent__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new SDAI_Entity_extent_ptr[_bufsize];
_count = 0;
SDAI_Entity_extent__set::SDAI_Entity_extent__set( int defaultSize ) : SDAI__set( defaultSize ) {
}
SDAI_Entity_extent__set::~SDAI_Entity_extent__set() {
delete _buf;
}
void SDAI_Entity_extent__set::Check( int index ) {
SDAI_Entity_extent_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new SDAI_Entity_extent_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( SDAI_Entity_extent_ptr ) );
delete _buf;
_buf = newbuf;
}
}
void
SDAI_Entity_extent__set::Insert( SDAI_Entity_extent_ptr v, int index ) {
SDAI_Entity_extent_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Entity_extent_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_Entity_extent__set::Append( SDAI_Entity_extent_ptr v ) {
int index = _count;
SDAI_Entity_extent_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Entity_extent_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_Entity_extent__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
SDAI_Entity_extent_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_Entity_extent_ptr ) );
}
}
int SDAI_Entity_extent__set::Index( SDAI_Entity_extent_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
SDAI_Entity_extent_ptr
@@ -129,25 +56,7 @@ SDAI_Entity_extent__set::retrieve( int index ) {
}
SDAI_Entity_extent_ptr & SDAI_Entity_extent__set::operator[]( int index ) {
Check( index );
// _count = max(_count, index+1);
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int
SDAI_Entity_extent__set::Count() {
return _count;
}
int
SDAI_Entity_extent__set::is_empty() {
return _count;
}
void
SDAI_Entity_extent__set::Clear() {
_count = 0;
return ( SDAI_Entity_extent_ptr & )SDAI__set::operator[]( index );
}
/*****************************************************************************/
+1 -19
View File
@@ -37,32 +37,14 @@
//#include <EntityExtent.h>
*/
class SC_DAI_EXPORT SDAI_Entity_extent__set {
class SC_DAI_EXPORT SDAI_Entity_extent__set : public SDAI__set {
public:
SDAI_Entity_extent__set( int = 16 );
~SDAI_Entity_extent__set();
SDAI_Entity_extent_ptr retrieve( int index );
int is_empty();
SDAI_Entity_extent_ptr & operator[]( int index );
void Insert( SDAI_Entity_extent_ptr, int index );
void Append( SDAI_Entity_extent_ptr );
void Remove( int index );
int Index( SDAI_Entity_extent_ptr );
void Clear();
int Count();
private:
void Check( int index );
private:
SDAI_Entity_extent_ptr * _buf;
int _bufsize;
int _count;
};
typedef SDAI_Entity_extent__set * SDAI_Entity_extent__set_ptr;
+1 -1
View File
@@ -73,7 +73,7 @@ void SDAI_Model_contents::AddInstance( const SDAI_DAObject_SDAI_ptr & appInst )
}
void SDAI_Model_contents::RemoveInstance( SDAI_DAObject_SDAI_ptr & appInst ) {
_instances.contents_()->Remove( _instances.contents_()->Index( appInst ) );
_instances.contents_()->Remove( appInst );
}
+2 -94
View File
@@ -36,83 +36,10 @@ extern "C"
/*****************************************************************************/
SDAI_Model_contents__list::SDAI_Model_contents__list( int defaultSize ) {
_bufsize = defaultSize;
_buf = new SDAI_Model_contents_ptr[_bufsize];
_count = 0;
SDAI_Model_contents__list::SDAI_Model_contents__list( int defaultSize ) : SDAI__set( defaultSize ){
}
SDAI_Model_contents__list::~SDAI_Model_contents__list() {
delete _buf;
}
void SDAI_Model_contents__list::Check( int index ) {
SDAI_Model_contents_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new SDAI_Model_contents_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( SDAI_Model_contents_ptr ) );
delete _buf;
_buf = newbuf;
}
}
void
SDAI_Model_contents__list::Insert( SDAI_Model_contents_ptr v, int index ) {
SDAI_Model_contents_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Model_contents_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_Model_contents__list::Append( SDAI_Model_contents_ptr v ) {
int index = _count;
SDAI_Model_contents_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Model_contents_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void SDAI_Model_contents__list::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
SDAI_Model_contents_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_Model_contents_ptr ) );
}
}
int SDAI_Model_contents__list::Index( SDAI_Model_contents_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
SDAI_Model_contents_ptr
@@ -122,25 +49,6 @@ SDAI_Model_contents__list::retrieve( int index ) {
SDAI_Model_contents_ptr &
SDAI_Model_contents__list::operator[]( int index ) {
Check( index );
// _count = max(_count, index+1);
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int
SDAI_Model_contents__list::Count() {
return _count;
}
int
SDAI_Model_contents__list::is_empty() {
return _count;
}
void
SDAI_Model_contents__list::Clear() {
_count = 0;
return ( SDAI_Model_contents_ptr & )SDAI__set::operator[]( index );
}
+1 -18
View File
@@ -3,30 +3,13 @@
#include <sc_export.h>
class SC_DAI_EXPORT SDAI_Model_contents__list {
class SC_DAI_EXPORT SDAI_Model_contents__list : public SDAI__set {
public:
SDAI_Model_contents__list( int = 16 );
~SDAI_Model_contents__list();
SDAI_Model_contents_ptr retrieve( int index );
int is_empty();
SDAI_Model_contents_ptr & operator[]( int index );
void Insert( SDAI_Model_contents_ptr, int index );
void Append( SDAI_Model_contents_ptr );
void Remove( int index );
int Index( SDAI_Model_contents_ptr );
void Clear();
int Count();
private:
void Check( int index );
private:
SDAI_Model_contents_ptr * _buf;
int _bufsize;
int _count;
};
typedef SDAI_Model_contents__list *
+153
View File
@@ -0,0 +1,153 @@
#include <memory.h>
#include <math.h>
#include <sdai.h>
#include "sc_memmgr.h"
#ifndef HAVE_MEMMOVE
extern "C"
{
void * memmove( void * __s1, const void * __s2, size_t __n );
}
#endif
/*****************************************************************************/
SDAI__set::SDAI__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new SDAI_ptr[_bufsize];
_count = 0;
mtxP = new sc_mutex();
}
SDAI__set::~SDAI__set() {
delete _buf;
delete mtxP;
}
void SDAI__set::Check( int index ) {
// No locking as it is a private function.
// i.e. The caller will have to take the responsibilty.
SDAI_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new SDAI_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( SDAI_ptr ) );
delete _buf;
_buf = newbuf;
}
}
void
SDAI__set::Insert( SDAI_ptr v, int index ) {
mtxP->lock();
SDAI_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
mtxP->unlock();
}
void SDAI__set::Append( SDAI_ptr v ) {
mtxP->lock();
int index = _count;
SDAI_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
mtxP->unlock();
}
void SDAI__set::Remove( int index ) {
mtxP->lock();
if( 0 <= index && index < _count ) {
--_count;
SDAI_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_ptr ) );
}
mtxP->unlock();
}
// First find the index of v and then remove v.
void SDAI__set::Remove( SDAI_ptr v ) {
mtxP->lock();
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
--_count;
SDAI_ptr * spot = &_buf[i];
memmove( spot, spot + 1, ( _count - i )*sizeof( SDAI_ptr ) );
}
}
mtxP->unlock();
}
int SDAI__set::Index( SDAI_ptr v ) {
mtxP->lock();
int index = -1;
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
index = i;
break;
}
}
mtxP->unlock();
return index;
}
SDAI_ptr
SDAI__set::retrieve( int index ) {
return operator[]( index );
}
SDAI_ptr & SDAI__set::operator[]( int index ) {
mtxP->lock();
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
SDAI_ptr & sp = _buf[index];
mtxP->unlock();
return sp;
}
int
SDAI__set::Count() {
return _count;
}
int
SDAI__set::is_empty() {
return _count;
}
void
SDAI__set::Clear() {
mtxP->lock();
_count = 0;
mtxP->unlock();
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef SDAISET_H
#define SDAISET_H 1
#include <sc_mutex.h>
#include <sc_export.h>
typedef void * SDAI_ptr;
class SC_DAI_EXPORT SDAI__set {
public:
SDAI__set( int = 16 );
~SDAI__set();
SDAI_ptr retrieve( int index );
int is_empty();
SDAI_ptr & operator[]( int index );
void Insert( SDAI_ptr, int index );
void Append( SDAI_ptr );
void Remove( int index );
void Remove( SDAI_ptr );
int Index( SDAI_ptr );
void Clear();
int Count();
private:
void Check( int index );
private:
SDAI_ptr * _buf;
int _bufsize;
int _count;
sc_mutex * mtxP;
// The above function is declared as a pointer to prevent
// 'use of deleted function' compilation error as the
// assignment operator '=' is being in the function
// 'SDAI_Entity_extent::owned_by_' for a subclass of
// SDAI__set: 'SDAI_Model_contents__list'
public:
};
#endif
+35 -23
View File
@@ -1,33 +1,45 @@
set(LIBSTEPEDITOR_SRCS
STEPfile.cc
STEPfile.inline.cc
cmdmgr.cc
SdaiHeaderSchema.cc
SdaiHeaderSchemaAll.cc
SdaiHeaderSchemaInit.cc
SdaiSchemaInit.cc
)
STEPfile.cc
STEPfile.inline.cc
cmdmgr.cc
SdaiHeaderSchema.cc
SdaiHeaderSchemaAll.cc
SdaiHeaderSchemaInit.cc
SdaiSchemaInit.cc
)
SET(SC_CLEDITOR_HDRS
STEPfile.h
cmdmgr.h
editordefines.h
SdaiHeaderSchema.h
SdaiHeaderSchemaClasses.h
SdaiSchemaInit.h
seeinfodefault.h
)
STEPfile.h
cmdmgr.h
editordefines.h
SdaiHeaderSchema.h
SdaiHeaderSchemaClasses.h
SdaiSchemaInit.h
seeinfodefault.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/cldai
${SC_SOURCE_DIR}/src/clstepcore
${SC_SOURCE_DIR}/src/clutils
)
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/cldai
${SC_SOURCE_DIR}/src/clstepcore
${SC_SOURCE_DIR}/src/clutils
)
SC_ADDLIB(stepeditor "${LIBSTEPEDITOR_SRCS}" "stepcore;stepdai;steputils;base")
if(HAVE_STD_THREAD)
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
set_target_properties(stepeditor PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
endif(HAVE_STD_THREAD)
install(FILES ${SC_CLEDITOR_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cleditor)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cleditor)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+44 -45
View File
@@ -149,7 +149,7 @@ Severity STEPfile::ReadHeader( istream & in ) {
}
//get the entity keyword
keywd = GetKeyword( in, ";( /\\", _error );
FillKeyword( in, ";( /\\", _error, keywd );
ReadTokenSeparator( in, &cmtStr );
//check for "ENDSEC"
@@ -367,9 +367,9 @@ void STEPfile::HeaderMergeInstances( InstMgr * im ) {
//checking for _headerInstances::FILE_NAME
idnum = HeaderId( "File_Name" );
se = _headerInstances->GetApplication_instance( _headerInstances->FindFileId( idnum ) );
se = _headerInstances->GetApplication_instanceFromFileId( idnum );
if( se ) {
from = im->GetApplication_instance( im->FindFileId( idnum ) );
from = im->GetApplication_instanceFromFileId( idnum );
// name:
// time_stamp: keep the newer time_stamp
@@ -379,33 +379,33 @@ void STEPfile::HeaderMergeInstances( InstMgr * im ) {
// originating_system:
// authorization:
} else { // No current File_Name instance
from = im->GetApplication_instance( im->FindFileId( idnum ) );
from = im->GetApplication_instanceFromFileId( idnum );
_headerInstances->Append( from, completeSE );
}
//checking for _headerInstances::FILE_DESCRIPTION
idnum = HeaderId( "File_Description" );
se = _headerInstances->GetApplication_instance( _headerInstances->FindFileId( idnum ) );
se = _headerInstances->GetApplication_instanceFromFileId( idnum );
if( se ) {
from = im->GetApplication_instance( im->FindFileId( idnum ) );
from = im->GetApplication_instanceFromFileId( idnum );
//description
//implementation_level
} else {
from = im->GetApplication_instance( im->FindFileId( idnum ) );
from = im->GetApplication_instanceFromFileId( idnum );
_headerInstances->Append( from, completeSE );
}
//checking for _headerInstances::FILE_SCHEMA
idnum = HeaderId( "File_Schema" );
se = _headerInstances->GetApplication_instance( _headerInstances->FindFileId( idnum ) );
se = _headerInstances->GetApplication_instanceFromFileId( idnum );
if( se ) {
from = im->GetApplication_instance( im->FindFileId( idnum ) );
from = im->GetApplication_instanceFromFileId( idnum );
//description
//implementation_level
} else {
from = im->GetApplication_instance( im->FindFileId( idnum ) );
from = im->GetApplication_instanceFromFileId( idnum );
_headerInstances->Append( from, completeSE );
}
@@ -913,7 +913,7 @@ Severity STEPfile::CreateScopeInstances( istream & in, SDAI_Application_instance
std::vector< SDAI_Application_instance_ptr > inscope;
std::string keywd;
keywd = GetKeyword( in, " \n\t/\\#;", _error );
FillKeyword( in, " \n\t/\\#;", _error, keywd );
if( strncmp( const_cast<char *>( keywd.c_str() ), "&SCOPE", 6 ) ) {
//ERROR: "&SCOPE" expected
//TODO: should attempt to recover by reading through ENDSCOPE
@@ -955,7 +955,7 @@ Severity STEPfile::CreateScopeInstances( istream & in, SDAI_Application_instance
}
//check for "ENDSCOPE"
keywd = GetKeyword( in, " \t\n/\\#;", _error );
FillKeyword( in, " \t\n/\\#;", _error, keywd );
if( strncmp( const_cast<char *>( keywd.c_str() ), "ENDSCOPE", 8 ) ) {
//ERROR: "ENDSCOPE" expected
SkipInstance( in, tmpbuf );
@@ -1071,7 +1071,7 @@ Severity STEPfile::ReadScopeInstances( istream & in ) {
std::string keywd;
std::string cmtStr;
keywd = GetKeyword( in, " \n\t/\\#;", _error );
FillKeyword( in, " \n\t/\\#;", _error, keywd );
if( strncmp( const_cast<char *>( keywd.c_str() ), "&SCOPE", 6 ) ) {
//ERROR: "&SCOPE" expected
SkipInstance( in, tmpbuf );
@@ -1099,7 +1099,7 @@ Severity STEPfile::ReadScopeInstances( istream & in ) {
in.putback( c );
//check for "ENDSCOPE"
keywd = GetKeyword( in, " \t\n/\\#;", _error );
FillKeyword( in, " \t\n/\\#;", _error, keywd );
if( strncmp( const_cast<char *>( keywd.c_str() ), "ENDSCOPE", 8 ) ) {
//ERROR: "ENDSCOPE" expected
SkipInstance( in, tmpbuf );
@@ -1480,7 +1480,11 @@ int STEPfile::HeaderId( const char * name ) {
if( tmp == "FILE_SCHEMA" ) {
return 3;
}
return ++_headerId;
_headerIdMtx.lock();
int myHeaderId = ++_headerId;
_headerIdMtx.unlock();
return myHeaderId;
}
/***************************
@@ -1494,6 +1498,7 @@ void STEPfile::WriteHeader( ostream & out ) {
// Write the rest of the header instances
SDAI_Application_instance * se;
_headerInstances->masterMtx.lock();
int n = _headerInstances->InstanceCount();
for( int i = 0; i < n; ++i ) {
se = _headerInstances->GetMgrNode( i ) ->GetApplication_instance();
@@ -1505,6 +1510,7 @@ void STEPfile::WriteHeader( ostream & out ) {
WriteHeaderInstance(
_headerInstances->GetMgrNode( i )->GetApplication_instance(), out );
}
_headerInstances->masterMtx.unlock();
out << "ENDSEC;\n";
}
@@ -1516,6 +1522,8 @@ void STEPfile::WriteHeaderInstance( SDAI_Application_instance * obj, ostream & o
out << obj->P21Comment();
}
out << StrToUpper( obj->EntityName(), tmp ) << "(";
obj->mtx.lock();
obj->attributes.mtxP->lock();
int n = obj->attributes.list_length();
for( int i = 0; i < n; ++i ) {
( obj->attributes[i] ).STEPwrite( out );
@@ -1523,6 +1531,8 @@ void STEPfile::WriteHeaderInstance( SDAI_Application_instance * obj, ostream & o
out << ",";
}
}
obj->attributes.mtxP->unlock();
obj->mtx.unlock();
out << ");\n";
}
@@ -1584,21 +1594,25 @@ void STEPfile::WriteData( ostream & out, int writeComments ) {
std::string currSch = schemaName();
out << "DATA;\n";
instances().masterMtx.lock();
int n = instances().InstanceCount();
for( int i = 0; i < n; ++i ) {
instances().GetMgrNode( i )->GetApplication_instance()->STEPwrite( out, currSch.c_str(), writeComments );
_oFileInstsWritten++;
}
instances().masterMtx.unlock();
out << "ENDSEC;\n";
}
void STEPfile::WriteValuePairsData( ostream & out, int writeComments, int mixedCase ) {
std::string currSch = schemaName();
instances().masterMtx.lock();
int n = instances().InstanceCount();
for( int i = 0; i < n; ++i ) {
instances().GetMgrNode( i )->GetApplication_instance()->WriteValuePairs( out, currSch.c_str(), writeComments, mixedCase );
}
instances().masterMtx.unlock();
}
Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
@@ -1609,7 +1623,8 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
int total_insts = 0, valid_insts = 0;
ReadTokenSeparator( *in );
std::string keywd = GetKeyword( *in, "; #", _error );
std::string keywd;
FillKeyword( *in, "; #", _error, keywd );
// get the delimiter off the istream
char c;
in->get( c );
@@ -1672,26 +1687,11 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
cout << errbuf;
// PASS 2
// This would be nicer if you didn't actually have to close the
// file but could just reposition the pointer back to the
// beginning of the data section. It looks like you can do this
// with the GNU File class, but that class doesn't have the
// operator >> overloaded which is used to do the rest of the
// parsing. SO we are using istreams and this works, but could
// be better.
// reset the error count so you're not counting things twice:
_errorCount = 0;
istream * in2;
if( !( ( in2 = OpenInputFile() ) && ( in2 -> good() ) ) ) {
// if the stream is not readable, there's an error
_error.AppendToUserMsg( "Cannot open file for 2nd pass -- No data read.\n" );
CloseInputFile( in2 );
return SEVERITY_INPUT_ERROR;
}
if( !FindDataSection( *in2 ) ) {
in->seekg( 0, std::ifstream::beg );
if( !FindDataSection( *in ) ) {
_error.AppendToUserMsg( "Error: Unable to find DATA section delimiter in second pass. \nData section not read. Rest of file ignored.\n" );
CloseInputFile( in2 );
return SEVERITY_INPUT_ERROR;
}
@@ -1699,21 +1699,19 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
case VERSION_CURRENT:
case VERSION_UNKNOWN:
case WORKING_SESSION:
valid_insts = ReadData2( *in2, useTechCor );
valid_insts = ReadData2( *in, useTechCor );
break;
default:
_error.AppendToUserMsg( "STEPfile::AppendFile: STEP file version set to unrecognized value.\n" );
CloseInputFile( in2 );
return SEVERITY_BUG;
}
//check for "ENDSEC;"
ReadTokenSeparator( *in2 );
ReadTokenSeparator( *in );
if( total_insts != valid_insts ) {
sprintf( errbuf, "%d invalid instances in file: %s\n",
total_insts - valid_insts, ( ( FileName().compare( "-" ) == 0 ) ? "standard input" : FileName().c_str() ) );
_error.AppendToUserMsg( errbuf );
CloseInputFile( in2 );
return _error.GreaterSeverity( SEVERITY_WARNING );
}
@@ -1728,25 +1726,23 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
//check for "ENDSTEP;" || "END-ISO-10303-21;"
if( in2 -> good() ) {
ReadTokenSeparator( *in2 );
keywd = GetKeyword( *in2, ";", _error );
if( in -> good() ) {
ReadTokenSeparator( *in );
FillKeyword( *in, ";", _error, keywd );
//yank the ";" from the istream
//if (';' == in2->peek()) in2->get();
//if (';' == in->peek()) in->get();
char ch;
in2->get( ch );
in->get( ch );
if( ch != ';' ) {
std::cerr << __FILE__ << ":" << __LINE__ << " - Expected ';' at Part 21 EOF, found '" << c << "'." << std::endl;
}
}
if( ( !keywd.compare( 0, keywd.size(), END_FILE_DELIM ) ) || !( in2 -> good() ) ) {
if( ( !keywd.compare( 0, keywd.size(), END_FILE_DELIM ) ) || !( in -> good() ) ) {
_error.AppendToUserMsg( END_FILE_DELIM );
_error.AppendToUserMsg( " missing at end of file.\n" );
CloseInputFile( in2 );
return _error.GreaterSeverity( SEVERITY_WARNING );
}
CloseInputFile( in2 );
cout << "Finished reading file.\n\n";
return SEVERITY_NULL;
}
@@ -1790,6 +1786,8 @@ Severity STEPfile::WriteWorkingFile( const std::string filename, int clearError,
void STEPfile::WriteWorkingData( ostream & out, int writeComments ) {
std::string currSch = schemaName();
out << "DATA;\n";
instances().masterMtx.lock();
int n = instances().InstanceCount();
for( int i = 0; i < n; ++i ) {
@@ -1819,6 +1817,7 @@ void STEPfile::WriteWorkingData( ostream & out, int writeComments ) {
break;
}
}
instances().masterMtx.unlock();
out << "ENDSEC;\n";
}
+7
View File
@@ -23,6 +23,7 @@
#include <time.h>
#include <read_func.h>
#include <sc_mutex.h>
//error reporting level
#define READ_COMPLETE 10
@@ -36,6 +37,11 @@ enum FileTypeCode {
};
class SC_EDITOR_EXPORT STEPfile {
/// hoiji09: As this class is a parser, the locking in this class is dependent upon how it is
/// being used in a multithreaded way. Example: The variable llke _fileName restricts
/// this class to parse only one file at a time. If we want to parse more then one
/// then this will have to change.
protected:
//data members
@@ -55,6 +61,7 @@ class SC_EDITOR_EXPORT STEPfile {
Registry * _headerRegistry;
int _headerId; ///< STEPfile_id given to SDAI_Application_instance from header section
sc_mutex _headerIdMtx; ///< Protects the _headerId
//file information
DirObj * _currentDir;
+4
View File
@@ -113,7 +113,9 @@ Severity STEPfile::ReadExchangeFile( const std::string filename, bool useTechCor
if( _headerInstances ) {
_headerInstances->ClearInstances();
}
_headerIdMtx.lock();
_headerId = 5;
_headerIdMtx.unlock();
Severity rval = AppendFile( in, useTechCor );
CloseInputFile( in );
return rval;
@@ -262,11 +264,13 @@ int STEPfile::IncrementFileId( int fileid ) {
void STEPfile::SetFileIdIncrement() {
instances().masterMtx.lock();
if( instances().MaxFileId() < 0 ) {
_fileIdIncr = 0;
} else {
_fileIdIncr = ( int )( ( ceil( ( instances().MaxFileId() + 99.0 ) / 1000.0 ) + 1.0 ) * 1000.0 );
}
instances().masterMtx.unlock();
}
/**
+16 -8
View File
@@ -14,15 +14,19 @@
#include "sc_memmgr.h"
ReplicateLinkNode * ReplicateList::FindNode( MgrNode * mn ) {
mtxP->lock(); //mtxP belongs to the superclass SingleLinkList
ReplicateLinkNode * rln = ( ReplicateLinkNode * )GetHead();
ReplicateLinkNode * retrln = 0;
int numEntries = EntryCount();
while( numEntries-- ) {
if( rln->ReplicateNode() == mn ) {
return rln;
retrln = rln;
break;
}
rln = ( ReplicateLinkNode * )rln->NextNode();
}
return 0;
mtxP->unlock();
return retrln;
}
bool ReplicateList::IsOnList( MgrNode * mn ) {
@@ -33,28 +37,30 @@ bool ReplicateList::IsOnList( MgrNode * mn ) {
// returns true if it could delete the node
///////////////////////////////////////////////////////////////////////////////
bool ReplicateList::Remove( ReplicateLinkNode * rln ) {
mtxP->lock();
bool retval = false;
ReplicateLinkNode * rnFollow = ( ReplicateLinkNode * )GetHead();
if( !rnFollow || !rln ) {
return false;
} else {
if( rnFollow && rln ) {
if( rnFollow == rln ) {
head = rln->NextNode();
delete rln;
return true;
retval = true;
} else {
ReplicateLinkNode * rn = ( ReplicateLinkNode * )rnFollow->NextNode();
while( rn ) {
if( rn == rln ) {
rnFollow->next = ( SingleLinkNode * )rln->NextNode();
delete rln;
return true;
retval = true;
break;
}
rnFollow = rn;
rn = ( ReplicateLinkNode * )rn->NextNode();
} // end while(rn)
} // end else
} // end else
return false;
mtxP->unlock();
return retval;
}
bool ReplicateList::Remove( MgrNode * rn ) {
@@ -73,9 +79,11 @@ CmdMgr::CmdMgr() {
}
void CmdMgr::ReplicateCmdList( MgrNode * mn ) {
replicateList->mtxP->lock(); // To prevent double appending of mn
if( !( replicateList->IsOnList( mn ) ) ) {
replicateList->AddNode( mn );
}
replicateList->mtxP->unlock();
}
void CmdMgr::ClearInstances() {
+56 -30
View File
@@ -1,41 +1,67 @@
set( clLazyFile_SRCS
lazyDataSectionReader.cc
lazyFileReader.cc
lazyInstMgr.cc
p21HeaderSectionReader.cc
sectionReader.cc
lazyP21DataSectionReader.cc
../base/judy/src/judy.c
../base/judy/src/judyLArray.h
../base/judy/src/judySArray.h
)
lazyDataSectionReader.cc
lazyFileReader.cc
lazyInstMgr.cc
p21HeaderSectionReader.cc
sectionReader.cc
lazyP21DataSectionReader.cc
../base/judy/src/judy.c
../base/judy/src/judyLArray.h
../base/judy/src/judySArray.h
)
set( SC_CLLAZYFILE_HDRS
headerSectionReader.h
lazyFileReader.h
lazyP21DataSectionReader.h
p21HeaderSectionReader.h
lazyDataSectionReader.h
lazyInstMgr.h
lazyTypes.h
sectionReader.h
instMgrHelper.h
)
headerSectionReader.h
lazyFileReader.h
lazyP21DataSectionReader.h
p21HeaderSectionReader.h
lazyDataSectionReader.h
lazyInstMgr.h
lazyTypes.h
sectionReader.h
instMgrHelper.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/cleditor
${SC_SOURCE_DIR}/src/cldai
${SC_SOURCE_DIR}/src/clstepcore
${SC_SOURCE_DIR}/src/clutils
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/base/judy/src
)
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/cleditor
${SC_SOURCE_DIR}/src/cldai
${SC_SOURCE_DIR}/src/clstepcore
${SC_SOURCE_DIR}/src/clutils
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/base/judy/src
)
SC_ADDLIB(steplazyfile "${clLazyFile_SRCS};${clLazyFile_HDRS}" "stepcore;stepdai;steputils;base;")
if(HAVE_STD_THREAD)
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
set_target_properties(steplazyfile PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
#Directory frim which lazy_thread_safety_test will get its schema.h
include_directories(
${CMAKE_BINARY_DIR}/schemas/sdai_cd209
)
SC_ADDEXEC(lazy_thread_safety_test "lazy_thread_safety_test.cc" "steplazyfile;stepeditor" )
set_target_properties(lazy_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD -DNO_REGISTRY")
target_link_libraries(lazy_thread_safety_test sdai_cd209 "pthread" ) #sdai_cd209 in causes schema dependency
endif(HAVE_STD_THREAD)
SC_ADDLIB(steplazyfile "${clLazyFile_SRCS};${clLazyFile_HDRS}" "stepcore;stepdai;steputils;base")
SC_ADDEXEC(lazy_test "lazy_test.cc" "steplazyfile;stepeditor" )
set_target_properties(lazy_test PROPERTIES COMPILE_FLAGS "-DNO_REGISTRY" )
if(TARGET lazy_test-static)
set_target_properties(lazy_test-static PROPERTIES COMPILE_FLAGS "-DNO_REGISTRY" )
endif(TARGET lazy_test-static)
install(FILES ${SC_CLLAZYFILE_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cllazyfile)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cllazyfile)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+1 -1
View File
@@ -27,7 +27,7 @@ class SC_LAZYFILE_EXPORT headerSectionReader: public sectionReader {
return _headerInstances;
}
virtual ~headerSectionReader() {
~headerSectionReader() {
//FIXME delete each instance?! maybe add to clear, since it iterates over everything already
//enum clearHow { rawData, deletePointers }
_headerInstances->clear();
+56 -2
View File
@@ -3,6 +3,10 @@
#include <lazyInstMgr.h>
#include <instmgr.h>
#include <lazyTypes.h>
#include <sc_mutex.h>
#include <sc_thread.h>
/**
* \file instMgrHelper.h helper classes for the lazyInstMgr. Allows use of SDAI_Application_instance class
@@ -30,6 +34,12 @@ class mgrNodeHelper: protected MgrNode {
// unsigned int c = _lim->countDataSections();
return _lim->loadInstance( _id );
}
///Thread safe counterpart of GetSTEPentity()
inline SDAI_Application_instance * GetSTEPentitySafely() {
return _lim->loadInstanceSafely( _id );
}
};
@@ -42,14 +52,58 @@ class mgrNodeHelper: protected MgrNode {
class instMgrAdapter: public InstMgr {
protected:
mgrNodeHelper _mn;
mgrNodeHelper _mn; //Used in single threaded operations
lazyInstMgr * _lim; //Used in multi threaded operations
//map between threadID and the thread's local copy of mgrNodeHelper. Each thread has zero or one copy
//of mgrNodeHelper assigned to it. This _map holds the pointer to that mgrNodeHelper.
idNodeMap_t _map;
sc_mutex _mapMtx;
public:
instMgrAdapter( lazyInstMgr * lim ): InstMgr( 0 ), _mn( lim ) {}
instMgrAdapter( lazyInstMgr * lim ): InstMgr( 0 ), _mn( lim ) {
_lim = lim;
_map.clear();
}
//In case of multiple threads an explicit destructor is needed to free each threads mgrNodeHelper copy
~instMgrAdapter() {
if( _map.empty() ) {
return;
}
for( idNodeMap_t::iterator it = _map.begin(); it != _map.end(); it++ ) {
delete it->second;
}
}
inline mgrNodeHelper * FindFileId( int fileId ) {
_mn.setInstance( fileId );
return &_mn;
}
///Thread-safe counterpart of FindFileId( fileId ). It protects the state of mgrNodeHelper.
inline mgrNodeHelper * FindFileIdSafely( int fileId ) {
mgrNodeHelper * _myMN;
thread_id_t tid = sc_thread::getthread_id();
_mapMtx.lock();
idNodeMap_t::iterator it = _map.find( tid );
if( it == _map.end() ) {
//thread local copy yet not made. Hence create its copy.
_myMN = new mgrNodeHelper( _lim );
_map.insert( idNodePair_t( tid, _myMN ) );
} else {
//reuse the already existing copy.
_myMN = it->second;
}
_mapMtx.unlock();
_myMN->setInstance( fileId );
return _myMN;
}
};
+3 -2
View File
@@ -11,13 +11,14 @@ void lazyFileReader::initP21() {
for( ;; ) {
lazyDataSectionReader * r;
r = new lazyP21DataSectionReader( this, _file, _file.tellg(), _parent->countDataSections() );
sectionID sid = _parent->reserveDataSection();
r = new lazyP21DataSectionReader( this, _file, _file.tellg(), sid );
if( !r->success() ) {
delete r; //last read attempt failed
std::cerr << "Corrupted data section" << std::endl;
break;
}
_parent->registerDataSection( r );
_parent->registerDataSection( r, sid );
//check for new data section (DATA) or end of file (END-ISO-10303-21;)
while( isspace( _file.peek() ) && _file.good() ) {
+159 -16
View File
@@ -1,17 +1,16 @@
#include "lazyTypes.h"
#include "lazyInstMgr.h"
#include "Registry.h"
#include <SubSuperIterators.h>
#include "SdaiSchemaInit.h"
#include "instMgrHelper.h"
lazyInstMgr::lazyInstMgr() {
_headerRegistry = new Registry( HeaderSchemaInit );
_mainRegistry = 0;
_instanceTypes = new instanceTypes_t( 255 ); //NOTE arbitrary max of 255 chars for a type name
_lazyInstanceCount = 0;
_loadedInstanceCount = 0;
_longestTypeNameLen = 0;
_mainRegistry = 0;
_errors = new ErrorDescriptor();
_ima = new instMgrAdapter( this );
}
@@ -23,51 +22,85 @@ lazyInstMgr::~lazyInstMgr() {
//loop over files, sections, instances; delete header instances
lazyFileReaderVec_t::iterator fit = _files.begin();
for( ; fit != _files.end(); ++fit ) {
delete *fit;
if( *fit ) {
delete *fit;
}
}
dataSectionReaderVec_t::iterator sit = _dataSections.begin();
for( ; sit != _dataSections.end(); ++sit ) {
delete *sit;
if( *sit ) {
delete *sit;
}
}
_instancesLoaded.clear();
_instanceStreamPos.clear();
void * last = _instanceTypes->end().key;
void * current = _instanceTypes->begin().key;
std::string str;
while( current != last ) {
str = (char *)current;
str.clear();
current = _instanceTypes->next().key;
}
str.clear();
delete _instanceTypes;
}
sectionID lazyInstMgr::registerDataSection( lazyDataSectionReader * sreader ) {
_dataSections.push_back( sreader );
return _dataSections.size() - 1;
sectionID lazyInstMgr::reserveDataSection() {
mtxLock( dataSectionsMtx );
sectionID sid = _dataSections.size();
_dataSections.push_back( NULL );
mtxUnlock( dataSectionsMtx );
return sid;
}
void lazyInstMgr::registerDataSection( lazyDataSectionReader * sreader, sectionID sid ) {
assert( _dataSections[sid] == NULL );
mtxLock( dataSectionsMtx );
_dataSections[sid] = sreader;
mtxUnlock( dataSectionsMtx );
}
void lazyInstMgr::addLazyInstance( namedLazyInstance inst ) {
assert( inst.loc.begin > 0 && inst.loc.instance > 0 && inst.loc.section >= 0 );
mtxLock( instanceTypesMtx );
_lazyInstanceCount++;
assert( inst.loc.begin > 0 && inst.loc.instance > 0 );
int len = strlen( inst.name );
if( len > _longestTypeNameLen ) {
_longestTypeNameLen = len;
_longestTypeName = inst.name;
}
_instanceTypes->insert( inst.name, inst.loc.instance );
mtxUnlock( instanceTypesMtx );
/* store 16 bits of section id and 48 of instance offset into one 64-bit int
** TODO: check and warn if anything is lost (in calling code?)
** does 32bit need anything special?
**
** create conversion class?
** could then initialize conversion object with number of bits
** also a good place to check for data loss
* TODO: check and warn if anything is lost (in calling code?)
* does 32bit need anything special?
*/
positionAndSection ps = inst.loc.section;
ps <<= 48;
ps |= ( inst.loc.begin & 0xFFFFFFFFFFFFULL );
mtxLock( instanceStreamPosMtx );
_instanceStreamPos.insert( inst.loc.instance, ps );
mtxUnlock( instanceStreamPosMtx );
if( inst.refs ) {
if( inst.refs->size() > 0 ) {
//forward refs
mtxLock( fwdRefsMtx );
_fwdInstanceRefs.insert( inst.loc.instance, *inst.refs );
mtxUnlock( fwdRefsMtx );
instanceRefs::iterator it = inst.refs->begin();
for( ; it != inst.refs->end(); ++it ) {
//reverse refs
mtxLock( revRefsMtx );
_revInstanceRefs.insert( *it, inst.loc.instance );
mtxUnlock( revRefsMtx );
}
} else {
delete inst.refs;
@@ -96,9 +129,16 @@ void lazyInstMgr::openFile( std::string fname ) {
SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
assert( _mainRegistry && "Main registry has not been initialized. Do so with initRegistry() or setRegistry()." );
SDAI_Application_instance * inst = 0;
positionAndSection ps;
sectionID sid;
SDAI_Application_instance * inst = _instancesLoaded.find( id );
mtxLock( instanceStreamPosMtx );
mtxLock( loadInstanceMtx );
inst = _instancesLoaded.find( id );
mtxUnlock( loadInstanceMtx );
instanceStreamPos_t::cvector * cv;
if( !inst && 0 != ( cv = _instanceStreamPos.find( id ) ) ) {
//FIXME _instanceStreamPos.find( id ) can return nonzero for nonexistent key?!
@@ -119,14 +159,117 @@ SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
break;
}
if( ( inst ) && ( inst != & NilSTEPentity ) ) {
mtxLock( loadInstanceMtx );
_instancesLoaded.insert( id, inst );
_loadedInstanceCount++;
mtxUnlock( loadInstanceMtx );
} else {
std::cerr << "Error loading instance #" << id << "." << std::endl;
}
} else {
} else if( !inst ) {
std::cerr << "Instance #" << id << " not found in any section." << std::endl;
}
mtxUnlock( instanceStreamPosMtx );
return inst;
}
instanceSet * lazyInstMgr::instanceDependenciesHelper( instanceID id, instanceRefs_t * _fwdRefs ) {
instanceSet * checkedDependencies = new instanceSet();
instanceRefs dependencies; //Acts as queue for checking duplicated dependency
instanceRefs_t::cvector * _fwdRefsVec = _fwdRefs->find( id );
//Initially populating direct dependencies of id into the queue
if( _fwdRefsVec != 0 ) {
dependencies.insert( dependencies.end(), _fwdRefsVec->begin(), _fwdRefsVec->end() );
}
size_t curPos = 0;
while( curPos < dependencies.size() ) {
bool isNewElement = ( checkedDependencies->insert( dependencies.at( curPos ) ) ).second;
if( isNewElement ) {
_fwdRefsVec = _fwdRefs->find( dependencies.at( curPos ) );
if( _fwdRefsVec != 0 ) {
dependencies.insert( dependencies.end(), _fwdRefsVec->begin(), _fwdRefsVec->end() );
}
}
curPos++;
}
return checkedDependencies;
}
instanceSet * lazyInstMgr::instanceDependencies( instanceID id ) {
return instanceDependenciesHelper( id, getFwdRefs() );
}
void lazyInstMgr::openFileSafely( std::string fname ) {
filesMtx.lock();
size_t size = _files.size();
_files.push_back( NULL ); //place Holder
filesMtx.unlock();
lazyFileReader * fileReader = new lazyFileReader( fname, this, size );
filesMtx.lock();
_files[size] = fileReader;
filesMtx.unlock();
}
instanceRefs_t * lazyInstMgr::getFwdRefsSafely() {
fwdRefsMtx.lock();
instanceRefs_t * myFwdRefsCopy = new instanceRefs_t( _fwdInstanceRefs );
fwdRefsMtx.unlock();
return myFwdRefsCopy;
}
instanceRefs_t * lazyInstMgr::getRevRefsSafely() {
revRefsMtx.lock();
instanceRefs_t * myRevRefsCopy = new instanceRefs_t( _revInstanceRefs );
revRefsMtx.unlock();
return myRevRefsCopy;
}
instanceTypes_t::cvector * lazyInstMgr::getInstancesSafely( std::string type ) {
instanceTypesMtx.lock();
instanceTypes_t::cvector * typeInstances = _instanceTypes->find( type.c_str() );
instanceTypesMtx.unlock();
return typeInstances;
}
unsigned int lazyInstMgr::countInstancesSafely( std::string type ) {
instanceTypes_t::cvector * v = getInstancesSafely( type );
if( !v ) {
return 0;
}
return v->size();
}
SDAI_Application_instance * lazyInstMgr::loadInstanceSafely( instanceID id ) {
assert( _mainRegistry && "Main registry has not been initialized. Do so with initRegistry() or setRegistry()." );
SDAI_Application_instance * sdaiInst;
mtxLock( loadInstanceMtx );
sdaiInst = _instancesLoaded.find( id );
mtxUnlock( loadInstanceMtx );
if( !sdaiInst ) {
sdaiInst = loadInstance( id );
}
return sdaiInst;
}
instanceSet * lazyInstMgr::instanceDependenciesSafely( instanceID id ) {
return instanceDependenciesHelper( id, getFwdRefsSafely() );
}
+70 -32
View File
@@ -9,6 +9,8 @@
#include "lazyFileReader.h"
#include "lazyTypes.h"
#include "sc_mutex.h"
#include "Registry.h"
#include "sc_memmgr.h"
@@ -22,11 +24,11 @@ class instMgrAdapter;
class lazyInstMgr {
protected:
/** multimap from instance number to instances that it refers to
/** map from instance number to instances that it refers to
* \sa instanceRefs_pair
*/
instanceRefs_t _fwdInstanceRefs;
/** multimap from instance number to instances that refer to it - the majority of these will not be inverse references!
/** map from instance number to instances that refer to it
* \sa instanceRefs_pair
*/
instanceRefs_t _revInstanceRefs;
@@ -39,15 +41,11 @@ class lazyInstMgr {
/** map from instance number to instance pointer (loaded instances only)
* \sa instancesLoaded_pair
*
* TODO should be multimap to allow use of instances in multiple data sections?
* a unique instance ID (containing sectionID and instanceID) would also work
*/
instancesLoaded_t _instancesLoaded;
/** map from instance number to beginning and end positions and the data section
* \sa instanceStreamPos_pair
*
* FIXME to save memory, modify judyL2Array to not use a vector until there are several
* instances with the same instanceID. This will help elsewhere as well.
*/
@@ -66,9 +64,13 @@ class lazyInstMgr {
instMgrAdapter * _ima;
/** mutexes for mutual exclusion */
sc_mutex fwdRefsMtx, revRefsMtx, instanceTypesMtx, loadInstanceMtx, instanceStreamPosMtx, dataSectionsMtx, filesMtx;
public:
lazyInstMgr();
~lazyInstMgr();
void addSchema( void ( *initFn )() ); //?
void openFile( std::string fname );
void addLazyInstance( namedLazyInstance inst );
@@ -83,14 +85,9 @@ class lazyInstMgr {
instanceRefs_t * getRevRefs() {
return & _revInstanceRefs;
}
/// returns a vector containing the instances that match `type`
instanceTypes_t::cvector * getInstances( std::string type, bool caseSensitive = false ) { /*const*/
if( !caseSensitive ) {
std::string::iterator it = type.begin();
for( ; it != type.end(); ++it ) {
*it = toupper( *it );
}
}
/// returns two iterators delimiting the instances that match `type`
instanceTypes_t::cvector * getInstances( std::string type ) { /*const*/
return _instanceTypes->find( type.c_str() );
}
/// get the number of instances of a certain type
@@ -101,6 +98,7 @@ class lazyInstMgr {
}
return v->size();
}
instancesLoaded_t * getHeaderInstances( fileID file ) {
return _files[file]->getHeaderInstances();
}
@@ -148,7 +146,12 @@ class lazyInstMgr {
/// get the number of types of instances.
unsigned long getNumTypes() const;
sectionID registerDataSection( lazyDataSectionReader * sreader );
/// reserves a slot in _dataSections vector. Gives the slot a value null, and return the index value.
sectionID reserveDataSection();
/// updates _dataSections vector with the sreader value at the given index.
void registerDataSection( lazyDataSectionReader * sreader, sectionID sid );
fileID registerLazyFile( lazyFileReader * freader );
ErrorDescriptor * getErrorDesc() {
@@ -157,26 +160,61 @@ class lazyInstMgr {
SDAI_Application_instance * loadInstance( instanceID id );
/// lists all instances that one instance depends on (recursive)
instanceSet * instanceDependencies( instanceID id );
instanceSet * instanceDependenciesHelper( instanceID id, instanceRefs_t * _fwdRefs );
/// thread safe counterpart of openFile();
void openFileSafely( std::string fname );
/// thread safe counterpart of getFwdRefs()
instanceRefs_t * getFwdRefsSafely();
/// thread safe counterpart of getRevRefs()
instanceRefs_t * getRevRefsSafely();
/// thread safe counterpart of getInstances()
instanceTypes_t::cvector * getInstancesSafely( std::string type );
/// thread safe counterpart of countInstances()
unsigned int countInstancesSafely( std::string type );
/// Thread safe counterpart of loadInstance( instanceID )
SDAI_Application_instance * loadInstanceSafely( instanceID id );
/// Thread safe counterpart of instanceDependencies( instanceID )
instanceSet * instanceDependenciesSafely( instanceID id );
void mtxLock( sc_mutex &mtx ) {
mtx.lock();
}
void mtxUnlock( sc_mutex &mtx ) {
mtx.unlock();
}
/// unloads all instances. (For testing purpose, not thread safe)
void unloadAllInstances() {
_loadedInstanceCount = 0;
_instancesLoaded.clear();
}
/// (For testing purpose, not thread safe)
instanceStreamPos_t * getInstanceStreamPos() {
return &_instanceStreamPos;
}
// TODO implement these
// add another schema to registry
//void addSchema( void ( *initFn )() );
//list all instances that one instance depends on (recursive)
//std::vector<instanceID> instanceDependencies( instanceID id ); //set is faster?
/* * the opposite of instanceDependencies() - all instances that are *not* dependencies of one particular instance
/* * the opposite of instanceDependencies() - all instances that are *not* dependencies of one particular instance
same as above, but with list of instances */
//std::vector<instanceID> notDependencies(...)
//std::vector<instanceID> notDependencies(...)
//renumber instances so that they are numbered 1..N where N is the total number of instances
//void normalizeInstanceIds();
//find data that is repeated and eliminate, if possible
//void eliminateDuplicates();
//tell instMgr to use instances from this section
//void useDataSection( sectionID id );
//renumber instances so that they are numbered 1..N where N is the total number of instances
//void normalizeInstanceIds();
//find data that is repeated and eliminate, if possible
//void eliminateDuplicates();
//tell instMgr to use instances from this section
//void useDataSection( sectionID id );
// TODO support references from one file to another
};
+14 -1
View File
@@ -11,6 +11,15 @@ lazyP21DataSectionReader::lazyP21DataSectionReader( lazyFileReader * parent, std
while( nl = nextInstance(), ( ( nl.loc.begin > 0 ) && ( nl.name != 0 ) ) ) {
parent->getInstMgr()->addLazyInstance( nl );
}
if( sectionReader::_error->severity() <= SEVERITY_WARNING ) {
sectionReader::_error->PrintContents( std::cerr );
if( sectionReader::_error->severity() <= SEVERITY_INPUT_ERROR ) {
_error = true;
return;
}
}
if( !_file.good() ) {
_error = true;
return;
@@ -45,7 +54,11 @@ const namedLazyInstance lazyP21DataSectionReader::nextInstance() {
skipWS();
i.loc.section = _sectionID;
skipWS();
i.name = getDelimitedKeyword( ";( /\\" );
std::string * keyword = new string();
fillDelimitedKeyword( ";( /\\", *keyword );
i.name = keyword->c_str();
if( _file.good() ) {
end = seekInstanceEnd( & i.refs );
}
-99
View File
@@ -1,99 +0,0 @@
#ifndef LAZYREFS_H
#define LAZYREFS_H
#include <string>
#include <set>
#include <utility>
#include <vector>
#include "lazyTypes.h"
#include "ExpDict.h"
#include "sdaiApplication_instance.h"
class lazyRefs {
public:
//typedefs
typedef std::set<std::string> * entityTypeSet;
typedef std::pair< EntityDescriptor *, const char * > attrPair; //EntityDescriptor and attr name
typedef std::vector< STEPattribute * > attrVec;
protected:
/* don't need this - the default comparator of std::set, std::less, should work
///functor to compare std::pair<> of pointers; in this case, those in attrPair
struct pairCmp {
bool operator()( const attrPair & lhs, const attrPair & rhs ) const {
if( lhs.first == rhs.first && lhs.second == rhs.second ) {
return true;
}
return false;
}
};
typedef std::set< attrPair, pairCmp > attrVec; //set of attrPair's, and comparison functor
*/
///find any inverse attributes, put in `attrs`
/// attrs not necessarily in order!
void getInverseAttrs( attrVec & attrs, EntityDescriptor * ed ) {
attrs.clear();
supertypesIterator supersIter( ed );
InverseAItr invAttrIter;
Inverse_attribute * invAttr;
for( ; !supersIter.empty(); ++supersIter ) {
//look at attrs of *si
invAttrIter( *supersIter );
while( 0 != ( invAttr = invAttrIter.NextInverse_attribute() ) ) {
attrs.push_back( invAttr );
}
}
// look at our own attrs
invAttrIter( *ed );
while( 0 != ( invAttr = invAttrIter.NextInverse_attribute() ) ) {
attrs.push_back( invAttr );
}
}
void loadPossibleInverseRefs( instanceID id ) {
EntityDescriptor * eDesc = getEntityDescriptor( id );
//it would be nice to be able to check the type of each potential reference and only load those for which there is an inverse attr
//however, that would require that we build a list of all types with inverse reference *and* all of their children
//that requires looking up each type in the registry and iterating over its supertypes
//slow? faster if results are cached, perhaps in std::set<std::string>
/*
* need to look for hits in _revInstanceRefs, then check the type of each
* however, we must also check their supertypes - use checkIfEntityTypeMatch() (**** faster to compare entities with a subtype list instead? ****)
* also, we must check which entity type actually declares the attr, and use that as the type name to match
*/
//for each inverse attr, add that type and its subtypes to a set
attrVec invAttrs;
getInverseAttrs( invAttrs, eDesc );
attrVec::iterator iAiter = invAttrs.begin();
for( ; iAiter != invAttrs.end(); ++iAiter ) {
// const char * _inverted_attr_id;
// const char * _inverted_entity_id;
iAiter->_inverted_attr_id;
iAiter->_inverted_entity_id;
iAiter->Owner();
}
//find possible referring instances and loop over them, checking each, loading instances of types that may have matching refs
instanceRefs_t::cvector * possRefs = _revInstanceRefs.find( id );
const instanceRefs_t::cvector::iterator it = possRefs->cbegin();
for( ; it != possRefs->cend; ++it ) {
//1. get inst type
//2. compare its type to types that may reference this inst
//3. if there is a match, load it and check whether this instance is reference by the correct attr
//4. if so, link the two
//5. repeat
}
}
public:
void loadInverseRefs( instanceID id ) {}
};
#endif //LAZYREFS_H
-68
View File
@@ -1,68 +0,0 @@
for inverse attrs, we have the attr name and the type of the instance
--load instance, find inverse attr(s)
--for each inverse attr:
--find all instance types that inherit from the inverted attr's owner (list A)
--look up instances that reference the one in question (list B) - use memoization
--find instances that match both lists, put in list C
--load instances in list C
--for list C, check that the relevant attr references the original instance - if not, unload (?)
--
--when done with this inverse attr, cache list A
EXAMPLE
*******
information model
-----------------
ENTITY Object;
ObjectType : OPTIONAL STRING;
INVERSE
IsDefinedBy : SET [0:?] OF RelDefinesByType FOR RelatedObjects;
END_ENTITY;
ENTITY RelDefinesByType;
RelatedObjects : SET [1:?] OF Object;
END_ENTITY;
ENTITY Window
SUBTYPE OF (Object);
Description : OPTIONAL string;
END_ENTITY;
data file
---------
#1=OBJECT('one');
#2=RELDEFINESBYTYPE((#1));
#3=RELDEFINESBYTYPE((#4));
#4=WINDOW('two','blah');
#1 and #4 have an inverse attr, but this is not visible in the data file
#2 and #3 have #1 and #4, respectively, in an aggregate (thus the parenthesis around the instance); in this case, a SET called RelatedObjects
RelatedObjects is the inverted attr that the inverse attr IsDefinedBy links to
looking at the entity descriptor for WINDOW, it is not apparent that there is an inverse attr; its parents must be examined
given inverted attr ia:
attr method value
----------- -----
ia->Name() isdefinedby
ia->inverted_attr_id_() relatedobjects
ia->inverted_entity_id_() reldefinesbytype
1. for the instance in question, find inverse attrs with recursion
2. for each ia,
a. entity name is returned by ia->inverted_entity_id_()
b. add this entity and its children to a list (list A)
c. look up references to the current instance (list B)
d. for each item in B, look up its type; if its type is present in A, remember the instance number (list C)
e. load each instance in C
f. (optional) check if the relevant inverted attr of instances loaded from list C reference the instance in step 1; if not, unload **IF** the instance hadn't been loaded
--> if it was loaded, this implies that it is used elsewhere
g. cache list A, since it may be useful in the future
-- best to store such that the most recently (frequently?) used lists are retained and others are discarded
+13
View File
@@ -3,8 +3,12 @@
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <stdint.h>
# include <sc_thread.h>
#include "judyLArray.h"
#include "judySArray.h"
#include "judyL2Array.h"
@@ -13,6 +17,7 @@
class SDAI_Application_instance;
class lazyDataSectionReader;
class lazyFileReader;
class mgrNodeHelper;
enum fileTypeEnum { Part21, Part28 };
// enum loadingEnum { immediate, lazy };
@@ -35,6 +40,8 @@ typedef uint64_t positionAndSection;
typedef std::vector< instanceID > instanceRefs;
typedef std::set< instanceID > instanceSet;
//TODO: create a "unique instance id" from the sectionID and instanceID, and use it everywhere?
/** This struct contains all the information necessary to locate an instance. It is primarily
@@ -76,6 +83,12 @@ typedef std::vector< lazyDataSectionReader * > dataSectionReaderVec_t;
// files
typedef std::vector< lazyFileReader * > lazyFileReaderVec_t;
//map thread id to mgrNodeHelper. Each thread will have only one mgrNodeHelper value.
typedef std::map< thread_id_t, mgrNodeHelper * > idNodeMap_t;
//thread id - mgrNodeHelper pointer pair to be used while using the above map
typedef std::pair< thread_id_t, mgrNodeHelper * > idNodePair_t;
// type for performing actions on multiple instances
// NOTE not useful? typedef std::vector< lazyInstance > lazyInstanceVec_t;
+29
View File
@@ -71,6 +71,34 @@ instanceID printRefs( lazyInstMgr & mgr ) {
return id;
}
/// prints dependencies of an instance
void printDeps( lazyInstMgr & mgr ) {
const unsigned int displayInstances = 10;
instanceRefs_t * refs = mgr.getFwdRefs();
instanceRefs_t::cpair p = refs->end();
instanceID id = p.key;
instanceSet * dependencies = mgr.instanceDependencies( id );
std::cout << std::endl <<"Dependencies" << std::endl << "==============" << std::endl;
instanceSet::const_iterator it( dependencies->begin() ), end( dependencies->end() );
std::cout << "Example: Instance #" << id << " is recursively dependent on " << dependencies->size() << " instances: ";
unsigned int i;
for(i = 0; it != end && i < displayInstances; it++, i++ ) {
std::cout << *it << " ";
}
if( dependencies->size() > displayInstances ) {
std::cout << ".... (Displaying only " << displayInstances << " instances) ";
}
std::cout << std::endl;
std::cout << std::endl;
delete dependencies;
}
///prints info about a complex instance
void dumpComplexInst( STEPcomplex * c, unsigned int depth ) {
if( c ) {
@@ -127,6 +155,7 @@ int main( int argc, char ** argv ) {
// std::cout << "Total types: " << mgr->getNumTypes() << std::endl;
instWithRef = printRefs( *mgr );
printDeps( *mgr );
#ifndef NO_REGISTRY
if( instWithRef ) {
+593
View File
@@ -0,0 +1,593 @@
#include "lazyTypes.h"
#include "lazyInstMgr.h"
#include "SdaiSchemaInit.h"
#include "instMgrHelper.h"
// Registry will be needed for checkLazyLoadingSafety & checkLazyLoadingSafetyWithAdapter checks.
#ifndef NO_REGISTRY
# include "schema.h"
#endif //NO_REGISTRY
#include <algorithm>
#ifdef HAVE_STD_THREAD
# include <thread>
#else
# error Need std::thread for this test!
#endif
/// It copies the keys of the _refs judy structure provided to it into the vector realRefs
void prepareRealRefs ( instanceRefs_t * _refs, instanceRefs &realRefs ) {
instanceID last = _refs->end().key;
instanceID current = _refs->begin().key;
while( current != last ) {
realRefs.push_back( current );
current = _refs->next().key;
}
realRefs.push_back( last );
}
/// It copies the keys of the _refs judy structure provided to it into the vector realRefs
void prepareRealRefsFromStreamPos ( instanceStreamPos_t * _spos, instanceRefs &realRefs ) {
instanceID last = _spos->end().key;
instanceID current = _spos->begin().key;
while( current != last ) {
realRefs.push_back( current );
current = _spos->next().key;
}
realRefs.push_back( last );
}
/// Used by an individual thread to iterate over the keys of the _fwdRefs / _revRefs multiple times. For each iteration it expects the order of the keys to be the same as dictated by realRefs.
void iterateOverRefs ( lazyInstMgr *mgr, instanceRefs * realRefs, bool forward, bool * success ) {
const int iterations = 1000;
int i, k, instances = realRefs->size();
instanceID current;
instanceRefs_t * _refs;
for( k = 0; k < iterations; k++ ) {
_refs = forward ? mgr->getFwdRefsSafely() : mgr->getRevRefsSafely();
current = _refs->begin().key;
for( i = 0; i < instances; i++ ) {
if( current != (*realRefs)[i] ) {
break;
}
current = _refs->next().key;
}
*success = *success && ( i == instances );
}
}
/// Checks the thread safety of _fwdRefs (_revRefs) when the forward value provided to it is true (false).
bool checkRefsSafety( char * fileName, bool forward ) {
instanceRefs realRefs;
lazyInstMgr * mgr = new lazyInstMgr;
mgr->openFile( fileName );
if( forward ) {
std::cout << "Checking thread safety while iterating over forward references..." ;
prepareRealRefs( mgr->getFwdRefs(), realRefs );
} else {
std::cout << "Checking thread safety while iterating over backward references..." ;
prepareRealRefs( mgr->getRevRefs(), realRefs );
}
bool success[2] = { true, true };
std::thread first( iterateOverRefs, mgr, &realRefs, forward, &success[0] );
std::thread second( iterateOverRefs, mgr, &realRefs, forward, &success[1] );
first.join();
second.join();
bool pass = ( success[0] && success[1] );
if( pass ) {
std::cout << "..PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
if( !success[0] ) {
std::cout << "\tThread 0 could not iterate properly" << std::endl;
}
if( !success[1] ) {
std::cout << "\tThread 1 could not iterate properly" << std::endl;
}
}
std::cout << std::endl;
delete mgr;
return pass;
}
/// Checks thread safety of getFwdRefs();
bool checkFwdRefsSafety( char * fileName ) {
return checkRefsSafety( fileName, true );
}
/// Checks thread safety of getFwdRefs();
bool checkRevRefsSafety( char * fileName ) {
return checkRefsSafety( fileName, false );
}
/// A vector of some common types which are present in most step files. The types persent in this vector are used to check for thread safety.
const std::vector< std::string > commonTypes { "PRODUCT_DEFINITION", "CARTESIAN_POINT", "NODE", "CLASSIFICATION_ROLE" };
/// Prepares a vector containing pointers to list of instances of the above types.
void prepareSameTypeInstances( lazyInstMgr *mgr, std::vector< const instanceRefs * > &sameTypeInstances ) {
for( int i = 0; i < ( int )commonTypes.size(); i++ ) {
sameTypeInstances.push_back( mgr->getInstances( commonTypes[i] ) );
}
}
/// compares the list of both vectors. Returns true when the lists are same.
bool compareTypeLists( const instanceRefs * v1, const instanceRefs * v2 ) {
if( v1 == NULL || v1->empty() ) {
//return true if both lists are NULL or EMPTY. false if only one is NULL or EMPTY
return ( v2 == NULL || v2->empty() );
} else {
//An O(1) operation since if the first element is same so will be the rest. (std::vectors are concurrent read safe)
return ( v1->at( 0 ) == v2->at( 0 ) );
}
}
/// compares the original instances lists with the thread's own view of instances list.
void iterateTypeLists( lazyInstMgr * mgr, std::vector< const instanceRefs * > * sameTypeInstances, bool * success ) {
const int iterations = 100000;
const instanceRefs * refs;
int i, k, instances = commonTypes.size();
for( k = 0; k < iterations; k++ ) {
for( i = 0; i < instances; i++ ) {
refs = mgr->getInstancesSafely( commonTypes[i] );
if( !compareTypeLists( refs, (*sameTypeInstances)[i] ) ) {
break;
}
}
*success = *success && ( i == instances );
}
}
/// checks the thread safety of getInstances();
bool checkTypeInstancesSafety( char * fileName ) {
lazyInstMgr * mgr = new lazyInstMgr;
mgr->openFile( fileName );
std::cout << "Checking thread safety while getting insances of a common types..." ;
std::vector< const instanceRefs * > sameTypeInstances;
prepareSameTypeInstances( mgr, sameTypeInstances );
bool success[2] = { true, true };
std::thread first( iterateTypeLists, mgr, &sameTypeInstances, &success[0] );
std::thread second( iterateTypeLists, mgr, &sameTypeInstances, &success[1] );
first.join();
second.join();
bool pass = ( success[0] && success[1] );
if( pass ) {
std::cout << "..PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
if( !success[0] ) {
std::cout << "\tThread 0 could not get insances properly" << std::endl;
}
if( !success[1] ) {
std::cout << "\tThread 1 could not get insances properly" << std::endl;
}
}
std::cout << "\t\tNumber of instances of different types: ";
for( int i = 0; i < ( int )commonTypes.size(); i++ ) {
std::cout << ( sameTypeInstances[i] == NULL ? 0 : sameTypeInstances[i]->size() ) << " ";
}
std::cout << std::endl << std::endl;
delete mgr;
return pass;
}
/// load instances found in _refs into the instancesLoaded. After doing this once, it iterates over the _refs and reports any changes in loaded value.
/// Either directly calls loadInstance or uses an adapter, (determined by the value of useAdapter)
void loadInstancesFromList( lazyInstMgr * mgr, instanceRefs * _refs, instancesLoaded_t * myInstances, bool useAdapter, bool * success) {
const int instances = _refs->size();
SDAI_Application_instance * sdaiInstance;
int i;
// Initial insertion into myInstances
for( i = 0; i < instances; i++ ) {
if( useAdapter ) {
sdaiInstance = mgr->getAdapter()->FindFileIdSafely( _refs->at( i ) )->GetSTEPentitySafely();
} else {
sdaiInstance = mgr->loadInstanceSafely( _refs->at( i ) );
}
myInstances->insert( _refs->at( i ), sdaiInstance );
}
// For each instance comparing the new pointer with the original pointer
for( i = 0; i < instances; i++ ) {
if( useAdapter ) {
sdaiInstance = mgr->getAdapter()->FindFileIdSafely( _refs->at( i ) )->GetSTEPentitySafely();
} else {
sdaiInstance = mgr->loadInstanceSafely( _refs->at( i ) );
}
if( myInstances->find( _refs->at( i ) ) != sdaiInstance ) {
//the old value has been overwritten. An object lazy-loaded twice. Not Good!!!
*success = false;
}
}
}
//compares the instances present in loadedOnT1 and loadedOnT2. If both have an instance belonging to a particular instanceID then the instances should be same
bool compareLoadedInstances( instanceRefs * toBeLoadedOnT1, instancesLoaded_t * loadedOnT1, instanceRefs * toBeLoadedOnT2, instancesLoaded_t * loadedOnT2 ) {
SDAI_Application_instance * sdaiInstance;
//Iterate over instanceID's in toBeLoadedOnT1
int i, instances = toBeLoadedOnT1->size();
for( i = 0; i < instances; i++ ) {
sdaiInstance = loadedOnT2->find( toBeLoadedOnT1->at( i ) );
if( sdaiInstance != NULL ) {
if( sdaiInstance != loadedOnT1->find( toBeLoadedOnT1->at( i ) ) ) {
return false;
}
}
}
//Iterate over instanceID's in toBeLoadedOnT2
instances = toBeLoadedOnT2->size();
for( i = 0; i < instances; i++ ) {
sdaiInstance = loadedOnT1->find( toBeLoadedOnT2->at( i ) );
if( sdaiInstance != NULL ) {
if( sdaiInstance != loadedOnT2->find( toBeLoadedOnT2->at( i ) ) ) {
return false;
}
}
}
return true;
}
#ifndef NO_REGISTRY
//checks thread safety of loadInstance. (Also of instMgrAdapter if useAdapter is TRUE)
bool checkLazyLoadingSafety( char * fileName, bool useAdapter=false ) {
instanceRefs instancesToBeLoadedFwd, instancesToBeLoadedRev;
instanceRefs * toBeLoadedOnT1, * toBeLoadedOnT2;
instancesLoaded_t loadedOnT1, loadedOnT2;
lazyInstMgr * mgr = new lazyInstMgr;
mgr->initRegistry( SchemaInit );
mgr->openFile( fileName );
std::cout << "Checking thread safety in Lazy Loading ("<< ( useAdapter ? "with" : "without" ) << " Adapter)...";
prepareRealRefs( mgr->getFwdRefs(), instancesToBeLoadedFwd );
prepareRealRefs( mgr->getRevRefs(), instancesToBeLoadedRev );
bool intraThreadSuccess[2] = { true, true };
bool interThreadSuccess = true;
const int iterations = 50;
for( int i = 0; i < 2 * iterations; i++ ) {
// First set iterations both threads will try to load from same list.
toBeLoadedOnT1 = &instancesToBeLoadedFwd;
toBeLoadedOnT2 = i < iterations ? &instancesToBeLoadedFwd : &instancesToBeLoadedRev;
std::thread first( loadInstancesFromList, mgr, toBeLoadedOnT1, &loadedOnT1, useAdapter, &intraThreadSuccess[0] );
std::thread second( loadInstancesFromList, mgr, toBeLoadedOnT2, &loadedOnT2, useAdapter, &intraThreadSuccess[1] );
first.join();
second.join();
interThreadSuccess &= compareLoadedInstances( toBeLoadedOnT1, &loadedOnT1, toBeLoadedOnT2, &loadedOnT2 );
mgr->unloadAllInstances();
loadedOnT1.clear();
loadedOnT2.clear();
}
bool pass = ( intraThreadSuccess[0] && intraThreadSuccess[1] && interThreadSuccess );
if( pass ) {
std::cout << "..PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
if( !intraThreadSuccess[0] ) {
std::cout << "\tThread 0: Difference in instances loaded within 1st and 2nd iterations" << std::endl;
}
if( !intraThreadSuccess[1] ) {
std::cout << "\tThread 1: Difference in instances loaded within 1st and 2nd iterations" << std::endl;
}
if( !interThreadSuccess ) {
std::cout << "\tDifference in instances loaded by the 2 threads" << std::endl;
}
}
std::cout << std::endl;
delete mgr;
return pass;
}
//checks thread safety of lazyloading along with that of instMgrAdapter
bool checkLazyLoadingSafetyWithAdapter( char * fileName ) {
return checkLazyLoadingSafety( fileName, true );
}
#endif //NO_REGISTRY
/// enum elements represent the status used checking thread safety of openFile
enum lazyInstMgrStatus {
FWD_REFS,
REV_REFS,
TYPES,
TOTAL_COUNT,
COUNT_DATA_SECTIONS,
LONGEST_TYPE,
STREAM_POS,
OK
};
std::string getLazyInstMgrStatusString( lazyInstMgrStatus lIMStatus ) {
switch( lIMStatus ) {
case FWD_REFS: return "FWD_REFS";
case REV_REFS: return "REV_REFS";
case TYPES: return "TYPES";
case TOTAL_COUNT: return "TOTAL_COUNT";
case COUNT_DATA_SECTIONS: return "COUNT_DATA_SECTIONS";
case LONGEST_TYPE: return "LONGEST_TYPE";
case STREAM_POS: return "STREAM_POS";
case OK: return "OK";
default: return "Unknown Type";
}
}
/// compares the given instanceRefs_t.
bool compareRefs( instanceRefs_t * _refs1, instanceRefs_t * _refs2 ) {
instanceRefs refs1, refs2;
prepareRealRefs( _refs1, refs1 );
prepareRealRefs( _refs2, refs2 );
//both vectors should have same number of elements
if( refs1.size() != refs2.size() ) {
return false;
}
for( size_t i = 0; i < refs1.size(); i++ ) {
const instanceRefs * deps1 = _refs1->find( refs1[i] );
const instanceRefs * deps2 = _refs2->find( refs1[i] );
//Just compare the size of both (value) vectors is sufficient
if( deps2 == NULL || deps1->size() != deps2->size() ) {
return false;
}
}
return true;
}
/// compares the given instance vectors. Returns true if both have same elements (irrespective of their order)
bool compareInstanceRefs( const instanceRefs * refs1, const instanceRefs * refs2 ) {
if( refs1 == NULL ) {
return ( refs2 == NULL ) || ( refs2->size() == 0 );
}
if( refs2 == NULL ) {
return ( refs1 == NULL ) || ( refs1->size() == 0 );
}
if( refs1->size() != refs2->size() ) {
return false;
}
for( size_t i = 0; i < refs1->size(); i++ )
{
if( std::find( refs2->begin(), refs2->end(), refs1->at( i ) ) == refs2->end() ) {
return false;
}
}
return true;
}
/// compares _instanceTypes data structure of both managers.
bool compareTypes( lazyInstMgr * mgr1, lazyInstMgr * mgr2 ) {
int i, types = commonTypes.size();
for( i = 0; i < types; i++ ) {
const instanceRefs * refs1 = mgr1->getInstances( commonTypes[i] );
const instanceRefs * refs2 = mgr2->getInstances( commonTypes[i] );
if( !compareInstanceRefs( refs1, refs2 ) ) {
return false;
}
}
return true;
}
/// compares the given positionAndSection vectors. Returns true if both have same elements (irrespective of their order)
bool comparePosVectors( const std::vector< positionAndSection > * pos1, const std::vector< positionAndSection > * pos2 ) {
if( pos1->size() != pos2->size() ) {
return false;
}
unsigned i, j;
for( i = 0; i < pos1->size(); i++ ) {
bool result = false;
for( j = 0; j < pos2->size(); j++ ) {
positionAndSection ps1, ps2;
ps1 = pos1->at( i );
ps2 = pos2->at( j );
//only checking the offset as the sectionID may be different
if( ( ps1 & 0xFFFFFFFFFFFF ) == ( ps2 & 0xFFFFFFFFFFFF ) ) {
result = true;
break;
}
}
if( !result ) {
return false;
}
}
return true;
}
/// For every instance compares its corresponding stream position vector in both lazyInstMgr. Returns false in case of any disprenency
bool compareStreamPos( lazyInstMgr * mgr1, lazyInstMgr * mgr2 ) {
instanceRefs refs1, refs2;
instanceStreamPos_t * _pos1 = mgr1->getInstanceStreamPos();
instanceStreamPos_t * _pos2 = mgr2->getInstanceStreamPos();
prepareRealRefsFromStreamPos( _pos1, refs1 );
prepareRealRefsFromStreamPos( _pos2, refs2 );
// number of instances in both managers must be equal
if( refs1.size() != refs2.size() ) {
return false;
}
const std::vector< positionAndSection > * pos1, * pos2;
unsigned int i;
for( i = 0; i < refs1.size(); i++ ) {
pos1 = _pos1->find( refs1[i] );
pos2 = _pos2->find( refs1[i] );
//checking pos1 and pos2 for similarity
if( !comparePosVectors( pos1, pos2 ) ) {
return false;
}
}
return true;
}
/// compares various data structures of both lazyInstMgr's and returns OK if both are similar, else returns the point of difference.
lazyInstMgrStatus compareLazyInstMgr( lazyInstMgr * mgr1, lazyInstMgr * mgr2 ) {
if( !compareRefs( mgr1->getFwdRefs(), mgr2->getFwdRefs() ) ) {
return FWD_REFS;
}
if( !compareRefs( mgr1->getRevRefs(), mgr2->getRevRefs() ) ) {
return REV_REFS;
}
// compares getType and getNumTypes
if( !compareTypes( mgr1, mgr2 ) ) {
return TYPES;
}
if( mgr1->totalInstanceCount() != mgr2->totalInstanceCount() ) {
return TOTAL_COUNT;
}
if( mgr1->countDataSections() != mgr2->countDataSections() ) {
return COUNT_DATA_SECTIONS;
}
if( mgr1->getLongestTypeName().length() != mgr2->getLongestTypeName().length() ) {
return LONGEST_TYPE;
}
if( !compareStreamPos( mgr1, mgr2 ) ) {
return STREAM_POS;
}
return OK;
}
/// used by different threads to open a step file
void openFile( lazyInstMgr * mgr, char * fileName ) {
mgr->openFileSafely( fileName );
}
/// checks the thread safety by opening multiple files in parallel
bool checkOpenFileSafety( char * file1, char * file2 ) {
lazyInstMgr * e_mgr = new lazyInstMgr; //expected lazyInstMgr
std::cout << "Checking thread safety while opening multiple files in parallel...";
e_mgr->openFile( file1 );
e_mgr->openFile( file2 );
lazyInstMgrStatus compareResult = OK;
const int iterations = 100;
for( int i = 0; i < iterations; i++ ) {
lazyInstMgr * a_mgr = new lazyInstMgr; //actual lazyInstMgr
std::thread first( openFile, a_mgr, file1 );
std::thread second( openFile, a_mgr, file2 );
first.join();
second.join();
compareResult = compareLazyInstMgr( e_mgr, a_mgr );
delete a_mgr;
if( compareResult != OK ) {
break;
}
}
bool pass = ( compareResult == OK );
if( pass ) {
std::cout << "..PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
std::cout << "\tDisperency in " << getLazyInstMgrStatusString( compareResult ) << " structure" << std::endl;
}
std::cout << std::endl;
delete e_mgr;
return pass;
}
/// These tests were run on stepcode/data/cd209/ATS1-out.stp && stepcode/data/cd209/ATS10-out.stp (Bigger files may take a longer time)
int main( int argc, char ** argv ) {
if( argc != 3 ) {
std::cerr << "Expected two argument, given " << argc - 1 << ". Exiting." << std::endl;
exit( EXIT_FAILURE );
}
bool pass = true;
pass &= checkFwdRefsSafety( argv[1] );
pass &= checkRevRefsSafety( argv[1] );
pass &= checkTypeInstancesSafety( argv[1] );
#ifndef NO_REGISTRY
pass &= checkLazyLoadingSafety( argv[1] );
pass &= checkLazyLoadingSafetyWithAdapter( argv[1] );
#endif //NO_REGISTRY
pass &= checkOpenFileSafety( argv[1], argv[2] );
if( pass ) {
exit( EXIT_SUCCESS );
}
exit( EXIT_FAILURE );
}
+4 -2
View File
@@ -20,6 +20,7 @@ p21HeaderSectionReader::p21HeaderSectionReader( lazyFileReader * parent, std::if
findSectionEnd();
_file.seekg( _sectionStart );
namedLazyInstance nl;
nextFreeInstance = 4; // 1-3 are reserved per 10303-21
while( nl = nextInstance(), ( nl.loc.begin > 0 ) ) {
std::streampos pos = _file.tellg();
_headerInstances->insert( nl.loc.instance, getRealInstance( _lazyFile->getInstMgr()->getHeaderRegistry(), nl.loc.begin, nl.loc.instance, nl.name, "", true ) );
@@ -31,7 +32,6 @@ p21HeaderSectionReader::p21HeaderSectionReader( lazyFileReader * parent, std::if
// part of readdata1
const namedLazyInstance p21HeaderSectionReader::nextInstance() {
namedLazyInstance i;
static instanceID nextFreeInstance = 4; // 1-3 are reserved per 10303-21
i.loc.begin = _file.tellg();
i.loc.section = _sectionID;
@@ -39,7 +39,9 @@ const namedLazyInstance p21HeaderSectionReader::nextInstance() {
if( i.loc.begin <= 0 ) {
i.name = 0;
} else {
i.name = getDelimitedKeyword( ";( /\\" );
std::string * keyword = new string();
fillDelimitedKeyword( ";( /\\", *keyword );
i.name = keyword->c_str();
if( 0 == strcmp( "FILE_DESCRIPTION", i.name ) ) {
i.loc.instance = 1;
+2
View File
@@ -6,6 +6,8 @@
#include "sc_export.h"
class SC_LAZYFILE_EXPORT p21HeaderSectionReader: public headerSectionReader {
protected:
instanceID nextFreeInstance;
public:
p21HeaderSectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid );
void findSectionStart();
+54 -16
View File
@@ -7,6 +7,7 @@
#include <assert.h>
#include "Registry.h"
#include "sc_strtoull.h"
#include "sdaiApplication_instance.h"
#include "read_func.h"
#include "SdaiSchemaInit.h"
@@ -23,6 +24,7 @@
sectionReader::sectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid ):
_lazyFile( parent ), _file( file ), _sectionStart( start ), _sectionID( sid ) {
_fileID = _lazyFile->ID();
_error = new ErrorDescriptor();
}
@@ -79,10 +81,9 @@ std::streampos sectionReader::findNormalString( const std::string & str, bool se
}
//NOTE different behavior than const char * GetKeyword( istream & in, const char * delims, ErrorDescriptor & err ) in read_func.cc
const char * sectionReader::getDelimitedKeyword( const char * delimiters ) {
static std::string str;
char c;
//NOTE different behavior than const char * FillKeyword( istream & in, const char * delims, ErrorDescriptor & err, std::string & str ) in read_func.cc
void sectionReader::fillDelimitedKeyword( const char * delimiters, std::string &str ) {
char c, firstSpaceDelimeter;
str.clear();
str.reserve( 100 );
skipWS();
@@ -95,17 +96,22 @@ const char * sectionReader::getDelimitedKeyword( const char * delimiters ) {
findNormalString( "*/" );
skipWS();
continue;
} else if( isspace( c ) ) {
//firstSpaceDelimeter is used for comparision later to handle the case where the first whitespace was a delimeter itself
firstSpaceDelimeter = c;
skipWS();//skip the remaining whitespaces
break;
} else {
_file.putback( c );
break;
}
}
c = _file.peek();
if( !strchr( delimiters, c ) ) {
if( !strchr( delimiters, c ) && !strchr( delimiters, firstSpaceDelimeter ) ) {
// current c is not a delimiter, the first white space encountered is also not a delimeter
std::cerr << SC_CURRENT_FUNCTION << ": missing delimiter. Found " << c << ", expected one of " << delimiters << " at end of keyword " << str << ". File offset: " << _file.tellg() << std::endl;
abort();
}
return str.c_str();
}
/// search forward in the file for the end of the instance. Start position should
@@ -174,9 +180,8 @@ void sectionReader::locateAllInstances() {
}
instanceID sectionReader::readInstanceNumber() {
std::streampos start, end;
char c;
int digits = 0;
size_t digits = 0;
instanceID id = 0;
//find instance number ("# nnnn ="), where ' ' is any whitespace found by isspace()
@@ -193,25 +198,55 @@ instanceID sectionReader::readInstanceNumber() {
return 0;
}
skipWS();
start = _file.tellg();
// The largest instance ID yet supported is the maximum value of unsigned long long int
assert( std::numeric_limits<instanceID>::max() <= std::numeric_limits<unsigned long long int>::max() );
size_t instanceIDLength = std::numeric_limits<instanceID>::digits10 + 1;
char * buffer = new char( instanceIDLength + 1 ); // +1 for the terminating character
std::stringstream errorMsg;
do {
c = _file.get();
if( isdigit( c ) ) {
buffer[ digits ] = c; //copy the charcter into the buffer
digits++;
} else {
_file.unget();
break;
}
if( digits > instanceIDLength ) {
errorMsg << "A very large instance ID of string length greater then " << instanceIDLength << " found. Skipping data section " << _sectionID << ".";
_error->GreaterSeverity( SEVERITY_INPUT_ERROR );
_error->UserMsg( "A very large instance ID encountered" );
_error->DetailMsg( errorMsg.str() );
delete buffer;
return 0;
}
} while( _file.good() );
buffer[ digits ] = '\0'; //Append the terminating character
skipWS();
if( _file.good() && ( digits > 0 ) && ( _file.get() == '=' ) ) {
end = _file.tellg();
_file.seekg( start );
_file >> id;
_file.seekg( end );
id = strtoull( buffer, NULL, 10);
if( id == std::numeric_limits<instanceID>::max() ) {
//Handling those cases where although the number of digits is equal, but the id value is greater then equal to the maximum allowed value.
errorMsg << "A very large instance ID caused an overflow. Skipping data section " << _sectionID << ".";
_error->GreaterSeverity( SEVERITY_INPUT_ERROR );
_error->UserMsg( "A very large instance ID encountered" );
_error->DetailMsg( errorMsg.str() );
}
assert( id > 0 );
}
delete buffer;
return id;
}
@@ -220,7 +255,7 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg
const std::string & typeName, const std::string & schName, bool header ) {
char c;
const char * tName = 0, * sName = 0; //these are necessary since typeName and schName are const
std::string comment;
std::string comment, keyword;
Severity sev;
SDAI_Application_instance * inst = 0;
@@ -264,7 +299,8 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg
break;
default:
if( ( !header ) && ( typeName.size() == 0 ) ) {
tName = getDelimitedKeyword( ";( /\\" );
fillDelimitedKeyword( ";( /\\", keyword );
tName = keyword.c_str();
}
inst = reg->ObjCreate( tName, sName );
break;
@@ -290,7 +326,9 @@ STEPcomplex * sectionReader::CreateSubSuperInstance( const Registry * reg, insta
std::vector<std::string *> typeNames;
_file.get(); //move past the first '('
while( _file.good() && ( _file.peek() != ')' ) ) {
typeNames.push_back( new std::string( getDelimitedKeyword( ";( /\\" ) ) );
std::string keyword;
fillDelimitedKeyword( ";( /\\", keyword );
typeNames.push_back( new std::string( keyword ) );
if( typeNames.back()->empty() ) {
delete typeNames.back();
typeNames.pop_back();
+1 -1
View File
@@ -41,7 +41,7 @@ class SC_LAZYFILE_EXPORT sectionReader {
/** Get a keyword ending with one of delimiters.
*/
const char * getDelimitedKeyword( const char * delimiters );
void fillDelimitedKeyword( const char * delimiters, std::string &keyword );
/** Seek to the end of the current instance */
std::streampos seekInstanceEnd( instanceRefs ** refs );
+92 -68
View File
@@ -1,78 +1,102 @@
set(LIBSTEPCORE_SRCS
sdaiApplication_instance.cc
STEPcomplex.cc
STEPattribute.cc
STEPattribute.inline.cc
sdai.cc
sdaiSelect.cc
STEPaggregate.cc
STEPundefined.cc
STEPattributeList.cc
SingleLinkList.cc
SingleLinkList.inline.cc
Registry.inline.cc
ExpDict.cc
ExpDict.inline.cc
read_func.cc
collect.cc
complexlist.cc
entlist.cc
multlist.cc
orlist.cc
entnode.cc
non-ors.cc
match-ors.cc
trynext.cc
print.cc
instmgr.cc
mgrnode.cc
mgrnodearray.cc
mgrnodelist.cc
dispnode.cc
dispnodelist.cc
needFunc.cc
)
sdaiApplication_instance.cc
STEPcomplex.cc
STEPattribute.cc
STEPattribute.inline.cc
sdai.cc
sdaiSelect.cc
STEPaggregate.cc
STEPundefined.cc
STEPattributeList.cc
SingleLinkList.cc
SingleLinkList.inline.cc
Registry.inline.cc
ExpDict.cc
ExpDict.inline.cc
read_func.cc
collect.cc
complexlist.cc
entlist.cc
multlist.cc
orlist.cc
entnode.cc
non-ors.cc
match-ors.cc
trynext.cc
print.cc
instmgr.cc
mgrnode.cc
mgrnodearray.cc
mgrnodelist.cc
dispnode.cc
dispnodelist.cc
needFunc.cc
)
SET(SC_CLSTEPCORE_HDRS
baseType.h
complexSupport.h
dictdefs.h
ExpDict.h
read_func.h
Registry.h
sdaiApplication_instance.h
sdai.h
sdaiSelect.h
SingleLinkList.h
STEPaggregate.h
STEPattribute.h
STEPattributeList.h
STEPcomplex.h
STEPundefined.h
instmgr.h
mgrnode.h
mgrnodearray.h
mgrnodelist.h
dispnode.h
dispnodelist.h
needFunc.h
SubSuperIterators.h
)
set(SC_CLSTEPCORE_HDRS
baseType.h
complexSupport.h
dictdefs.h
ExpDict.h
read_func.h
Registry.h
sdaiApplication_instance.h
sdai.h
sdaiSelect.h
SingleLinkList.h
STEPaggregate.h
STEPattribute.h
STEPattributeList.h
STEPcomplex.h
STEPundefined.h
instmgr.h
mgrnode.h
mgrnodearray.h
mgrnodelist.h
dispnode.h
dispnodelist.h
needFunc.h
SubSuperIterators.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/cldai
${SC_SOURCE_DIR}/src/cleditor
${SC_SOURCE_DIR}/src/clutils
)
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/cldai
${SC_SOURCE_DIR}/src/cleditor
${SC_SOURCE_DIR}/src/clutils
)
SC_ADDLIB(stepcore "${LIBSTEPCORE_SRCS}" "steputils;stepdai;base")
if(HAVE_STD_THREAD)
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
set_target_properties(stepcore PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
SC_ADDEXEC(InstMgr_thread_safety_test "InstMgr_thread_safety_test.cc" "stepcore" )
set_target_properties(InstMgr_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
target_link_libraries(InstMgr_thread_safety_test "pthread" )
SC_ADDEXEC(Registry_thread_safety_test "Registry_thread_safety_test.cc" "stepcore" )
set_target_properties(Registry_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
target_link_libraries(Registry_thread_safety_test "pthread" )
SC_ADDEXEC(sdaiApplication_instance_thread_safety_test "sdaiApplication_instance_thread_safety_test.cc" "stepcore" )
set_target_properties(sdaiApplication_instance_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
target_link_libraries(sdaiApplication_instance_thread_safety_test "pthread" )
endif(HAVE_STD_THREAD)
install(FILES ${SC_CLSTEPCORE_HDRS}
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/clstepcore)
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/clstepcore)
if(SC_ENABLE_TESTING)
add_subdirectory(test)
endif(SC_ENABLE_TESTING)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
IF(SC_ENABLE_TESTING)
ADD_SUBDIRECTORY( test )
ENDIF(SC_ENABLE_TESTING)
+191 -479
View File
@@ -21,269 +21,143 @@
#include "sc_memmgr.h"
Explicit_item_id__set::Explicit_item_id__set( int defaultSize ) {
Dictionary_instance__set::Dictionary_instance__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new Explicit_item_id_ptr[_bufsize];
_buf = new Dictionary_instance_ptr[_bufsize];
_count = 0;
}
Dictionary_instance__set::~Dictionary_instance__set() {
delete[] _buf;
}
void Dictionary_instance__set::Check( int index ) {
Dictionary_instance_ptr * newbuf;
mtx.lock();
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Dictionary_instance_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Dictionary_instance_ptr ) );
delete[] _buf;
_buf = newbuf;
}
mtx.unlock();
}
void Dictionary_instance__set::Insert( Dictionary_instance_ptr v, int index ) {
Dictionary_instance_ptr * spot;
mtx.lock();
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Dictionary_instance_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
mtx.unlock();
}
void Dictionary_instance__set::Append( Dictionary_instance_ptr v ) {
Dictionary_instance_ptr * spot;
mtx.lock();
int index = _count;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Dictionary_instance_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
mtx.unlock();
}
void Dictionary_instance__set::Remove( int index ) {
mtx.lock();
if( 0 <= index && index < _count ) {
--_count;
Dictionary_instance_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Dictionary_instance_ptr ) );
}
mtx.unlock();
}
int Dictionary_instance__set::Index( Dictionary_instance_ptr v ) {
int index = -1;
mtx.lock();
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
index = i;
break;
}
}
mtx.unlock();
return index;
}
Dictionary_instance_ptr & Dictionary_instance__set::operator[]( int index ) {
mtx.lock();
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
Dictionary_instance_ptr & dip = _buf[index];
mtx.unlock();
return dip;
}
int Dictionary_instance__set::Count() {
return _count;
}
void Dictionary_instance__set::Clear() {
_count = 0;
}
///////////////////////////////////////////////////////////////////////////////
Explicit_item_id__set::Explicit_item_id__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
}
Explicit_item_id__set::~Explicit_item_id__set() {
delete[] _buf;
}
void Explicit_item_id__set::Check( int index ) {
Explicit_item_id_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Explicit_item_id_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Explicit_item_id_ptr ) );
delete[] _buf;
_buf = newbuf;
}
}
void Explicit_item_id__set::Insert( Explicit_item_id_ptr v, int index ) {
Explicit_item_id_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Explicit_item_id_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Explicit_item_id__set::Append( Explicit_item_id_ptr v ) {
int index = _count;
Explicit_item_id_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Explicit_item_id_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Explicit_item_id__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
Explicit_item_id_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Explicit_item_id_ptr ) );
}
}
int Explicit_item_id__set::Index( Explicit_item_id_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
Explicit_item_id_ptr & Explicit_item_id__set::operator[]( int index ) {
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int Explicit_item_id__set::Count() {
return _count;
}
void Explicit_item_id__set::Clear() {
_count = 0;
return ( Explicit_item_id_ptr & )Dictionary_instance__set::operator[]( index );
}
///////////////////////////////////////////////////////////////////////////////
Implicit_item_id__set::Implicit_item_id__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new Implicit_item_id_ptr[_bufsize];
_count = 0;
Implicit_item_id__set::Implicit_item_id__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
}
Implicit_item_id__set::~Implicit_item_id__set() {
delete[] _buf;
}
void Implicit_item_id__set::Check( int index ) {
Implicit_item_id_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Implicit_item_id_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Implicit_item_id_ptr ) );
delete[]_buf;
_buf = newbuf;
}
}
void Implicit_item_id__set::Insert( Implicit_item_id_ptr v, int index ) {
Implicit_item_id_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Implicit_item_id_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Implicit_item_id__set::Append( Implicit_item_id_ptr v ) {
int index = _count;
Implicit_item_id_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Implicit_item_id_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Implicit_item_id__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
Implicit_item_id_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Implicit_item_id_ptr ) );
}
}
int Implicit_item_id__set::Index( Implicit_item_id_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
Implicit_item_id_ptr & Implicit_item_id__set::operator[]( int index ) {
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int Implicit_item_id__set::Count() {
return _count;
}
void Implicit_item_id__set::Clear() {
_count = 0;
return ( Implicit_item_id_ptr & )Dictionary_instance__set::operator[]( index );
}
///////////////////////////////////////////////////////////////////////////////
Interface_spec__set::Interface_spec__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new Interface_spec_ptr[_bufsize];
_count = 0;
Interface_spec__set::Interface_spec__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
}
Interface_spec__set::~Interface_spec__set() {
delete[] _buf;
}
void Interface_spec__set::Check( int index ) {
Interface_spec_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Interface_spec_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Interface_spec_ptr ) );
delete[] _buf;
_buf = newbuf;
}
}
void Interface_spec__set::Insert( Interface_spec_ptr v, int index ) {
Interface_spec_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Interface_spec_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Interface_spec__set::Append( Interface_spec_ptr v ) {
int index = _count;
Interface_spec_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Interface_spec_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Interface_spec__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
Interface_spec_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Interface_spec_ptr ) );
}
}
int Interface_spec__set::Index( Interface_spec_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
Interface_spec_ptr & Interface_spec__set::operator[]( int index ) {
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int Interface_spec__set::Count() {
return _count;
}
void Interface_spec__set::Clear() {
_count = 0;
return ( Interface_spec_ptr & )Dictionary_instance__set::operator[]( index );
}
///////////////////////////////////////////////////////////////////////////////
@@ -322,18 +196,24 @@ Interface_spec::~Interface_spec() {
//////////////////////////////////////////////////////////////////////////////
void Schema::AddFunction( const std::string & f ) {
_function_list_mtx.lock();
_function_list.push_back( f );
_function_list_mtx.unlock();
}
void Schema::AddGlobal_rule( Global_rule_ptr gr ) {
// locking here is required to prevent _global_rules from initializing twice
_global_rules_mtx.lock();
if( _global_rules == 0 ) {
_global_rules = new Global_rule__set;
}
_global_rules->Append( gr );
_global_rules_mtx.unlock();
}
/// hope I did this right (MP) - was "not implemented"
void Schema::global_rules_( Global_rule__set_var & grs ) {
_global_rules_mtx.lock();
if( _global_rules ) {
if( _global_rules->Count() > 0 ) {
std::cerr << "In " << __FILE__ << ", Schema::global_rules_(): overwriting non-empty global rule set!" << std::endl;
@@ -341,10 +221,13 @@ void Schema::global_rules_( Global_rule__set_var & grs ) {
delete _global_rules;
}
_global_rules = grs;
_global_rules_mtx.unlock();
}
void Schema::AddProcedure( const std::string & p ) {
_procedure_list_mtx.lock();
_procedure_list.push_back( p );
_procedure_list_mtx.unlock();
}
/// the whole schema
@@ -478,6 +361,7 @@ void Schema::GenerateUseRefExpress( ostream & out ) const {
/// TYPE definitions
void Schema::GenerateTypesExpress( ostream & out ) const {
_typeList.mtxP->lock();
TypeDescItr tdi( _typeList );
tdi.ResetItr();
std::string tmp;
@@ -487,10 +371,12 @@ void Schema::GenerateTypesExpress( ostream & out ) const {
out << endl << td->GenerateExpress( tmp );
td = tdi.NextTypeDesc();
}
_typeList.mtxP->unlock();
}
/// Entity definitions
void Schema::GenerateEntitiesExpress( ostream & out ) const {
_entList.mtxP->lock();
EntityDescItr edi( _entList );
edi.ResetItr();
std::string tmp;
@@ -500,6 +386,7 @@ void Schema::GenerateEntitiesExpress( ostream & out ) const {
out << endl << ed->GenerateExpress( tmp );
ed = edi.NextEntityDesc();
}
_entList.mtxP->unlock();
}
///////////////////////////////////////////////////////////////////////////////
@@ -757,6 +644,7 @@ const char * EnumTypeDescriptor::GenerateExpress( std::string & buf ) const {
///////////////
// count is # of WHERE rules
if( _where_rules != 0 ) {
_where_rules->mtx.lock();
int all_comments = 1;
int count = _where_rules->Count();
for( int i = 0; i < count; i++ ) { // print out each UNIQUE rule
@@ -781,6 +669,7 @@ const char * EnumTypeDescriptor::GenerateExpress( std::string & buf ) const {
buf.append( ( *( _where_rules ) )[i]->label_() );
}
}
_where_rules->mtx.unlock();
}
buf.append( "END_TYPE;\n" );
@@ -827,6 +716,7 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
const EntityDescriptor * ed = 0;
_supertypes.mtxP->lock();
EntityDescItr edi_super( _supertypes );
edi_super.ResetItr();
ed = edi_super.NextEntityDesc();
@@ -845,9 +735,11 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
if( supertypes ) {
buf.append( ")" );
}
_supertypes.mtxP->unlock();
buf.append( ";\n" );
_explicitAttr.mtxP->lock();
AttrDescItr adi( _explicitAttr );
adi.ResetItr();
@@ -876,8 +768,10 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
}
ad = adi.NextAttrDesc();
}
_explicitAttr.mtxP->unlock();
/////////
_inverseAttr.mtxP->lock();
InverseAItr iai( _inverseAttr );
iai.ResetItr();
@@ -892,9 +786,11 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
buf.append( ia->GenerateExpress( sstr ) );
ia = iai.NextInverse_attribute();
}
_inverseAttr.mtxP->unlock();
///////////////
// count is # of UNIQUE rules
if( _uniqueness_rules != 0 ) {
_uniqueness_rules->mtx.lock();
count = _uniqueness_rules->Count();
for( i = 0; i < count; i++ ) { // print out each UNIQUE rule
if( !( *( _uniqueness_rules ) )[i]->_label.size() ) {
@@ -919,11 +815,13 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
buf.append( "\n" );
}
}
_uniqueness_rules->mtx.unlock();
}
///////////////
// count is # of WHERE rules
if( _where_rules != 0 ) {
_where_rules->mtx.lock();
all_comments = 1;
count = _where_rules->Count();
for( i = 0; i < count; i++ ) { // print out each UNIQUE rule
@@ -949,6 +847,7 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
buf.append( "\n" );
}
}
_where_rules->mtx.unlock();
}
buf.append( "END_ENTITY;\n" );
@@ -958,6 +857,7 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
const char * EntityDescriptor::QualifiedName( std::string & s ) const {
s.clear();
_supertypes.mtxP->lock();
EntityDescItr edi( _supertypes );
int count = 1;
@@ -970,6 +870,8 @@ const char * EntityDescriptor::QualifiedName( std::string & s ) const {
count++;
ed = edi.NextEntityDesc();
}
_supertypes.mtxP->unlock();
if( count > 1 ) {
s.append( "&" );
}
@@ -987,16 +889,18 @@ const TypeDescriptor * EntityDescriptor::IsA( const TypeDescriptor * td ) const
const EntityDescriptor * EntityDescriptor::IsA( const EntityDescriptor * other ) const {
const EntityDescriptor * found = 0;
const EntityDescLinkNode * link = ( const EntityDescLinkNode * )( GetSupertypes().GetHead() );
_supertypes.mtxP->lock();
const EntityDescLinkNode * link = ( const EntityDescLinkNode * )( _supertypes.GetHead() );
if( this == other ) {
return other;
found = other;
} else {
while( link && ! found ) {
found = link -> EntityDesc() -> IsA( other );
link = ( EntityDescLinkNode * ) link -> NextNode();
}
}
_supertypes.mtxP->unlock();
return found;
}
@@ -1025,96 +929,24 @@ Where_rule::~Where_rule() {
///////////////////////////////////////////////////////////////////////////////
Where_rule__list::Where_rule__list( int defaultSize ) {
_bufsize = defaultSize;
_buf = new Where_rule_ptr[_bufsize];
_count = 0;
Where_rule__list::Where_rule__list( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
}
Where_rule__list::~Where_rule__list() {
Clear();
delete[] _buf;
}
void Where_rule__list::Check( int index ) {
Where_rule_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Where_rule_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Where_rule_ptr ) );
delete[] _buf;
_buf = newbuf;
}
}
void Where_rule__list::Insert( Where_rule_ptr v, int index ) {
Where_rule_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Where_rule_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Where_rule__list::Append( Where_rule_ptr v ) {
int index = _count;
Where_rule_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Where_rule_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Where_rule__list::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
Where_rule_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Where_rule_ptr ) );
}
}
int Where_rule__list::Index( Where_rule_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
Where_rule_ptr & Where_rule__list::operator[]( int index ) {
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int Where_rule__list::Count() {
return _count;
return ( Where_rule_ptr & )Dictionary_instance__set::operator[]( index );
}
void Where_rule__list::Clear() {
mtx.lock();
for( int i = 0; i < _count ; i ++ ) {
delete _buf[i];
delete ( Where_rule_ptr )_buf[i];
}
_count = 0;
mtx.unlock();
}
///////////////////////////////////////////////////////////////////////////////
@@ -1134,96 +966,24 @@ Uniqueness_rule::~Uniqueness_rule() {
///////////////////////////////////////////////////////////////////////////////
Uniqueness_rule__set::Uniqueness_rule__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new Uniqueness_rule_ptr[_bufsize];
_count = 0;
Uniqueness_rule__set::Uniqueness_rule__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
}
Uniqueness_rule__set::~Uniqueness_rule__set() {
Clear();
delete[] _buf;
}
void Uniqueness_rule__set::Check( int index ) {
Uniqueness_rule_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Uniqueness_rule_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Uniqueness_rule_ptr ) );
delete[] _buf;
_buf = newbuf;
}
}
void Uniqueness_rule__set::Insert( Uniqueness_rule_ptr v, int index ) {
Uniqueness_rule_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Uniqueness_rule_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Uniqueness_rule__set::Append( Uniqueness_rule_ptr v ) {
int index = _count;
Uniqueness_rule_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Uniqueness_rule_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Uniqueness_rule__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
Uniqueness_rule_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Uniqueness_rule_ptr ) );
}
}
int Uniqueness_rule__set::Index( Uniqueness_rule_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
Uniqueness_rule_ptr & Uniqueness_rule__set::operator[]( int index ) {
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int Uniqueness_rule__set::Count() {
return _count;
return ( Uniqueness_rule_ptr & )Dictionary_instance__set::operator[]( index );
}
void Uniqueness_rule__set::Clear() {
mtx.lock();
for( int i = 0; i < _count; i ++ ) {
delete _buf[i];
delete ( Uniqueness_rule_ptr )_buf[i];
}
_count = 0;
mtx.unlock();
}
///////////////////////////////////////////////////////////////////////////////
@@ -1249,6 +1009,8 @@ Global_rule::~Global_rule() {
}
void Global_rule::entities_( const Entity__set_var & e ) {
// required to prevent potential double deletion
mtx.lock();
if( _entities ) {
if( _entities->EntryCount() > 0 ) {
std::cerr << "In " << __FILE__ << ", Global_rule::entities_(): overwriting non-empty entity set!" << std::endl;
@@ -1256,9 +1018,11 @@ void Global_rule::entities_( const Entity__set_var & e ) {
delete _entities;
}
_entities = e;
mtx.unlock();
}
void Global_rule::where_rules_( const Where_rule__list_var & wrl ) {
mtx.lock();
if( _where_rules ) {
if( _where_rules->Count() > 0 ) {
std::cerr << "In " << __FILE__ << ", Global_rule::where_rules_(): overwriting non-empty rule set!" << std::endl;
@@ -1266,99 +1030,29 @@ void Global_rule::where_rules_( const Where_rule__list_var & wrl ) {
delete _where_rules;
}
_where_rules = wrl;
mtx.unlock();
}
///////////////////////////////////////////////////////////////////////////////
Global_rule__set::Global_rule__set( int defaultSize ) {
_bufsize = defaultSize;
_buf = new Global_rule_ptr[_bufsize];
_count = 0;
Global_rule__set::Global_rule__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
}
Global_rule__set::~Global_rule__set() {
Clear();
delete[] _buf;
}
void Global_rule__set::Check( int index ) {
Global_rule_ptr * newbuf;
if( index >= _bufsize ) {
_bufsize = ( index + 1 ) * 2;
newbuf = new Global_rule_ptr[_bufsize];
memmove( newbuf, _buf, _count * sizeof( Global_rule_ptr ) );
delete[] _buf;
_buf = newbuf;
}
}
void Global_rule__set::Insert( Global_rule_ptr v, int index ) {
Global_rule_ptr * spot;
index = ( index < 0 ) ? _count : index;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Global_rule_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Global_rule__set::Append( Global_rule_ptr v ) {
int index = _count;
Global_rule_ptr * spot;
if( index < _count ) {
Check( _count + 1 );
spot = &_buf[index];
memmove( spot + 1, spot, ( _count - index )*sizeof( Global_rule_ptr ) );
} else {
Check( index );
spot = &_buf[index];
}
*spot = v;
++_count;
}
void Global_rule__set::Remove( int index ) {
if( 0 <= index && index < _count ) {
--_count;
Global_rule_ptr * spot = &_buf[index];
memmove( spot, spot + 1, ( _count - index )*sizeof( Global_rule_ptr ) );
}
}
int Global_rule__set::Index( Global_rule_ptr v ) {
for( int i = 0; i < _count; ++i ) {
if( _buf[i] == v ) {
return i;
}
}
return -1;
}
Global_rule_ptr & Global_rule__set::operator[]( int index ) {
Check( index );
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
return _buf[index];
}
int Global_rule__set::Count() {
return _count;
return ( Global_rule_ptr & )Dictionary_instance__set::operator[]( index );
}
void Global_rule__set::Clear() {
mtx.lock();
for( int i = 0; i < _count; i ++ ) {
delete _buf[i];
delete ( Global_rule_ptr )_buf[i];
}
_count = 0;
mtx.unlock();
}
@@ -1396,6 +1090,7 @@ const char * TypeDescriptor::GenerateExpress( std::string & buf ) const {
///////////////
// count is # of WHERE rules
if( _where_rules != 0 ) {
_where_rules->mtx.lock();
int all_comments = 1;
int count = _where_rules->Count();
for( int i = 0; i < count; i++ ) { // print out each UNIQUE rule
@@ -1420,6 +1115,7 @@ const char * TypeDescriptor::GenerateExpress( std::string & buf ) const {
buf.append( ( *( _where_rules ) )[i]->label_() );
}
}
_where_rules->mtx.unlock();
}
buf.append( "END_TYPE;\n" );
@@ -1704,15 +1400,20 @@ const TypeDescriptor * SelectTypeDescriptor::CanBe( const TypeDescriptor * other
return other;
}
TypeDescItr elements( GetElements() ) ;
const TypeDescriptor * rettd = 0;
const TypeDescriptorList & tl = GetElements();
tl.mtxP->lock();
TypeDescItr elements( tl ) ;
const TypeDescriptor * td = elements.NextTypeDesc();
while( td ) {
if( td -> CanBe( other ) ) {
return td;
rettd = td;
break;
}
td = elements.NextTypeDesc();
}
return 0;
tl.mtxP->unlock();
return rettd;
}
/**
@@ -1721,21 +1422,26 @@ const TypeDescriptor * SelectTypeDescriptor::CanBe( const TypeDescriptor * other
* type may be an element of a td for a select that is returned.
*/
const TypeDescriptor * SelectTypeDescriptor::CanBe( const char * other ) const {
TypeDescItr elements( GetElements() ) ;
const TypeDescriptor * td = 0;
// see if other is the select
if( !StrCmpIns( _name, other ) ) {
return this;
}
const TypeDescriptor * td = 0;
const TypeDescriptor * rettd = 0;
const TypeDescriptorList & tl = GetElements();
tl.mtxP->lock();
TypeDescItr elements( tl ) ;
// see if other is one of the elements
while( ( td = elements.NextTypeDesc() ) ) {
if( td -> CanBe( other ) ) {
return td;
rettd = td;
break;
}
}
return 0;
tl.mtxP->unlock();
return rettd;
}
/**
@@ -1758,21 +1464,27 @@ const TypeDescriptor * SelectTypeDescriptor::CanBe( const char * other ) const {
* from XX (A as B)").
*/
const TypeDescriptor * SelectTypeDescriptor::CanBeSet( const char * other, const char * schNm ) const {
TypeDescItr elements( GetElements() ) ;
const TypeDescriptorList & tl = GetElements();
tl.mtxP->lock();
TypeDescItr elements( tl ) ;
const TypeDescriptor * td = elements.NextTypeDesc();
const TypeDescriptor * rettd = 0;
while( td ) {
if( td->Type() == REFERENCE_TYPE && td->NonRefType() == sdaiSELECT ) {
// Just look at this level, don't look at my items (see intro).
if( td->CurrName( other, schNm ) ) {
return td;
rettd = td;
break;
}
} else if( td->CanBeSet( other, schNm ) ) {
return td;
rettd = td;
break;
}
td = elements.NextTypeDesc();
}
return 0;
tl.mtxP->unlock();
return rettd;
}
///////////////////////////////////////////////////////////////////////////////
+41 -78
View File
@@ -40,6 +40,7 @@ enum AggrBoundTypeEnum {
#include <baseType.h>
#include <dictdefs.h>
#include <Str.h>
#include <sc_mutex.h>
// defined and created in Registry.inline.cc
extern SC_CORE_EXPORT const TypeDescriptor * t_sdaiINTEGER;
@@ -63,6 +64,33 @@ class SC_CORE_EXPORT Dictionary_instance {
virtual ~Dictionary_instance();
};
typedef Dictionary_instance * Dictionary_instance_ptr;
///////////////////////////////////////////////////////////////////////////////
class SC_CORE_EXPORT Dictionary_instance__set {
public:
Dictionary_instance__set( int = 16 );
~Dictionary_instance__set();
Dictionary_instance_ptr & operator[]( int index );
virtual void Insert( Dictionary_instance_ptr, int index );
virtual void Append( Dictionary_instance_ptr );
virtual void Remove( int index );
virtual int Index( Dictionary_instance_ptr );
virtual int Count();
virtual void Clear();
sc_recursive_mutex mtx;
private:
virtual void Check( int index );
protected:
Dictionary_instance_ptr * _buf;
int _bufsize;
int _count;
};
///////////////////////////////////////////////////////////////////////////////
class SC_CORE_EXPORT TypeDescLinkNode : public SingleLinkNode {
@@ -286,25 +314,12 @@ class SC_CORE_EXPORT Referenced_item : public Explicit_item_id {
typedef Referenced_item * Referenced_item_ptr;
class SC_CORE_EXPORT Explicit_item_id__set {
class SC_CORE_EXPORT Explicit_item_id__set : public Dictionary_instance__set {
public:
Explicit_item_id__set( int = 16 );
~Explicit_item_id__set();
Explicit_item_id_ptr & operator[]( int index );
void Insert( Explicit_item_id_ptr, int index );
void Append( Explicit_item_id_ptr );
void Remove( int index );
int Index( Explicit_item_id_ptr );
int Count();
void Clear();
private:
void Check( int index );
private:
Explicit_item_id_ptr * _buf;
int _bufsize;
int _count;
};
typedef Explicit_item_id__set * Explicit_item_id__set_ptr;
@@ -338,25 +353,12 @@ typedef Implicit_item_id * Implicit_item_id_ptr;
// Implicit_item_id__set
///////////////////////////////////////////////////////////////////////////////
class SC_CORE_EXPORT Implicit_item_id__set {
class SC_CORE_EXPORT Implicit_item_id__set : public Dictionary_instance__set {
public:
Implicit_item_id__set( int = 16 );
~Implicit_item_id__set();
Implicit_item_id_ptr & operator[]( int index );
void Insert( Implicit_item_id_ptr, int index );
void Append( Implicit_item_id_ptr );
void Remove( int index );
int Index( Implicit_item_id_ptr );
int Count();
void Clear();
private:
void Check( int index );
private:
Implicit_item_id_ptr * _buf;
int _bufsize;
int _count;
};
typedef Implicit_item_id__set * Implicit_item_id__set_ptr;
@@ -423,25 +425,12 @@ class SC_CORE_EXPORT Interface_spec : public Dictionary_instance {
typedef Interface_spec * Interface_spec_ptr;
class SC_CORE_EXPORT Interface_spec__set {
class SC_CORE_EXPORT Interface_spec__set : public Dictionary_instance__set {
public:
Interface_spec__set( int = 16 );
~Interface_spec__set();
Interface_spec_ptr & operator[]( int index );
void Insert( Interface_spec_ptr, int index );
void Append( Interface_spec_ptr );
void Remove( int index );
int Index( Interface_spec_ptr );
int Count();
void Clear();
private:
void Check( int index );
private:
Interface_spec_ptr * _buf;
int _bufsize;
int _count;
};
typedef Interface_spec__set * Interface_spec__set_ptr;
@@ -497,31 +486,23 @@ class SC_CORE_EXPORT Where_rule : public Dictionary_instance {
typedef Where_rule * Where_rule_ptr;
class SC_CORE_EXPORT Where_rule__list {
class SC_CORE_EXPORT Where_rule__list : public Dictionary_instance__set {
public:
Where_rule__list( int = 16 );
~Where_rule__list();
Where_rule_ptr & operator[]( int index );
void Insert( Where_rule_ptr, int index );
void Append( Where_rule_ptr );
void Remove( int index );
int Index( Where_rule_ptr );
int Count();
void Clear();
private:
void Check( int index );
private:
Where_rule_ptr * _buf;
int _bufsize;
int _count;
};
typedef Where_rule__list * Where_rule__list_ptr;
typedef Where_rule__list_ptr Where_rule__list_var;
class SC_CORE_EXPORT Global_rule : public Dictionary_instance {
protected:
sc_mutex mtx;
public:
Express_id _name;
Entity__set_var _entities; // not implemented
@@ -566,25 +547,14 @@ class SC_CORE_EXPORT Global_rule : public Dictionary_instance {
typedef Global_rule * Global_rule_ptr;
class SC_CORE_EXPORT Global_rule__set {
class SC_CORE_EXPORT Global_rule__set : public Dictionary_instance__set {
public:
Global_rule__set( int = 16 );
~Global_rule__set();
Global_rule_ptr & operator[]( int index );
void Insert( Global_rule_ptr, int index );
void Append( Global_rule_ptr );
void Remove( int index );
int Index( Global_rule_ptr );
int Count();
void Clear();
private:
void Check( int index );
private:
Global_rule_ptr * _buf;
int _bufsize;
int _count;
};
typedef Global_rule__set * Global_rule__set_ptr;
@@ -630,25 +600,14 @@ class SC_CORE_EXPORT Uniqueness_rule : public Dictionary_instance {
typedef Uniqueness_rule * Uniqueness_rule_ptr;
class SC_CORE_EXPORT Uniqueness_rule__set {
class SC_CORE_EXPORT Uniqueness_rule__set : public Dictionary_instance__set {
public:
Uniqueness_rule__set( int = 16 );
~Uniqueness_rule__set();
Uniqueness_rule_ptr & operator[]( int index );
void Insert( Uniqueness_rule_ptr, int index );
void Append( Uniqueness_rule_ptr );
void Remove( int index );
int Index( Uniqueness_rule_ptr );
int Count();
void Clear();
private:
void Check( int index );
private:
Uniqueness_rule_ptr * _buf;
int _bufsize;
int _count;
};
typedef Uniqueness_rule__set * Uniqueness_rule__set_ptr;
@@ -676,6 +635,10 @@ class SC_CORE_EXPORT Schema : public Dictionary_instance {
Global_rule__set_var _global_rules;
sc_mutex _function_list_mtx; // required as _function_list is a vector
sc_mutex _procedure_list_mtx; // required as _procedure_list is a vector
sc_mutex _global_rules_mtx; // required in AddGlobal_rule function
public:
ModelContentsCreator CreateNewModelContents;
@@ -0,0 +1,229 @@
#include "instmgr.h"
#include "ExpDict.h"
#include "sdaiApplication_instance.h"
#include <baseType.h>
#ifdef HAVE_STD_THREAD
# include <thread>
#else
# error Need std::thread for this test!
#endif
const std::vector< std::string > dummyEDescNames { "A", "B", "C", "A", "B", "C", "D", "B", "A", "E", "C", "D", "B", "A", "E", "F", "F", "B", "C", "E", "F", "G", "C", "A", "G", "H", "I", "B", "A", "E", "F", "F", "C", "C", "E", "F" };
typedef std::vector< SDAI_Application_instance * > sdaiVec_t;
/// Deletes non-null elements of sdaiVec
void deleteSdaiVec( sdaiVec_t &sdaiVec ) {
int i, size = sdaiVec.size();
for( i = 0; i < size; i++ ) {
if( !sdaiVec[i]) {
delete sdaiVec[i];
}
}
}
void appendInstances( InstMgr * im, sdaiVec_t * sdaiVec, int offset, int stride, int limit ) {
SDAI_Application_instance * sai;
for( int i = offset; i < limit; i+=stride ) {
sai = new SDAI_Application_instance( i+1 );
sai->eDesc = new EntityDescriptor( dummyEDescNames[i].c_str(), ( Schema * ) NULL, LTrue, LFalse );
(*sdaiVec)[i] = sai;
im->Append( sai, completeSE );
}
}
void deleteInstances( InstMgr * im, sdaiVec_t * sdaiVec, int offset, int stride, int limit ) {
for( int i = offset; i < limit; i+=stride ) {
im->Delete( (*sdaiVec)[i] );
(*sdaiVec)[i] = 0;
}
}
bool compareKeywordCount ( InstMgr * mgr1, InstMgr * mgr2 ) {
int i, size = dummyEDescNames.size();
for( i = 0; i < size; i++ ) {
//some comparisions may be repeated.
const char * str = dummyEDescNames[i].c_str();
if( mgr1->EntityKeywordCount( str ) != mgr2->EntityKeywordCount( str ) ) {
std::cout << std::endl << "\tEntityKeywordCount mistmatch for " << str << ": " << mgr1->EntityKeywordCount( str ) << " and " << mgr2->EntityKeywordCount( str ) << std::endl;
return false;
}
}
return true;
}
/// Checks for similarity in the two InstMgr
bool compareInstMgr( InstMgr * mgr1, InstMgr * mgr2 ) {
if( mgr1->MaxFileId() != mgr2->MaxFileId() ) {
std::cout << std::endl << "\tMaxFileId not same: " << mgr1->MaxFileId() << " and " << mgr2->MaxFileId() << std::endl;
return false;
}
if( mgr1->InstanceCount() != mgr2->InstanceCount() ) {
std::cout << std::endl << "\tInstance count not same: " << mgr1->InstanceCount() << " and " << mgr2->InstanceCount() << std::endl;
return false;
}
if( !compareKeywordCount( mgr1, mgr2 ) ) {
return false;
}
return true;
}
/// Performs addition of different instances to the same InstMgr simultaneosly.
bool checkInstMgrAppendOnlyThreadSafety() {
InstMgr * imExpected = new InstMgr( 0 );
int size = dummyEDescNames.size();
//simulate the work done by two threads
sdaiVec_t sdaiVecOld( size );
appendInstances( imExpected, &sdaiVecOld, 0, 2, size );
appendInstances( imExpected, &sdaiVecOld, 1, 2, size );
std::cout << "Checking thread safety of InstMgr in Append Operation..." ;
int i, iterations = 1000;
for( i = 0 ; i < iterations; i++ ) {
InstMgr * imActual = new InstMgr( 0 );
sdaiVec_t sdaiVecNew( size );
std::thread first( appendInstances, imActual, &sdaiVecNew, 0, 2, size );
std::thread second( appendInstances, imActual, &sdaiVecNew, 1, 2, size );
first.join();
second.join();
bool success = compareInstMgr( imExpected, imActual );
delete imActual;
deleteSdaiVec( sdaiVecNew );
if( !success ) {
break;
}
}
bool pass = ( i = iterations );
if( pass ) {
std::cout << "...PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
}
std::cout << std::endl;
delete imExpected;
deleteSdaiVec( sdaiVecOld );
return pass;
}
/// Performs deletion of different instances to the same InstMgr simultaneosly.
bool checkInstMgrDeleteOnlyThreadSafety() {
InstMgr * imExpected = new InstMgr( 0 );
int size = dummyEDescNames.size();
//simulate the work done by two threads
sdaiVec_t sdaiVecOld( size );
appendInstances( imExpected, &sdaiVecOld, 0, 1, size );
deleteInstances( imExpected, &sdaiVecOld, 0, 2, size );
deleteInstances( imExpected, &sdaiVecOld, 1, 2, size );
std::cout << "Checking thread safety of InstMgr in Delete Operation..." ;
int i, iterations = 1000;
for( i = 0 ; i < iterations; i++ ) {
InstMgr * imActual = new InstMgr( 0 );
sdaiVec_t sdaiVecNew( size );
appendInstances( imActual, &sdaiVecNew, 0, 1, size ); //Preparetion
std::thread first( deleteInstances, imActual, &sdaiVecNew, 0, 2, size );
std::thread second( deleteInstances, imActual, &sdaiVecNew, 1, 2, size );
first.join();
second.join();
bool success = compareInstMgr( imExpected, imActual );
delete imActual;
deleteSdaiVec( sdaiVecNew );
if( !success ) {
break;
}
}
bool pass = ( i = iterations );
if( pass ) {
std::cout << "...PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
}
std::cout << std::endl;
delete imExpected;
deleteSdaiVec( sdaiVecOld );
return pass;
}
/// Performs addition and deletion of different instances to the same InstMgr simultaneosly.
bool checkInstMgrAppendDeleteThreadSafety() {
InstMgr * imExpected = new InstMgr( 0 );
int size = dummyEDescNames.size();
//simulate the work done by two threads
sdaiVec_t sdaiVecOld( size );
appendInstances( imExpected, &sdaiVecOld, 0, 2, size );
appendInstances( imExpected, &sdaiVecOld, 1, 2, size );
deleteInstances( imExpected, &sdaiVecOld, 0, 2, size );
std::cout << "Checking thread safety of InstMgr in Append-Delete Operation..." ;
int i, iterations = 1000;
for( i = 0 ; i < iterations; i++ ) {
InstMgr * imActual = new InstMgr( 0 );
sdaiVec_t sdaiVecNew( size );
appendInstances( imActual, &sdaiVecNew, 0, 2, size ); //Preparation
std::thread first( appendInstances, imActual, &sdaiVecNew, 1, 2, size );
std::thread second( deleteInstances, imActual, &sdaiVecNew, 0, 2, size );
first.join();
second.join();
bool success = compareInstMgr( imExpected, imActual );
delete imActual;
deleteSdaiVec( sdaiVecNew );
if( !success ) {
break;
}
}
bool pass = ( i == iterations );
if( pass ) {
std::cout << "...PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
}
std::cout << std::endl;
delete imExpected;
deleteSdaiVec( sdaiVecOld );
return pass;
}
int main( int , char ** ) {
bool pass = true;
assert( dummyEDescNames.size() % 4 == 0 && "dummyEDescNames should be a multiple of 4 ");
pass &= checkInstMgrAppendOnlyThreadSafety();
pass &= checkInstMgrDeleteOnlyThreadSafety();
pass &= checkInstMgrAppendDeleteThreadSafety();
if( pass ) {
exit( EXIT_SUCCESS );
}
exit( EXIT_FAILURE );
}
+5
View File
@@ -18,6 +18,7 @@
#include <sc_hash.h>
#include <Str.h>
#include <complexSupport.h>
#include <sc_mutex.h>
typedef struct Hash_Table * HashTable;
@@ -37,6 +38,10 @@ class SC_CORE_EXPORT Registry {
HashEntry cur_schema;
HashEntry cur_type;
mutable sc_recursive_mutex entityMtx; // will protect primodialSwamp, entity_cnt and all_ents_cnt
mutable sc_recursive_mutex schemaMtx; // will protect active_schemas
mutable sc_recursive_mutex typeMtx; // will protect active_types
// used by AddEntity() and RemoveEntity() to deal with renamings of an
// entity done in a USE or REFERENCE clause - see header comments in
// file Registry.inline.cc
+48 -7
View File
@@ -113,22 +113,28 @@ Registry::~Registry() {
void Registry::DeleteContents() {
// entities first
entityMtx.lock();
SC_HASHlistinit( primordialSwamp, &cur_entity );
while( SC_HASHlist( &cur_entity ) ) {
delete( EntityDescriptor * ) cur_entity.e->data;
}
entityMtx.unlock();
// schemas
schemaMtx.lock();
SC_HASHlistinit( active_schemas, &cur_schema );
while( SC_HASHlist( &cur_schema ) ) {
delete( Schema * ) cur_schema.e->data;
}
schemaMtx.unlock();
// types
typeMtx.lock();
SC_HASHlistinit( active_types, &cur_type );
while( SC_HASHlist( &cur_type ) ) {
delete( TypeDescriptor * ) cur_type.e->data;
}
typeMtx.unlock();
}
/**
@@ -145,12 +151,14 @@ const EntityDescriptor * Registry::FindEntity( const char * e, const char * schN
const SchRename * altlist;
char schformat[BUFSIZ], altName[BUFSIZ];
entityMtx.lock();
if( check_case ) {
entd = ( EntityDescriptor * )SC_HASHfind( primordialSwamp, ( char * )e );
} else {
entd = ( EntityDescriptor * )SC_HASHfind( primordialSwamp,
( char * )PrettyTmpName( e ) );
}
entityMtx.unlock();
if( entd && schNm ) {
// We've now found an entity. If schNm has a value, we must ensure we
// have a valid name.
@@ -181,24 +189,35 @@ const EntityDescriptor * Registry::FindEntity( const char * e, const char * schN
}
const Schema * Registry::FindSchema( const char * n, int check_case ) const {
const Schema * sc;
schemaMtx.lock();
if( check_case ) {
return ( const Schema * ) SC_HASHfind( active_schemas, ( char * ) n );
}
return ( const Schema * ) SC_HASHfind( active_schemas,
sc = ( const Schema * ) SC_HASHfind( active_schemas, ( char * ) n );
} else {
sc = ( const Schema * ) SC_HASHfind( active_schemas,
( char * )PrettyTmpName( n ) );
}
schemaMtx.unlock();
return sc;
}
const TypeDescriptor * Registry::FindType( const char * n, int check_case ) const {
const TypeDescriptor * td;
typeMtx.lock();
if( check_case ) {
return ( const TypeDescriptor * ) SC_HASHfind( active_types, ( char * ) n );
td = ( const TypeDescriptor * ) SC_HASHfind( active_types, ( char * ) n );
} else {
td = ( const TypeDescriptor * ) SC_HASHfind( active_types,
( char * )PrettyTmpName( n ) );
}
return ( const TypeDescriptor * ) SC_HASHfind( active_types,
( char * )PrettyTmpName( n ) );
typeMtx.unlock();
return td;
}
void Registry::ResetTypes() {
typeMtx.lock();
SC_HASHlistinit( active_types, &cur_type );
typeMtx.unlock();
}
const TypeDescriptor * Registry::NextType() {
@@ -209,19 +228,25 @@ const TypeDescriptor * Registry::NextType() {
}
void Registry::AddEntity( const EntityDescriptor & e ) {
entityMtx.lock();
SC_HASHinsert( primordialSwamp, ( char * ) e.Name(), ( EntityDescriptor * ) &e );
++entity_cnt;
++all_ents_cnt;
AddClones( e );
entityMtx.unlock();
}
void Registry::AddSchema( const Schema & d ) {
schemaMtx.lock();
SC_HASHinsert( active_schemas, ( char * ) d.Name(), ( Schema * ) &d );
schemaMtx.unlock();
}
void Registry::AddType( const TypeDescriptor & d ) {
typeMtx.lock();
SC_HASHinsert( active_types, ( char * ) d.Name(), ( TypeDescriptor * ) &d );
typeMtx.unlock();
}
/**
@@ -234,12 +259,14 @@ void Registry::AddType( const TypeDescriptor & d ) {
void Registry::AddClones( const EntityDescriptor & e ) {
const SchRename * alts = e.AltNameList();
entityMtx.lock();
while( alts ) {
SC_HASHinsert( primordialSwamp, ( char * )alts->objName(),
( EntityDescriptor * )&e );
alts = alts->next;
}
all_ents_cnt += uniqueNames( e.Name(), e.AltNameList() );
entityMtx.unlock();
}
/**
@@ -271,6 +298,7 @@ static int uniqueNames( const char * entnm, const SchRename * altlist ) {
}
void Registry::RemoveEntity( const char * n ) {
entityMtx.lock();
const EntityDescriptor * e = FindEntity( n );
struct Element tmp;
@@ -279,19 +307,24 @@ void Registry::RemoveEntity( const char * n ) {
}
tmp.key = ( char * ) n;
SC_HASHsearch( primordialSwamp, &tmp, HASH_DELETE ) ? --entity_cnt : 0;
entityMtx.unlock();
}
void Registry::RemoveSchema( const char * n ) {
struct Element tmp;
tmp.key = ( char * ) n;
schemaMtx.lock();
SC_HASHsearch( active_schemas, &tmp, HASH_DELETE );
schemaMtx.unlock();
}
void Registry::RemoveType( const char * n ) {
struct Element tmp;
tmp.key = ( char * ) n;
typeMtx.lock();
SC_HASHsearch( active_types, &tmp, HASH_DELETE );
typeMtx.unlock();
}
/**
@@ -301,17 +334,21 @@ void Registry::RemoveClones( const EntityDescriptor & e ) {
const SchRename * alts = e.AltNameList();
struct Element * tmp;
entityMtx.lock();
while( alts ) {
tmp = new Element;
tmp->key = ( char * ) alts->objName();
SC_HASHsearch( primordialSwamp, tmp, HASH_DELETE );
alts = alts->next;
}
entityMtx.unlock();
}
SDAI_Application_instance * Registry::ObjCreate( const char * nm, const char * schnm, int check_case ) const {
entityMtx.lock();
const EntityDescriptor * entd = FindEntity( nm, schnm, check_case );
entityMtx.unlock();
if( entd ) {
SDAI_Application_instance * se =
( ( EntityDescriptor * )entd ) -> NewSTEPentity();
@@ -337,7 +374,9 @@ int Registry::GetEntityCnt() {
}
void Registry::ResetEntities() {
entityMtx.lock();
SC_HASHlistinit( primordialSwamp, &cur_entity );
entityMtx.unlock();
}
@@ -349,7 +388,9 @@ const EntityDescriptor * Registry::NextEntity() {
}
void Registry::ResetSchemas() {
schemaMtx.lock();
SC_HASHlistinit( active_schemas, &cur_schema );
schemaMtx.unlock();
}
const Schema * Registry::NextSchema() {
@@ -0,0 +1,338 @@
#include <string>
#include <vector>
#include <iostream>
#ifdef HAVE_STD_THREAD
# include <thread>
#else
# error Need std::thread for this test!
#endif
#include "ExpDict.h"
#include "baseType.h"
#include "Registry.h"
enum Mode {
ENTITY = 0,
SCHEMA = 1,
TYPE = 2
};
const std::vector< std::string > modeNames { "ENTITY", "SCHEMA", "TYPE" };
/// Will be populated in the main function
std::vector< std::string > names;
/// Needed for constructing a Registry
void dummyInit( Registry & reg ) {
( void )reg;
}
/// Adds the elements at the specified indexes from the Registry
void addElements( Registry * reg, Mode mode, int llimit, int ulimit, int stride ) {
int i;
for( i = llimit; i < ulimit; i+=stride ) {
switch( mode ) {
case ENTITY:
reg->AddEntity( *( new EntityDescriptor( names[i].c_str(), ( Schema * ) NULL, LTrue, LFalse ) ) );
break;
case SCHEMA:
reg->AddSchema( *( new Schema( names[i].c_str() ) ) );
break;
case TYPE:
reg->AddType( *( new TypeDescriptor( names[i].c_str(), UNKNOWN_TYPE, ( Schema * )0, ( char * )0 ) ) );
break;
}
}
}
/// Removes the elements at the specified indexes from the Registry
void removeElements( Registry * reg, Mode mode, int llimit, int ulimit, int stride ) {
int i;
for( i = llimit; i < ulimit; i+=stride ) {
switch( mode ) {
case ENTITY:
reg->RemoveEntity( names[i].c_str() );
break;
case SCHEMA:
reg->RemoveSchema( names[i].c_str() );
break;
case TYPE:
reg->RemoveType( names[i].c_str() );
break;
}
}
}
/// compares the elements of the two registry. i.e. either an element should be in both the registries or none of them
bool haveSameElements( Registry * reg1, Registry * reg2 ) {
int i, size = names.size();
for( i = 0; i < size; i++ ) {
if( ( reg1->FindEntity( names[i].c_str() ) != NULL ) &&
( reg2->FindEntity( names[i].c_str() ) == NULL ) ) {
std::cout << std::endl << modeNames[ENTITY] << " " << names[i] << " expected but not present" << std::endl;
return false;
}
if( ( reg1->FindEntity( names[i].c_str() ) == NULL ) &&
( reg2->FindEntity( names[i].c_str() ) != NULL ) ) {
std::cout << std::endl << modeNames[ENTITY] << " " << names[i] << " not expected but present" << std::endl;
return false;
}
if( ( reg1->FindSchema( names[i].c_str() ) != NULL ) &&
( reg2->FindSchema( names[i].c_str() ) == NULL ) ) {
std::cout << std::endl << modeNames[SCHEMA] << " " << names[i] << " expected but not present" << std::endl;
return false;
}
if( ( reg1->FindSchema( names[i].c_str() ) == NULL ) &&
( reg2->FindSchema( names[i].c_str() ) != NULL ) ) {
std::cout << std::endl << modeNames[SCHEMA] << " " << names[i] << " not expected but present" << std::endl;
return false;
}
if( ( reg1->FindType( names[i].c_str() ) != NULL ) &&
( reg2->FindType( names[i].c_str() ) == NULL ) ) {
std::cout << std::endl << modeNames[TYPE] << " " << names[i] << " expected but not present" << std::endl;
return false;
}
if( ( reg1->FindType( names[i].c_str() ) == NULL ) &&
( reg2->FindType( names[i].c_str() ) != NULL ) ) {
std::cout << std::endl << modeNames[TYPE] << " " << names[i] << " not expected but present" << std::endl;
return false;
}
}
return true;
}
/// compares the given registries and reports any disparity
bool compareRegistry( Registry * reg1, Registry * reg2 ) {
if( reg1->GetEntityCnt() != reg2->GetEntityCnt() ) {
std::cout << std::endl << "\tentityCnt not same: " << reg1->GetEntityCnt() << " and " << reg2->GetEntityCnt() << std::endl;
return false;
}
if( reg1->GetFullEntCnt() != reg2->GetFullEntCnt() ) {
std::cout << std::endl << "\tall_ents_Cnt not same: " << reg1->GetFullEntCnt() << " and " << reg2->GetFullEntCnt() << std::endl;
return false;
}
if( !haveSameElements( reg1, reg2 ) ) {
return false;
}
return true;
}
/// For a particular mode adds elements to one Registry serially and to another Registry parallely.
/// It then compares the two Registry and reports any disparity.
bool checkRegistryAddOnlyThreadSafety( Mode mode ) {
int size = names.size();
Registry * regExpected = new Registry( dummyInit );
addElements( regExpected, mode, 0, size, 2 ); // Add even indexed elements
addElements( regExpected, mode, 1, size, 2 ); // Add odd indexed elements
std::cout << "Checking thread safety of Registry " << modeNames[( int )mode] << " Add Operations..." ;
int i, iterations = 10;
for( i = 0 ; i < iterations; i++ ) {
Registry * regActual = new Registry( dummyInit );
std::thread first( addElements, regActual, mode, 0, size, 2 );
std::thread second( addElements, regActual, mode, 1, size, 2 );
first.join();
second.join();
bool success = compareRegistry( regExpected, regActual );
delete regActual;
if( !success ) {
break;
}
}
bool pass = ( i == iterations );
if( pass ) {
std::cout << "...PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
}
std::cout << std::endl;
delete regExpected;
return pass;
}
/// For a particular mode removes elements to one Registry serially and to another Registry parallely.
/// It then compares the two Registry and reports any disparity.
bool checkRegistryRemoveOnlyThreadSafety( Mode mode ) {
int size = names.size();
Registry * regExpected = new Registry( dummyInit );
addElements( regExpected, mode, 0, size, 1 ); // Add all elements
removeElements( regExpected, mode, 0, size, 3 ); // remove one-third elements
removeElements( regExpected, mode, 1, size, 3 ); // remove another third elements
std::cout << "Checking thread safety of Registry " << modeNames[( int )mode] << " Remove Operations..." ;
int i, iterations = 10;
for( i = 0 ; i < iterations; i++ ) {
Registry * regActual = new Registry( dummyInit );
addElements( regActual, mode, 0, size, 1 );
std::thread first( removeElements, regActual, mode, 0, size, 3 );
std::thread second( removeElements, regActual, mode, 1, size, 3 );
first.join();
second.join();
bool success = compareRegistry( regExpected, regActual );
delete regActual;
if( !success ) {
break;
}
}
bool pass = ( i == iterations );
if( pass ) {
std::cout << "...PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
}
std::cout << std::endl;
delete regExpected;
return pass;
}
/// For a particular mode adds and removes elements to one Registry serially and to ther Registry parallely.
/// It then compares the two Registry and reports any disparity.
bool checkRegistryAddRemoveThreadSafety( Mode mode ) {
int size = names.size();
Registry * regExpected = new Registry( dummyInit );
addElements( regExpected, mode, 0, size, 2 ); // Add even indexed elements
addElements( regExpected, mode, 1, size, 2 ); // Add odd indexed elements
removeElements( regExpected, mode, 0, size, 2 ); // remove even indexed elements
std::cout << "Checking thread safety of Registry " << modeNames[( int )mode] << " Add-Remove Operations..." ;
int i, iterations = 10;
for( i = 0 ; i < iterations; i++ ) {
Registry * regActual = new Registry( dummyInit );
addElements( regActual, mode, 0, size, 2 );
std::thread first( addElements, regActual, mode, 1, size, 2 );
std::thread second( removeElements, regActual, mode, 0, size, 2 );
first.join();
second.join();
bool success = compareRegistry( regExpected, regActual );
delete regActual;
if( !success ) {
break;
}
}
bool pass = ( i == iterations );
if( pass ) {
std::cout << "...PASS!" << std::endl;
} else {
std::cout << "...FAIL!" << std::endl;
}
std::cout << std::endl;
delete regExpected;
return pass;
}
bool checkRegistryEntityAddOnlyThreadSafety() {
return checkRegistryAddOnlyThreadSafety( ENTITY );
}
bool checkRegistrySchemaAddOnlyThreadSafety() {
return checkRegistryAddOnlyThreadSafety( SCHEMA );
}
bool checkRegistryTypeAddOnlyThreadSafety() {
return checkRegistryAddOnlyThreadSafety( TYPE );
}
bool checkRegistryEntityRemoveOnlyThreadSafety() {
return checkRegistryRemoveOnlyThreadSafety( ENTITY );
}
bool checkRegistrySchemaRemoveOnlyThreadSafety() {
return checkRegistryRemoveOnlyThreadSafety( SCHEMA );
}
bool checkRegistryTypeRemoveOnlyThreadSafety() {
return checkRegistryRemoveOnlyThreadSafety( TYPE );
}
bool checkRegistryEntityAddRemoveThreadSafety() {
return checkRegistryAddRemoveThreadSafety( ENTITY );
}
bool checkRegistrySchemaAddRemoveThreadSafety() {
return checkRegistryAddRemoveThreadSafety( SCHEMA );
}
bool checkRegistryTypeAddRemoveThreadSafety() {
return checkRegistryAddRemoveThreadSafety( TYPE );
}
// populates the vector names[] with string of the form [A-Z]/[a-z]/[a-z]
void populateNamesVector() {
char ch[3];
ch[0] = 'A';
while( ch[0] <= 'Z')
{
ch[1] = 'a';
while( ch[1] <= 'z')
{
ch[2] = '0';
while( ch[2] <= '9')
{
string str( ch );
names.push_back( str );
ch[2]++;
}
ch[1]++;
}
ch[0]++;
}
}
int main( int , char ** ) {
populateNamesVector();
bool pass = true;
pass &= checkRegistryEntityAddOnlyThreadSafety();
pass &= checkRegistryEntityRemoveOnlyThreadSafety();
pass &= checkRegistryEntityAddRemoveThreadSafety();
pass &= checkRegistrySchemaAddOnlyThreadSafety();
pass &= checkRegistrySchemaRemoveOnlyThreadSafety();
pass &= checkRegistrySchemaAddRemoveThreadSafety();
pass &= checkRegistryTypeAddOnlyThreadSafety();
pass &= checkRegistryTypeRemoveOnlyThreadSafety();
pass &= checkRegistryTypeAddRemoveThreadSafety();
if( pass ) {
exit( EXIT_SUCCESS );
}
exit( EXIT_FAILURE );
}
+25 -8
View File
@@ -38,14 +38,7 @@ STEPaggregate::STEPaggregate() {
}
STEPaggregate::~STEPaggregate() {
STEPnode * node;
node = ( STEPnode * ) head;
while( node ) {
head = node->NextNode();
delete node;
node = ( STEPnode * ) head;
}
// Left to the superclass
}
STEPaggregate & STEPaggregate::ShallowCopy( const STEPaggregate & a ) {
@@ -391,6 +384,7 @@ SingleLinkNode * GenericAggregate::NewNode() {
STEPaggregate & GenericAggregate::ShallowCopy( const STEPaggregate & a ) {
Empty();
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
SingleLinkNode * next = a.GetHead();
SingleLinkNode * copy;
@@ -399,6 +393,8 @@ STEPaggregate & GenericAggregate::ShallowCopy( const STEPaggregate & a ) {
AddNode( copy );
next = next->NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -579,11 +575,14 @@ Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err,
STEPaggregate & EntityAggregate::ShallowCopy( const STEPaggregate & a ) {
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
const EntityNode * tmp = ( const EntityNode * ) a.GetHead();
while( tmp ) {
AddNode( new EntityNode( tmp -> node ) );
tmp = ( const EntityNode * ) tmp -> NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -817,12 +816,15 @@ Severity SelectAggregate::ReadValue( istream & in, ErrorDescriptor * err,
STEPaggregate & SelectAggregate::ShallowCopy( const STEPaggregate & a ) {
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
const SelectNode * tmp = ( const SelectNode * ) a.GetHead();
while( tmp ) {
AddNode( new SelectNode( tmp -> node ) );
tmp = ( const SelectNode * ) tmp -> NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -937,6 +939,7 @@ StringAggregate::~StringAggregate() {
STEPaggregate & StringAggregate::ShallowCopy( const STEPaggregate & a ) {
Empty();
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
SingleLinkNode * next = a.GetHead();
SingleLinkNode * copy;
@@ -945,6 +948,8 @@ STEPaggregate & StringAggregate::ShallowCopy( const STEPaggregate & a ) {
AddNode( copy );
next = next->NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -1042,6 +1047,7 @@ BinaryAggregate::~BinaryAggregate() {
STEPaggregate & BinaryAggregate::ShallowCopy( const STEPaggregate & a ) {
Empty();
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
SingleLinkNode * next = a.GetHead();
SingleLinkNode * copy;
@@ -1050,6 +1056,8 @@ STEPaggregate & BinaryAggregate::ShallowCopy( const STEPaggregate & a ) {
AddNode( copy );
next = next->NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -1142,6 +1150,7 @@ void BinaryNode::STEPwrite( ostream & out ) {
/// COPY
STEPaggregate & EnumAggregate::ShallowCopy( const STEPaggregate & a ) {
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
const EnumNode * tmp = ( const EnumNode * ) a.GetHead();
EnumNode * to;
@@ -1151,6 +1160,8 @@ STEPaggregate & EnumAggregate::ShallowCopy( const STEPaggregate & a ) {
AddNode( to );
tmp = ( const EnumNode * ) tmp -> NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -1306,6 +1317,7 @@ SingleLinkNode * RealAggregate::NewNode() {
// COPY
STEPaggregate & RealAggregate::ShallowCopy( const STEPaggregate & a ) {
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
const RealNode * tmp = ( const RealNode * ) a.GetHead();
RealNode * to;
@@ -1315,6 +1327,8 @@ STEPaggregate & RealAggregate::ShallowCopy( const STEPaggregate & a ) {
AddNode( to );
tmp = ( const RealNode * ) tmp -> NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
@@ -1339,6 +1353,7 @@ SingleLinkNode * IntAggregate::NewNode() {
/// COPY
STEPaggregate & IntAggregate::ShallowCopy( const STEPaggregate & a ) {
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
const IntNode * tmp = ( const IntNode * ) a.GetHead();
IntNode * to;
@@ -1348,6 +1363,8 @@ STEPaggregate & IntAggregate::ShallowCopy( const STEPaggregate & a ) {
AddNode( to );
tmp = ( const IntNode * ) tmp -> NextNode();
}
a.mtxP->unlock();
if( head ) {
_null = 0;
} else {
+15 -11
View File
@@ -606,7 +606,7 @@ void STEPattribute::ShallowCopy( const STEPattribute * sa ) {
_derive = sa->_derive;
_redefAttr = sa->_redefAttr;
if( _redefAttr ) {
_redefAttr->ShallowCopy( sa );
ShallowCopy( _redefAttr );
}
//Should we just use memcpy()? That would be a true shallowCopy
switch( sa->NonRefType() ) {
@@ -750,22 +750,18 @@ Severity STEPattribute::set_null() {
case REFERENCE_TYPE:
case GENERIC_TYPE:
cerr << "Internal error: " << __FILE__ << __LINE__
<< "\n" << _POC_ "\n";
cerr << "Internal error: " << __FILE__ << ":" << __LINE__ << "\n" << _POC_ "\n";
return SEVERITY_BUG;
case UNKNOWN_TYPE:
default: {
default:
ptr.u -> set_null();
char errStr[BUFSIZ];
errStr[0] = '\0';
sprintf( errStr, " Warning: attribute '%s : %s : %d' - %s.\n",
Name(), TypeName(), Type(),
"Don't know how to make attribute NULL" );
_error.AppendToDetailMsg( errStr );
std::stringstream err;
err << " Warning: attribute '" << Name() << " : " << TypeName() << " : ";
err << Type() << "' - " << "Don't know how to make attribute NULL" << std::endl;
_error.AppendToDetailMsg( err.str() );
_error.GreaterSeverity( SEVERITY_WARNING );
return SEVERITY_WARNING;
}
}
if( Nullable() ) {
return SEVERITY_NULL;
@@ -1052,6 +1048,14 @@ bool operator == ( const STEPattribute & a1, const STEPattribute & a2 ) {
return false;
}
/** evaluate the equality of two attributes
* ignores _error and refCount, since those are ancillary
* \return true if not equal
*/
bool operator != ( const STEPattribute & a1, const STEPattribute & a2 ) {
return !( a1 == a2 );
}
/// return true if the attr descriptor is identical
bool sameADesc( const STEPattribute & a1, const STEPattribute & a2 ) {
return a1.aDesc == a2.aDesc;
+3 -5
View File
@@ -262,13 +262,11 @@ class SC_CORE_EXPORT STEPattribute {
STEPattribute( const class AttrDescriptor & d, SCLundefined * p );
/// return true if attr types and values match
friend bool operator == ( const STEPattribute & a1, const STEPattribute & a2 );
friend bool operator != ( const STEPattribute & a1, const STEPattribute & a2 ) {
return !( a1 == a2 );
}
SC_CORE_EXPORT friend bool operator == ( const STEPattribute & a1, const STEPattribute & a2 );
SC_CORE_EXPORT friend bool operator != ( const STEPattribute & a1, const STEPattribute & a2 );
/// return true if aDesc's match (behavior of old operator==)
friend bool sameADesc ( const STEPattribute & a1, const STEPattribute & a2 );
SC_CORE_EXPORT friend bool sameADesc ( const STEPattribute & a1, const STEPattribute & a2 );
};
#endif
+8 -1
View File
@@ -30,6 +30,7 @@ STEPattributeList::~STEPattributeList() {
STEPattribute & STEPattributeList::operator []( int n ) {
int x = 0;
mtxP->lock();
AttrListNode * a = ( AttrListNode * )head;
int cnt = EntryCount();
if( n < cnt ) {
@@ -39,12 +40,15 @@ STEPattribute & STEPattributeList::operator []( int n ) {
}
}
if( a ) {
return *( a->attr );
STEPattribute * attr = a->attr;
mtxP->unlock();
return *( attr );
}
// else
cerr << "\nERROR in STEP Core library: " << __FILE__ << ":"
<< __LINE__ << "\n" << _POC_ << "\n\n";
mtxP->unlock();
return *( STEPattribute * ) 0;
}
@@ -53,11 +57,13 @@ int STEPattributeList::list_length() {
}
void STEPattributeList::push( STEPattribute * a ) {
mtxP->lock();
AttrListNode * a2 = ( AttrListNode * )head;
// if the attribute already exists in the list, don't push it
while( a2 ) {
if( *a == *( a2 -> attr ) ) {
mtxP->unlock();
return;
}
a2 = ( AttrListNode * )( a2->next );
@@ -65,4 +71,5 @@ void STEPattributeList::push( STEPattribute * a ) {
a->incrRefCount();
AttrListNode * saln = new AttrListNode( a );
AppendNode( saln );
mtxP->unlock();
}
+53 -16
View File
@@ -64,6 +64,7 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
bool invalid = false, outOfOrder = false;
// Splice out the invalid names from our list:
ents->sharedMtxP->lock();
while( eptr ) {
enext = eptr->next;
enDesc = _registry->FindEntity( *eptr, schnm );
@@ -95,10 +96,13 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
}
eptr->next = NULL;
// must set eptr->next to NULL or next line would del entire list
eptr->sharedMtxP = NULL;
// must set eptr->sharedMtxP to NULL or the sharedMtxP for the EntNode link-list will get deleted
delete eptr;
}
eptr = enext;
}
ents->sharedMtxP->unlock();
// If we changed the name of any of the entities, resort:
if( outOfOrder ) {
@@ -129,20 +133,25 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
"Entity combination does not represent a legal complex entity" );
cerr << "ERROR: Could not create instance of the following complex"
<< " entity:" << endl;
ents->sharedMtxP->lock();
eptr = ents;
while( eptr ) {
cerr << *eptr << endl;
eptr = eptr->next;
}
cerr << endl;
ents->sharedMtxP->unlock();
return;
}
// Finally, build what we can:
ents->sharedMtxP->lock();
BuildAttrs( *ents );
for( eptr = ents->next; eptr; eptr = eptr->next ) {
AddEntityPart( *eptr );
}
ents->sharedMtxP->unlock();
AssignDerives();
delete ents;
}
@@ -170,9 +179,13 @@ void STEPcomplex::AssignDerives() {
AttrDescLinkNode * attrPtr;
const AttrDescriptor * ad;
// Even though the following is an interation on sc, we dont
// use the STEPcomplex mutex since we are assuming that no node
// can be removed or inserted between two
while( scomp1 && scomp1->eDesc ) {
a = 0;
attrList = &( scomp1->eDesc->ExplicitAttr() );
attrList->mtxP->lock();
attrPtr = ( AttrDescLinkNode * )attrList->GetHead();
// assign nm to be derived attr
@@ -188,18 +201,19 @@ void STEPcomplex::AssignDerives() {
} else {
attrNm = nm;
}
scomp2 = head;
while( scomp2 && !a ) {
if( scomp1 != scomp2 ) {
scomp2->MakeDerived( attrNm );
a = scomp2->GetSTEPattribute( attrNm );
}
scomp2 = head; //locked earlier
// If we had used the generic hand-over-hand fine grain
// locking, the following loop could have caused a deadlock.
while( scomp2 && !a && ( scomp1 != scomp2 ) ) {
scomp2->MakeDerived( attrNm );
a = scomp2->GetSTEPattribute( attrNm );
scomp2 = scomp2->sc;
}
}
// increment attr
attrPtr = ( AttrDescLinkNode * )attrPtr->NextNode();
}
attrList->mtxP->unlock();
scomp1 = scomp1->sc;
}
}
@@ -215,7 +229,7 @@ void STEPcomplex::AddEntityPart( const char * name ) {
scomplex = new STEPcomplex( _registry, STEPfile_id );
scomplex->BuildAttrs( name );
if( scomplex->eDesc ) {
scomplex->head = this;
scomplex->head = this; // no locking here as the only the current thread will have the copy
AppendEntity( scomplex );
} else {
cout << scomplex->_error.DetailMsg() << endl;
@@ -226,14 +240,16 @@ void STEPcomplex::AddEntityPart( const char * name ) {
STEPcomplex * STEPcomplex::EntityPart( const char * name, const char * currSch ) {
STEPcomplex * scomp = head;
// No locking in this loop as remove insert operaations are not allowed
while( scomp ) {
if( scomp->eDesc ) {
if( scomp->eDesc->CurrName( name, currSch ) ) {
return scomp;
}
} else
} else {
cout << "Bug in STEPcomplex::EntityPart(): entity part has "
<< "no EntityDescriptor\n";
}
scomp = scomp->sc;
}
return 0;
@@ -268,11 +284,19 @@ Severity STEPcomplex::ValidLevel( ErrorDescriptor * error, InstMgr * im,
}
void STEPcomplex::AppendEntity( STEPcomplex * stepc ) {
if( sc ) {
sc->AppendEntity( stepc );
} else {
sc = stepc;
// We use the assumption that no remove / insert operation is there.
// Hence is locking is required only at the last node.
if( !sc ) {
// We use the double checking. This safaly eliminates the locking of internal nodes
mtx.lock();
if( !sc ) {
sc = stepc;
mtx.unlock();
return;
} // else another node has just appended a new node
mtx.unlock();
}
sc->AppendEntity( stepc );
}
// READ
@@ -448,13 +472,13 @@ void STEPcomplex::BuildAttrs( const char * s ) {
//////////////////////////////////////////////
STEPattribute * a = 0;
attrList->mtxP->lock();
AttrDescLinkNode * attrPtr = ( AttrDescLinkNode * )attrList->GetHead();
while( attrPtr != 0 ) {
const AttrDescriptor * ad = attrPtr->AttrDesc();
if( ( ad->Derived() ) != LTrue ) {
mtx.lock(); // To protect _attr_data_list and attributes
switch( ad->NonRefType() ) {
case INTEGER_TYPE:
integer_data = new SDAI_Integer;
@@ -535,10 +559,14 @@ void STEPcomplex::BuildAttrs( const char * s ) {
}
a -> set_null();
attributes.mtxP->lock();
attributes.push( a );
attributes.mtxP->unlock();
mtx.unlock();
}
attrPtr = ( AttrDescLinkNode * )attrPtr->NextNode();
}
attrList->mtxP->unlock();
} else {
_error.AppendToDetailMsg( "Entity does not exist.\n" );
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
@@ -592,14 +620,19 @@ void STEPcomplex::WriteExtMapEntities( ostream & out, const char * currSch ) {
std::string tmp;
out << StrToUpper( EntityName( currSch ), tmp );
out << "(";
int n = attributes.list_length();
mtx.lock(); // Protects attributes
attributes.mtxP->lock();
int n = attributes.list_length();
for( int i = 0 ; i < n; i++ ) {
( attributes[i] ).STEPwrite( out, currSch );
if( i < n - 1 ) {
out << ",";
}
}
attributes.mtxP->unlock();
mtx.unlock();
out << ")\n";
if( sc ) {
sc->WriteExtMapEntities( out, currSch );
@@ -614,14 +647,18 @@ const char * STEPcomplex::WriteExtMapEntities( std::string & buf, const char * c
buf.append( tmp );
buf.append( "i" );
mtx.lock();
attributes.mtxP->lock();
int n = attributes.list_length();
for( int i = 0 ; i < n; i++ ) {
buf.append( attributes[i].asStr( currSch ) );
if( i < n - 1 ) {
buf.append( "," );
}
}
attributes.mtxP->unlock();
mtx.unlock();
buf.append( ")\n" );
if( sc ) {

Some files were not shown because too many files have changed in this diff Show More