LCOV - code coverage report
Current view: top level - asmjit - string.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 0 138 0.0 %
Date: 2024-10-18 14:00:27 Functions: 0 14 0.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             : Copyright (c) 2008-2017, Petr Kobalicek
       3             : 
       4             : This software is provided 'as-is', without any express or implied
       5             : warranty. In no event will the authors be held liable for any damages
       6             : arising from the use of this software.
       7             : 
       8             : Permission is granted to anyone to use this software for any purpose,
       9             : including commercial applications, and to alter it and redistribute it
      10             : freely, subject to the following restrictions:
      11             : 
      12             : 1. The origin of this software must not be misrepresented; you must not
      13             :    claim that you wrote the original software. If you use this software
      14             :    in a product, an acknowledgment in the product documentation would be
      15             :    appreciated but is not required.
      16             : 2. Altered source versions must be plainly marked as such, and must not be
      17             :    misrepresented as being the original software.
      18             : 3. This notice may not be removed or altered from any source distribution.
      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      20             : #ifdef __PLUMED_HAS_ASMJIT
      21             : #pragma GCC diagnostic push
      22             : #pragma GCC diagnostic ignored "-Wpedantic"
      23             : // [AsmJit]
      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
      25             : //
      26             : // [License]
      27             : // Zlib - See LICENSE.md file in the package.
      28             : 
      29             : // [Export]
      30             : #define ASMJIT_EXPORTS
      31             : 
      32             : // [Dependencies]
      33             : #include "./moved_string.h"
      34             : #include "./utils.h"
      35             : 
      36             : // [Api-Begin]
      37             : #include "./asmjit_apibegin.h"
      38             : 
      39             : namespace PLMD {
      40             : namespace asmjit {
      41             : 
      42             : // ============================================================================
      43             : // [asmjit::StringBuilder - Construction / Destruction]
      44             : // ============================================================================
      45             : 
      46             : // Should be placed in read-only memory.
      47             : static const char StringBuilder_empty[4] = { 0 };
      48             : 
      49           0 : StringBuilder::StringBuilder() noexcept
      50           0 :   : _data(const_cast<char*>(StringBuilder_empty)),
      51           0 :     _length(0),
      52           0 :     _capacity(0),
      53           0 :     _canFree(false) {}
      54             : 
      55           0 : StringBuilder::~StringBuilder() noexcept {
      56           0 :   if (_canFree)
      57           0 :     Internal::releaseMemory(_data);
      58           0 : }
      59             : 
      60             : // ============================================================================
      61             : // [asmjit::StringBuilder - Prepare / Reserve]
      62             : // ============================================================================
      63             : 
      64           0 : ASMJIT_FAVOR_SIZE char* StringBuilder::prepare(uint32_t op, size_t len) noexcept {
      65           0 :   if (op == kStringOpSet) {
      66             :     // We don't care here, but we can't return a null pointer since it indicates
      67             :     // failure in memory allocation.
      68           0 :     if (len == 0) {
      69           0 :       if (_data != StringBuilder_empty)
      70           0 :         _data[0] = 0;
      71             : 
      72           0 :       _length = 0;
      73           0 :       return _data;
      74             :     }
      75             : 
      76           0 :     if (_capacity < len) {
      77           0 :       if (len >= IntTraits<size_t>::maxValue() - sizeof(intptr_t) * 2)
      78             :         return nullptr;
      79             : 
      80             :       size_t to = Utils::alignTo<size_t>(len, sizeof(intptr_t));
      81             :       if (to < 256 - sizeof(intptr_t))
      82             :         to = 256 - sizeof(intptr_t);
      83             : 
      84           0 :       char* newData = static_cast<char*>(Internal::allocMemory(to + sizeof(intptr_t)));
      85           0 :       if (!newData) {
      86           0 :         clear();
      87           0 :         return nullptr;
      88             :       }
      89             : 
      90           0 :       if (_canFree)
      91           0 :         Internal::releaseMemory(_data);
      92             : 
      93           0 :       _data = newData;
      94           0 :       _capacity = to + sizeof(intptr_t) - 1;
      95           0 :       _canFree = true;
      96             :     }
      97             : 
      98           0 :     _data[len] = 0;
      99           0 :     _length = len;
     100             : 
     101             :     ASMJIT_ASSERT(_length <= _capacity);
     102           0 :     return _data;
     103             :   }
     104             :   else {
     105             :     // We don't care here, but we can't return a null pointer since it indicates
     106             :     // failure of memory allocation.
     107           0 :     if (len == 0)
     108           0 :       return _data + _length;
     109             : 
     110             :     // Overflow.
     111           0 :     if (IntTraits<size_t>::maxValue() - sizeof(intptr_t) * 2 - _length < len)
     112             :       return nullptr;
     113             : 
     114           0 :     size_t after = _length + len;
     115           0 :     if (_capacity < after) {
     116             :       size_t to = _capacity;
     117             : 
     118             :       if (to < 256)
     119             :         to = 256;
     120             : 
     121           0 :       while (to < 1024 * 1024 && to < after)
     122           0 :         to *= 2;
     123             : 
     124           0 :       if (to < after) {
     125             :         to = after;
     126           0 :         if (to < (IntTraits<size_t>::maxValue() - 1024 * 32))
     127             :           to = Utils::alignTo<size_t>(to, 1024 * 32);
     128             :       }
     129             : 
     130             :       to = Utils::alignTo<size_t>(to, sizeof(intptr_t));
     131           0 :       char* newData = static_cast<char*>(Internal::allocMemory(to + sizeof(intptr_t)));
     132           0 :       if (!newData) return nullptr;
     133             : 
     134           0 :       ::memcpy(newData, _data, _length);
     135           0 :       if (_canFree)
     136             :         Internal::releaseMemory(_data);
     137             : 
     138           0 :       _data = newData;
     139           0 :       _capacity = to + sizeof(intptr_t) - 1;
     140           0 :       _canFree = true;
     141             :     }
     142             : 
     143           0 :     char* ret = _data + _length;
     144           0 :     _data[after] = 0;
     145           0 :     _length = after;
     146             : 
     147             :     ASMJIT_ASSERT(_length <= _capacity);
     148           0 :     return ret;
     149             :   }
     150             : }
     151             : 
     152           0 : ASMJIT_FAVOR_SIZE Error StringBuilder::reserve(size_t to) noexcept {
     153           0 :   if (_capacity >= to)
     154             :     return kErrorOk;
     155             : 
     156           0 :   if (to >= IntTraits<size_t>::maxValue() - sizeof(intptr_t) * 2)
     157             :     return DebugUtils::errored(kErrorNoHeapMemory);
     158             : 
     159             :   to = Utils::alignTo<size_t>(to, sizeof(intptr_t));
     160           0 :   char* newData = static_cast<char*>(Internal::allocMemory(to + sizeof(intptr_t)));
     161             : 
     162           0 :   if (!newData)
     163             :     return DebugUtils::errored(kErrorNoHeapMemory);
     164             : 
     165           0 :   ::memcpy(newData, _data, _length + 1);
     166           0 :   if (_canFree)
     167             :     Internal::releaseMemory(_data);
     168             : 
     169           0 :   _data = newData;
     170           0 :   _capacity = to + sizeof(intptr_t) - 1;
     171           0 :   _canFree = true;
     172           0 :   return kErrorOk;
     173             : }
     174             : 
     175             : // ============================================================================
     176             : // [asmjit::StringBuilder - Clear]
     177             : // ============================================================================
     178             : 
     179           0 : void StringBuilder::clear() noexcept {
     180           0 :   if (_data != StringBuilder_empty)
     181           0 :     _data[0] = 0;
     182           0 :   _length = 0;
     183           0 : }
     184             : 
     185             : // ============================================================================
     186             : // [asmjit::StringBuilder - Methods]
     187             : // ============================================================================
     188             : 
     189           0 : Error StringBuilder::_opString(uint32_t op, const char* str, size_t len) noexcept {
     190           0 :   if (len == Globals::kInvalidIndex)
     191           0 :     len = str ? ::strlen(str) : static_cast<size_t>(0);
     192             : 
     193           0 :   char* p = prepare(op, len);
     194           0 :   if (!p) return DebugUtils::errored(kErrorNoHeapMemory);
     195             : 
     196             :   ::memcpy(p, str, len);
     197           0 :   return kErrorOk;
     198             : }
     199             : 
     200           0 : Error StringBuilder::_opChar(uint32_t op, char c) noexcept {
     201           0 :   char* p = prepare(op, 1);
     202           0 :   if (!p) return DebugUtils::errored(kErrorNoHeapMemory);
     203             : 
     204           0 :   *p = c;
     205           0 :   return kErrorOk;
     206             : }
     207             : 
     208           0 : Error StringBuilder::_opChars(uint32_t op, char c, size_t n) noexcept {
     209           0 :   char* p = prepare(op, n);
     210           0 :   if (!p) return DebugUtils::errored(kErrorNoHeapMemory);
     211             : 
     212           0 :   ::memset(p, c, n);
     213           0 :   return kErrorOk;
     214             : }
     215             : 
     216             : static const char StringBuilder_numbers[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     217             : 
     218           0 : Error StringBuilder::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) noexcept {
     219           0 :   if (base < 2 || base > 36)
     220             :     base = 10;
     221             : 
     222             :   char buf[128];
     223             :   char* p = buf + ASMJIT_ARRAY_SIZE(buf);
     224             : 
     225             :   uint64_t orig = i;
     226             :   char sign = '\0';
     227             : 
     228             :   // --------------------------------------------------------------------------
     229             :   // [Sign]
     230             :   // --------------------------------------------------------------------------
     231             : 
     232           0 :   if ((flags & kStringFormatSigned) != 0 && static_cast<int64_t>(i) < 0) {
     233           0 :     i = static_cast<uint64_t>(-static_cast<int64_t>(i));
     234             :     sign = '-';
     235             :   }
     236           0 :   else if ((flags & kStringFormatShowSign) != 0) {
     237             :     sign = '+';
     238             :   }
     239           0 :   else if ((flags & kStringFormatShowSpace) != 0) {
     240             :     sign = ' ';
     241             :   }
     242             : 
     243             :   // --------------------------------------------------------------------------
     244             :   // [Number]
     245             :   // --------------------------------------------------------------------------
     246             : 
     247             :   do {
     248           0 :     uint64_t d = i / base;
     249           0 :     uint64_t r = i % base;
     250             : 
     251           0 :     *--p = StringBuilder_numbers[r];
     252             :     i = d;
     253           0 :   } while (i);
     254             : 
     255           0 :   size_t numberLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p);
     256             : 
     257             :   // --------------------------------------------------------------------------
     258             :   // [Alternate Form]
     259             :   // --------------------------------------------------------------------------
     260             : 
     261           0 :   if ((flags & kStringFormatAlternate) != 0) {
     262           0 :     if (base == 8) {
     263           0 :       if (orig != 0)
     264           0 :         *--p = '0';
     265             :     }
     266           0 :     if (base == 16) {
     267           0 :       *--p = 'x';
     268           0 :       *--p = '0';
     269             :     }
     270             :   }
     271             : 
     272             :   // --------------------------------------------------------------------------
     273             :   // [Width]
     274             :   // --------------------------------------------------------------------------
     275             : 
     276           0 :   if (sign != 0)
     277           0 :     *--p = sign;
     278             : 
     279             :   if (width > 256)
     280             :     width = 256;
     281             : 
     282           0 :   if (width <= numberLength)
     283             :     width = 0;
     284             :   else
     285           0 :     width -= numberLength;
     286             : 
     287             :   // --------------------------------------------------------------------------
     288             :   // Write]
     289             :   // --------------------------------------------------------------------------
     290             : 
     291           0 :   size_t prefixLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberLength;
     292           0 :   char* data = prepare(op, prefixLength + width + numberLength);
     293             : 
     294           0 :   if (!data)
     295             :     return DebugUtils::errored(kErrorNoHeapMemory);
     296             : 
     297             :   ::memcpy(data, p, prefixLength);
     298           0 :   data += prefixLength;
     299             : 
     300             :   ::memset(data, '0', width);
     301           0 :   data += width;
     302             : 
     303           0 :   ::memcpy(data, p + prefixLength, numberLength);
     304           0 :   return kErrorOk;
     305             : }
     306             : 
     307           0 : Error StringBuilder::_opHex(uint32_t op, const void* data, size_t len) noexcept {
     308             :   char* dst;
     309             : 
     310           0 :   if (len >= IntTraits<size_t>::maxValue() / 2 || !(dst = prepare(op, len * 2)))
     311             :     return DebugUtils::errored(kErrorNoHeapMemory);;
     312             : 
     313             :   const char* src = static_cast<const char*>(data);
     314           0 :   for (size_t i = 0; i < len; i++, dst += 2, src++) {
     315           0 :     dst[0] = StringBuilder_numbers[(src[0] >> 4) & 0xF];
     316           0 :     dst[1] = StringBuilder_numbers[(src[0]     ) & 0xF];
     317             :   }
     318             :   return kErrorOk;
     319             : }
     320             : 
     321           0 : Error StringBuilder::_opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept {
     322             :   char buf[1024];
     323             : 
     324             :   vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
     325           0 :   buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
     326             : 
     327           0 :   return _opString(op, buf);
     328             : }
     329             : 
     330           0 : Error StringBuilder::setFormat(const char* fmt, ...) noexcept {
     331             :   bool result;
     332             : 
     333             :   va_list ap;
     334           0 :   va_start(ap, fmt);
     335           0 :   result = _opVFormat(kStringOpSet, fmt, ap);
     336           0 :   va_end(ap);
     337             : 
     338           0 :   return result;
     339             : }
     340             : 
     341           0 : Error StringBuilder::appendFormat(const char* fmt, ...) noexcept {
     342             :   bool result;
     343             : 
     344             :   va_list ap;
     345           0 :   va_start(ap, fmt);
     346           0 :   result = _opVFormat(kStringOpAppend, fmt, ap);
     347           0 :   va_end(ap);
     348             : 
     349           0 :   return result;
     350             : }
     351             : 
     352           0 : bool StringBuilder::eq(const char* str, size_t len) const noexcept {
     353           0 :   const char* aData = _data;
     354             :   const char* bData = str;
     355             : 
     356           0 :   size_t aLength = _length;
     357             :   size_t bLength = len;
     358             : 
     359           0 :   if (bLength == Globals::kInvalidIndex) {
     360             :     size_t i;
     361           0 :     for (i = 0; i < aLength; i++)
     362           0 :       if (aData[i] != bData[i] || bData[i] == 0)
     363             :         return false;
     364           0 :     return bData[i] == 0;
     365             :   }
     366             :   else {
     367           0 :     if (aLength != bLength)
     368             :       return false;
     369           0 :     return ::memcmp(aData, bData, aLength) == 0;
     370             :   }
     371             : }
     372             : 
     373             : } // asmjit namespace
     374             : } // namespace PLMD
     375             : 
     376             : // [Api-End]
     377             : #include "./asmjit_apiend.h"
     378             : #pragma GCC diagnostic pop
     379             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16