[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/rburkholder/daScript/master/src/simulate/runtime_string.cpp [Back]  [Original]

#include "daScript/misc/platform.h"

#include "daScript/simulate/runtime_string.h"
#include "daScript/simulate/simulate.h"
#include "daScript/simulate/hash.h"
#include "daScript/simulate/debug_print.h"
#include "daScript/simulate/runtime_string_delete.h"
#include "daScript/simulate/simulate_nodes.h"
#include "daScript/simulate/sim_policy.h"

namespace das
{
    // string operations

    vec4f SimPolicy_String::Add ( vec4f a, vec4f b, Context & context, LineInfo * at ) {
        const char *  sA = to_rts(a);
        auto la = stringLength(context, sA);
        const char *  sB = to_rts(b);
        auto lb = stringLength(context, sB);
        uint32_t commonLength = la + lb;
        if ( !commonLength ) {
            return v_zero();
        } else if ( char * sAB = (char * ) context.stringHeap->allocateString(nullptr, commonLength) ) {
            memcpy ( sAB, sA, la );
            memcpy ( sAB+la, sB, lb+1 );
            context.stringHeap->recognize(sAB);
            return cast::from(sAB);
        } else {
            context.throw_error_at(at, "can't add two strings, out of heap");
            return v_zero();
        }
    }

    void SimPolicy_String::SetAdd ( char * a, vec4f b, Context & context, LineInfo * at ) {
        char ** pA = (char **)a;
        const char *  sA = *pA ? *pA : rts_null;
        auto la = stringLength(context, sA);
        const char *  sB = to_rts(b);
        auto lb = stringLength(context, sB);
        uint32_t commonLength = la + lb;
        if ( !commonLength ) {
            // *pA = nullptr; is unnecessary, because its already nullptr
            return;
        } else if ( char * sAB = (char * ) context.stringHeap->allocateString(nullptr, commonLength) ) {
            memcpy ( sAB, sA, la );
            memcpy ( sAB+la, sB, lb+1 );
            *pA = sAB;
            context.stringHeap->recognize(sAB);
        } else {
            context.throw_error_at(at, "can't add two strings, out of heap");
        }
    }

    // helper functions

    const char * rts_null = "";

    int hexChar ( char ch ) {
        if ( ch>='a' && ch='A' && ch='0' && ch 12) | 0xE0);
          result[1] = char(((ch >> 6) & 0x3F) | 0x80);
          result[2] = char(((ch >> 0) & 0x3F) | 0x80);
          result[3] = 0;
          return true;
      }

      if (ch > 18) | 0xF0);
          result[1] = char(((ch >> 12) & 0x3F) | 0x80);
          result[2] = char(((ch >>  6) & 0x3F) | 0x80);
          result[3] = char(((ch >>  0) & 0x3F) | 0x80);
          result[4] = 0;
          return true;
      }

      if (ch > 24) | 0xF8);
          result[1] = char(((ch >> 18) & 0x3F) | 0x80);
          result[2] = char(((ch >> 12) & 0x3F) | 0x80);
          result[3] = char(((ch >>  6) & 0x3F) | 0x80);
          result[4] = char(((ch >>  0) & 0x3F) | 0x80);
          result[5] = 0;
          return true;
      }

      if (ch > 30) | 0xFC);
          result[1] = char(((ch >> 24) & 0x3F) | 0x80);
          result[2] = char(((ch >> 18) & 0x3F) | 0x80);
          result[3] = char(((ch >> 12) & 0x3F) | 0x80);
          result[4] = char(((ch >>  6) & 0x3F) | 0x80);
          result[5] = char(((ch >>  0) & 0x3F) | 0x80);
          result[6] = 0;
          return true;
      }

      result[0] = '?';
      result[1] = 0;

      return false;
    }

    string unescapeString ( const string & input, bool * error, bool ) {
        if ( error ) *error = false;
        const char* str = input.c_str();
        const char* strEnd = str + input.length();
        string result;
        result.reserve(input.size());
        for( ; str < strEnd; ++str ) {
            if ( *str=='\\' ) {
                ++str;
                if ( str == strEnd ) {
                    if ( error ) *error = true;
                    return result; // invalid escape sequence
                }
                switch ( *str ) {
                    case '"':
                    case '/':
                    case '\\':  result += *str;    break;
                    case 'b':   result += '\b';    break;
                    case 'f':   result += '\f';    break;
                    case 'n':   result += '\n';    break;
                    case 'r':   result += '\r';    break;
                    case 't':   result += '\t';    break;
                    case 'v':   result += '\v';    break;
                    case '\n':  break;  // skip LF
                    case '{':   result += '{';    break;
                    case '}':   result += '}';    break;
                    case '\r':  if ( str+1!=strEnd && str[1]=='\n' ) str++; break;  // skip CR LF or just CR
                    case 'x':
                    case 'u':
                    case 'U': {
                            int symbols = (*str == 'x') ? 2 : (*str == 'u') ? 4 : 8;
                            uint32_t charCode = 0;
                            int x = 0;
                            str++;
                            for (; x < symbols && str != strEnd; x++, str++) {
                                int h = hexChar(*str);
                                if (h < 0)
                                    break;
                                charCode = charCode * 16 + h;
                            }
                            str--;

                            if (symbols == 2) { // \xNN
                                if (!x) {
                                    if (error) *error = true;
                                }
                                else
                                    result += char(charCode);
                            }
                            else if (x != symbols) { // \u \U requires exactly 4 or 8 hex symbols
                                if (error) *error = true;
                            }
                            else {
                                char buf[8];
                                if (!encodeUtf8Char(charCode, buf) && error)
                                    *error = true;
                                result += buf;
                            }
                        }
                        break;
                    default:    result += *str; if ( error ) *error = true; break;  // invalid escape character
                }
            } else
                result += *str;
        }
        return result;
    }

    string escapeString ( const string & input, bool das_escape ) {
        const char* str = input.c_str();
        const char* strEnd = str + input.length();
        string result;
        result.reserve(input.size());
        for( ; str < strEnd; ++str ) {
            auto ch = uint8_t(*str);
            switch ( ch ) {
                case '\"':  result.append("\\\"");  break;
                case '\\':  result.append("\\\\");  break;
                case '\b':  result.append("\\b");   break;
                case '\v':  result.append("\\v");   break;
                case '\f':  result.append("\\f");   break;
                case '\n':  result.append("\\n");   break;
                case '\r':  result.append("\\r");   break;
                case '\t':  result.append("\\t");   break;
                case '{':   if (das_escape) result.append("\\{"); else result.append("{");  break;
                case '}':   if (das_escape) result.append("\\}"); else result.append("}");  break;
                default:
                    if ( ch >4)+'0');
                        result.append(1,(ch&15)+'0');
                    } else {
                        result.append(1, ch);
                    }
                    break;
            }
        }
        return result;
    }

    string getFewLines ( const char* st, uint32_t stlen, int ROW, int COL, int LROW, int LCOL, int TAB ) {
        TextWriter text;
        int col=0, row=1;
        auto it = st;
        auto itend = st + stlen;
        if ( ROW>1 ) {
            while ( *it && it!=itend ) {
                auto CH = *it++;
                if ( CH=='\n' ) {
                    row++;
                    col=0;
                    if ( row==ROW ) break;
                }
            }
        }
        if ( row!=ROW ) return "";
        auto beginOfLine = it;
        for (;;) {
            if (*it == 0 || it == itend)
            {
                text 

Web Proxy Viewer  |  New URL  |  Original Page