diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..3f51885 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,46 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/../../../../Temp/Includes/", + // "${workspaceFolder}/../includes/**", + // "${workspaceFolder}/../includes/loupe/Includes/", + // "${workspaceFolder}/Poly/**", + "C:/BrAutomation/AS410/AS/gnuinst/V6.3.0/4.9/i686-elf/include" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + // "_SG4" + ], + "windowsSdkVersion": "10.0.17763.0", + "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-msvc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + }, + { + "name": "Mac", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/../includes/**", + "${workspaceFolder}/../includes/loupe/Includes/", + "${workspaceFolder}/Poly/**" + ], + "defines": [], + "macFrameworkPath": [ + "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "c17", + "cppStandard": "c++98", + "intelliSenseMode": "macos-clang-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b74b1c3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,61 @@ +{ + "files.associations": { + "*.h": "c", + "*.tcc": "c", + "cctype": "c", + "clocale": "c", + "cmath": "c", + "cstddef": "c", + "cstdio": "c", + "cstdlib": "c", + "cstring": "c", + "ctime": "c", + "cwchar": "c", + "cwctype": "c", + "exception": "c", + "iosfwd": "c", + "istream": "c", + "limits": "c", + "memory": "c", + "new": "c", + "ostream": "c", + "stdexcept": "c", + "streambuf": "c", + "functional": "c", + "hashtable": "c", + "tuple": "c", + "type_traits": "c", + "unordered_map": "c", + "utility": "c", + "typeinfo": "c", + "algorithm": "c", + "atomic": "c", + "compare": "c", + "concepts": "c", + "cstdint": "c", + "initializer_list": "c", + "ios": "c", + "iterator": "c", + "list": "c", + "locale": "c", + "string": "c", + "system_error": "c", + "vector": "c", + "xfacet": "c", + "xhash": "c", + "xiosbase": "c", + "xlocale": "c", + "xlocbuf": "c", + "xlocinfo": "c", + "xlocmes": "c", + "xlocmon": "c", + "xlocnum": "c", + "xloctime": "c", + "xmemory": "c", + "xstddef": "c", + "xstring": "c", + "xtr1common": "c", + "xutility": "c" + }, + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" +} \ No newline at end of file diff --git a/ANSIC.lby b/ANSIC.lby index 23bdc1c..f8f0378 100644 --- a/ANSIC.lby +++ b/ANSIC.lby @@ -1,5 +1,5 @@  - + RevisionHistory.txt @@ -15,8 +15,10 @@ varVariableWatch.c variableBrowser.c varRefresh.c - varToolsInternal.h - + varToolsInternal.h + varCache.h + varCache.cpp + diff --git a/varCache.cpp b/varCache.cpp new file mode 100644 index 0000000..6680870 --- /dev/null +++ b/varCache.cpp @@ -0,0 +1,212 @@ +/******************************************************************* + * COPYRIGHT -- + ******************************************************************** + * Library: VarTools + * File: varRefresh.c + * Author: Lawrence + * Created: April 9, 2020 + ******************************************************************** + * Implementation of library VarTools + ********************************************************************/ +unsigned long bur_heap_size = 0xFFFFFF; + +#include +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "varToolsInternal.h" +#include "VarTools.h" + +#ifdef __cplusplus +}; +#endif + +#include "varCache.h" +#include +#include +#include "string.h" + +using namespace varTools; +using namespace std; + +Cache::Cache(void) +{ +} + +Cache::~Cache() +{ +} + + +///////////////////////////////// +// DEBUG +///////////////////////////////// + +size_t Cache::size() { + return _cache.size(); +} + +size_t Cache::capacity() { + return _cache.capacity(); +} + +void Cache::clear() { + auto it = _cache.begin(); + while (it != _cache.end()) + { + // remove cache items that do not have alias + if (it->alias.empty()) + { + // `erase()` invalidates the iterator, use returned iterator + it = _cache.erase(it); + } + // Notice that the iterator is incremented only on the else part + else { + // If we can not remove cache item, clean it instead + it->address = 0; + it->authorization.clear(); + it->dimension = 0; + //it->lastAccessed = 0; + it->length = 0; + it->subscribers.clear(); + it->type = VAR_TYPE_STRUCT; + it->value.clear(); + + ++it; + } + } +} + +void Cache::forceClear() { + _cache.clear(); // Note: This may not resize vector +} + + +//////////////////////////////// +// PUBLIC +//////////////////////////////// + + +const char* Cache::getValue(char* varName) { + cacheItem_typ* cacheItem = _getCacheItem(varName); + if(!cacheItem) cacheItem = _addVariable(varName); + _updateCacheItem(cacheItem); + return cacheItem->value.c_str(); +} + +const char* Cache::getInfo(char* varName, varVariable_typ& var) { + cacheItem_typ* cacheItem = _getCacheItem(varName); + if(!cacheItem) cacheItem = _addVariable(varName); + _updateCacheItem(cacheItem); + var.address = (unsigned long)cacheItem->address; + var.dataType = cacheItem->type; + var.dimension = cacheItem->dimension; + var.length = cacheItem->length; + strncpy(var.name, cacheItem->variable.c_str(), sizeof(var.name)-1); + strncpy(var.value, cacheItem->value.c_str(), sizeof(var.value)-1); + return cacheItem->value.c_str(); +} + +void Cache::addAlias(char* varName, char* alias) { + cacheItem_typ* cacheItem = _getCacheItem(varName); + if(!cacheItem) { + cacheItem = _addVariable(varName, alias); + } + else { + cacheItem->alias = alias; + } +} + +void Cache::subscribe(char* varName, cacheSubscribeLink_typ& link) { + +} + +void Cache::subscribe(varVariable_typ& var, cacheSubscribeLink_typ& link) { + +} + +void Cache::addVariable(char* varName) { + cacheItem_typ* cacheItem = _getCacheItem(varName); + if(!cacheItem) { + cacheItem = _addVariable(varName); + } +} + +bool Cache::inCache(char* varName) { + cacheItem_typ* cacheItem = _getCacheItem(varName); + return cacheItem != NULL; +} + +/////////////////////////////////// +// PRIVATE +////////////////////////////////// + +cacheItem_typ *Cache::_addVariable(char *varName) +{ + cacheItem_typ cacheItem; + cacheItem.variable = varName; + _updateCacheItem(&cacheItem); + + switch (_sortMode) + { + case CACHE_SORT_CONTINUOS: + // TODO: Implement + // We need to add in alphabetic order + break; + + case CACHE_SORT_COMMAND: + _isSorted = false; + // Fall through so we add item to cache, unsorted + + case CACHE_SORT_NONE: + default: + _cache.push_back(cacheItem); + break; + } +} + +cacheItem_typ *Cache::_addVariable(char *varName, char *alias) +{ + varTools::cacheItem_typ *cacheItem = _addVariable(varName); + cacheItem->alias = alias; +} + +cacheItem_typ *Cache::_getCacheItem(char *varName) +{ + // auto is_match = [](cacheItem_typ i){ return (i.variable == varName) || (i.alias == varName); }; + auto is_match = [](cacheItem_typ i){ return (i.variable == "varName"); }; + auto it = find_if(_cache.begin(), _cache.end(), is_match); + return it == _cache.end() ? NULL : &(*it); +} + +void Cache::_updateCacheItem(cacheItem_typ* item) +{ + varVariable_typ var = {}; + + if (item->address) + { + var.address = (unsigned long)item->address; + var.dataType = (unsigned long)item->type; + var.length = item->length; + } + else + { + strncpy(var.name, item->variable.c_str(), sizeof(var.name) - 1); + } + + varGetValue((unsigned long)&var); + + item->address = (void*)var.address; + item->value = var.value; + item->type = (VAR_TYPE_enum)var.dataType; + item->length = var.length; + item->dimension = var.dimension; + item->lastAccessed = _getCurrentTime(); +} + +cacheTime Cache::_getCurrentTime(void) +{ + return 0; // TODO: Populated this. Maybe just use ms after boot. clock_ms? +} diff --git a/varCache.h b/varCache.h new file mode 100644 index 0000000..3f8d00a --- /dev/null +++ b/varCache.h @@ -0,0 +1,106 @@ +/******************************************************************* + * COPYRIGHT -- + ******************************************************************** + * Library: VarTools + * File: varRefresh.c + * Author: Lawrence + * Created: April 9, 2020 + ******************************************************************** + * Implementation of library VarTools + ********************************************************************/ + +// varCache.h +#ifndef VAR_CACHE_H // include guard +#define VAR_CACHE_H + +//unsigned long bur_heap_size = 0xFFFFFF; + +#include +#ifdef __cplusplus + extern "C" + { +#endif + +#include "varToolsInternal.h" +#include "VarTools.h" + +#ifdef __cplusplus + }; +#endif + + +#include +#include + +namespace varTools +{ + typedef unsigned long cacheTime; + + struct cacheSubscribeLink_typ { // TODO: This type is not implemented yet + int dummy; + }; + + struct cacheSubscribe_typ { + cacheSubscribeLink_typ* link; + }; + + struct cacheAuth_typ { + std::string userToken; // TODO: We can probably define the size of the string here + }; + + enum cacheSortMode_enum { + CACHE_SORT_NONE, + CACHE_SORT_CONTINUOS, + CACHE_SORT_COMMAND + }; + + struct cacheItem_typ { + std::string variable; + std::string alias; + std::string value; + VAR_TYPE_enum type; + void* address = 0; // This needs to be initialized to 0 + size_t length; + size_t dimension; + cacheTime lastAccessed; // TODO: Maybe make it something other than a udint + std::vector subscribers; // This may end up being a vector of pointers of cacheSubLink_typ + std::vector authorization; + }; + + + class Cache + { + public: + // For debug, maybe has other uses + size_t size(); + size_t capacity(); + void clear(); // Does not clear variables with alias' + void forceClear(); // Clears everything out of the cache + + // Interface + Cache(void); + ~Cache(void); + + const char* getValue(char*); // TODO: We will probably need more information here + const char* getInfo(char*, varVariable_typ&); + void addAlias(char*, char*); + void subscribe(char*, cacheSubscribeLink_typ&); + void subscribe(varVariable_typ&, cacheSubscribeLink_typ&); + void addVariable(char*); // This function will add variable if not already in the cache + bool inCache(char*); // Returns true if variable is in cache + + private: + + cacheItem_typ* _addVariable(char*); // This function will add a new variable to the cache without checking if it already exists + cacheItem_typ* _addVariable(char*, char*); + cacheItem_typ* _getCacheItem(char*); + void _updateCacheItem(cacheItem_typ*); + cacheTime _getCurrentTime(void); + + std::vector _cache; + bool _isSorted = false; + cacheSortMode_enum _sortMode = CACHE_SORT_NONE; + }; +} + +#endif /* VAR_CACHE_H */