Beispiel #1
0
        /// <summary> Wraps, parses and formats the variable arguments of the real delegate. </summary>
        private static void LogHandlerWrapper(libobs.log_error_level lvl, string format, IntPtr args, IntPtr p)
        {
            using (va_list arglist = new va_list(args))
            {
                object[] objs         = arglist.GetObjectsByFormat(format);
                string   formattedMsg = Printf.sprintf(format, objs);

                realHandler((LogErrorLevel)lvl, formattedMsg, p);
            }
        }
Beispiel #2
0
        public static object /*?*/ va_arg(va_list argp, Type t)
        {
            ArgIterator ai = argp;

            if (ai.GetRemainingCount() > 0)
            {
                TypedReference tr = ai.GetNextArg();
                // TODO: coerce return value to type t...
                return((object)(__refvalue(tr, object)));
            }
            throw new FormatException();
        }
Beispiel #3
0
    static char[] buf = new char[etBUFSIZE];       /* Conversion buffer */
    static void sqlite3VXPrintf(
    StrAccum pAccum,             /* Accumulate results here */
    int useExtended,             /* Allow extended %-conversions */
    string fmt,                   /* Format string */
    va_list[] ap                   /* arguments */
    )
    {
      int c;                     /* Next character in the format string */
      int bufpt;                 /* Pointer to the conversion buffer */
      int precision;             /* Precision of the current field */
      int length;                /* Length of the field */
      int idx;                   /* A general purpose loop counter */
      int width;                 /* Width of the current field */
      etByte flag_leftjustify;   /* True if "-" flag is present */
      etByte flag_plussign;      /* True if "+" flag is present */
      etByte flag_blanksign;     /* True if " " flag is present */
      etByte flag_alternateform; /* True if "#" flag is present */
      etByte flag_altform2;      /* True if "!" flag is present */
      etByte flag_zeropad;       /* True if field width constant starts with zero */
      etByte flag_long;          /* True if "l" flag is present */
      etByte flag_longlong;      /* True if the "ll" flag is present */
      etByte done;               /* Loop termination flag */
      i64 longvalue;
      LONGDOUBLE_TYPE realvalue; /* Value for real types */
      et_info infop;      /* Pointer to the appropriate info structure */
      char[] buf = new char[etBUFSIZE];       /* Conversion buffer */
      char prefix;                /* Prefix character.  "+" or "-" or " " or '\0'. */
      byte xtype = 0;             /* Conversion paradigm */
      // Not used in C# -- string zExtra;              /* Extra memory used for etTCLESCAPE conversions */
#if !SQLITE_OMIT_FLOATING_POINT
      int exp, e2;                /* exponent of real numbers */
      double rounder;             /* Used for rounding floating point values */
      etByte flag_dp;             /* True if decimal point should be shown */
      etByte flag_rtz;            /* True if trailing zeros should be removed */
      etByte flag_exp;            /* True to force display of the exponent */
      int nsd;                    /* Number of significant digits returned */
#endif
      length = 0;
      bufpt = 0;
      int _fmt = 0; // Work around string pointer
      fmt += '\0';

      for ( ; _fmt <= fmt.Length && ( c = fmt[_fmt] ) != 0; ++_fmt )
      {
        if ( c != '%' )
        {
          int amt;
          bufpt = _fmt;
          amt = 1;
          while ( _fmt < fmt.Length && ( c = ( fmt[++_fmt] ) ) != '%' && c != 0 )
            amt++;
          sqlite3StrAccumAppend( pAccum, fmt.Substring( bufpt, amt ), amt );
          if ( c == 0 )
            break;
        }
        if ( _fmt < fmt.Length && ( c = ( fmt[++_fmt] ) ) == 0 )
        {
          sqlite3StrAccumAppend( pAccum, "%", 1 );
          break;
        }
        /* Find out what flags are present */
        flag_leftjustify = flag_plussign = flag_blanksign =
        flag_alternateform = flag_altform2 = flag_zeropad = false;
        done = false;
        do
        {
          switch ( c )
          {
            case '-':
              flag_leftjustify = true;
              break;
            case '+':
              flag_plussign = true;
              break;
            case ' ':
              flag_blanksign = true;
              break;
            case '#':
              flag_alternateform = true;
              break;
            case '!':
              flag_altform2 = true;
              break;
            case '0':
              flag_zeropad = true;
              break;
            default:
              done = true;
              break;
          }
        } while ( !done && _fmt < fmt.Length - 1 && ( c = ( fmt[++_fmt] ) ) != 0 );
        /* Get the field width */
        width = 0;
        if ( c == '*' )
        {
          width = (int)va_arg( ap, "int" );
          if ( width < 0 )
          {
            flag_leftjustify = true;
            width = -width;
          }
          c = fmt[++_fmt];
        }
        else
        {
          while ( c >= '0' && c <= '9' )
          {
            width = width * 10 + c - '0';
            c = fmt[++_fmt];
          }
        }
        if ( width > etBUFSIZE - 10 )
        {
          width = etBUFSIZE - 12;
        }
        /* Get the precision */
        if ( c == '.' )
        {
          precision = 0;
          c = fmt[++_fmt];
          if ( c == '*' )
          {
            precision = (int)va_arg( ap, "int" );
            if ( precision < 0 )
              precision = -precision;
            c = fmt[++_fmt];
          }
          else
          {
            while ( c >= '0' && c <= '9' )
            {
              precision = precision * 10 + c - '0';
              c = fmt[++_fmt];
            }
          }
        }
        else
        {
          precision = -1;
        }
        /* Get the conversion type modifier */
        if ( c == 'l' )
        {
          flag_long = true;
          c = fmt[++_fmt];
          if ( c == 'l' )
          {
            flag_longlong = true;
            c = fmt[++_fmt];
          }
          else
          {
            flag_longlong = false;
          }
        }
        else
        {
          flag_long = flag_longlong = false;
        }
        /* Fetch the info entry for the field */
        infop = fmtinfo[0];
        xtype = etINVALID;
        for ( idx = 0; idx < ArraySize( fmtinfo ); idx++ )
        {
          if ( c == fmtinfo[idx].fmttype )
          {
            infop = fmtinfo[idx];
            if ( useExtended != 0 || ( infop.flags & FLAG_INTERN ) == 0 )
            {
              xtype = infop.type;
            }
            else
            {
              return;
            }
            break;
          }
        }
        //zExtra = null;

        /* Limit the precision to prevent overflowing buf[] during conversion */
        if ( precision > etBUFSIZE - 40 && ( infop.flags & FLAG_STRING ) == 0 )
        {
          precision = etBUFSIZE - 40;
        }

        /*
        ** At this point, variables are initialized as follows:
        **
        **   flag_alternateform          TRUE if a '#' is present.
        **   flag_altform2               TRUE if a '!' is present.
        **   flag_plussign               TRUE if a '+' is present.
        **   flag_leftjustify            TRUE if a '-' is present or if the
        **                               field width was negative.
        **   flag_zeropad                TRUE if the width began with 0.
        **   flag_long                   TRUE if the letter 'l' (ell) prefixed
        **                               the conversion character.
        **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
        **                               the conversion character.
        **   flag_blanksign              TRUE if a ' ' is present.
        **   width                       The specified field width.  This is
        **                               always non-negative.  Zero is the default.
        **   precision                   The specified precision.  The default
        **                               is -1.
        **   xtype                       The class of the conversion.
        **   infop                       Pointer to the appropriate info struct.
        */
        switch ( xtype )
        {
          case etPOINTER:
            flag_longlong = true;// char*.Length == sizeof(i64);
            flag_long = false;// char*.Length == sizeof(long);
            /* Fall through into the next case */
            goto case etRADIX;
          case etORDINAL:
          case etRADIX:
            if ( ( infop.flags & FLAG_SIGNED ) != 0 )
            {
              i64 v;
              if ( flag_longlong )
              {
                v = (long)va_arg( ap, "i64" );
              }
              else if ( flag_long )
              {
                v = (long)va_arg( ap, "long int" );
              }
              else
              {
                v = (int)va_arg( ap, "int" );
              }
              if ( v < 0 )
              {
                longvalue = -v;
                prefix = '-';
              }
              else
              {
                longvalue = v;
                if ( flag_plussign )
                  prefix = '+';
                else if ( flag_blanksign )
                  prefix = ' ';
                else
                  prefix = '\0';
              }
            }
            else
            {
              if ( flag_longlong )
              {
                longvalue = (i64)va_arg( ap, "longlong int" );
              }
              else if ( flag_long )
              {
                longvalue = (i64)va_arg( ap, "long int" );
              }
              else
              {
                longvalue = (i64)va_arg( ap, "long" );
              }
              prefix = '\0';
            }
            if ( longvalue == 0 )
              flag_alternateform = false;
            if ( flag_zeropad && precision < width - ( ( prefix != '\0' ) ? 1 : 0 ) )
            {
              precision = width - ( ( prefix != '\0' ) ? 1 : 0 );
            }
            bufpt = buf.Length;//[etBUFSIZE-1];
            char[] _bufOrd = null;
            if ( xtype == etORDINAL )
            {
              char[] zOrd = "thstndrd".ToCharArray();
              int x = (int)( longvalue % 10 );
              if ( x >= 4 || ( longvalue / 10 ) % 10 == 1 )
              {
                x = 0;
              }
              _bufOrd = new char[2];
              _bufOrd[0] = zOrd[x * 2];
              _bufOrd[1] = zOrd[x * 2 + 1];
              //bufpt -= 2;
            }
            {

              char[] _buf;
              switch ( infop._base )
              {
                case 16:
                  _buf = longvalue.ToString( "x" ).ToCharArray();
                  break;
                case 8:
                  _buf = Convert.ToString( (long)longvalue, 8 ).ToCharArray();
                  break;
                default:
                  {
                    if ( flag_zeropad )
                      _buf = longvalue.ToString( new string( '0', width - ( ( prefix != '\0' ) ? 1 : 0 ) ) ).ToCharArray();
                    else
                      _buf = longvalue.ToString().ToCharArray();
                  }
                  break;
              }
              bufpt = buf.Length - _buf.Length - ( _bufOrd == null ? 0 : 2 );
              Array.Copy( _buf, 0, buf, bufpt, _buf.Length );
              if ( _bufOrd != null )
              {
                buf[buf.Length - 1] = _bufOrd[1];
                buf[buf.Length - 2] = _bufOrd[0];
              }
              //char* cset;      /* Use registers for speed */
              //int _base;
              //cset = aDigits[infop.charset];
              //_base = infop._base;
              //do
              //{ /* Convert to ascii */
              //   *(--bufpt) = cset[longvalue % (ulong)_base];
              //  longvalue = longvalue / (ulong)_base;
              //} while (longvalue > 0);
            }
            length = buf.Length - bufpt;//length = (int)(&buf[etBUFSIZE-1]-bufpt);
            for ( idx = precision - length; idx > 0; idx-- )
            {
              buf[( --bufpt )] = '0';                             /* Zero pad */
            }
            if ( prefix != '\0' )
              buf[--bufpt] = prefix;   /* Add sign */
            if ( flag_alternateform && infop.prefix != 0 )
            {      /* Add "0" or "0x" */
              int pre;
              char x;
              pre = infop.prefix;
              for ( ; ( x = aPrefix[pre] ) != 0; pre++ )
                buf[--bufpt] = x;
            }
            length = buf.Length - bufpt;//length = (int)(&buf[etBUFSIZE-1]-bufpt);
            break;
          case etFLOAT:
          case etEXP:
          case etGENERIC:
            realvalue = (double)va_arg( ap, "double" );
#if SQLITE_OMIT_FLOATING_POINT
length = 0;
#else
            if ( precision < 0 )
              precision = 6;         /* Set default precision */
            if ( precision > etBUFSIZE / 2 - 10 )
              precision = etBUFSIZE / 2 - 10;
            if ( realvalue < 0.0 )
            {
              realvalue = -realvalue;
              prefix = '-';
            }
            else
            {
              if ( flag_plussign )
                prefix = '+';
              else if ( flag_blanksign )
                prefix = ' ';
              else
                prefix = '\0';
            }
            if ( xtype == etGENERIC && precision > 0 )
              precision--;
#if FALSE
/* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
#else
            /* It makes more sense to use 0.5 */
            for ( idx = precision, rounder = 0.5; idx > 0; idx--, rounder *= 0.1 )
            {
            }
#endif
            if ( xtype == etFLOAT )
              realvalue += rounder;
            /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
            exp = 0;
            double d = 0;
            if ( Double.IsNaN( realvalue ) || !( Double.TryParse( Convert.ToString( realvalue ), out d ) ) )//if( sqlite3IsNaN((double)realvalue) )
            {
              buf[0] = 'N';
              buf[1] = 'a';
              buf[2] = 'N';// "NaN"
              length = 3;
              break;
            }
            if ( realvalue > 0.0 )
            {
              while ( realvalue >= 1e32 && exp <= 350 )
              {
                realvalue *= 1e-32;
                exp += 32;
              }
              while ( realvalue >= 1e8 && exp <= 350 )
              {
                realvalue *= 1e-8;
                exp += 8;
              }
              while ( realvalue >= 10.0 && exp <= 350 )
              {
                realvalue *= 0.1;
                exp++;
              }
              while ( realvalue < 1e-8 )
              {
                realvalue *= 1e8;
                exp -= 8;
              }
              while ( realvalue < 1.0 )
              {
                realvalue *= 10.0;
                exp--;
              }
              if ( exp > 350 )
              {
                if ( prefix == '-' )
                {
                  buf[0] = '-';
                  buf[1] = 'I';
                  buf[2] = 'n';
                  buf[3] = 'f';// "-Inf"
                  bufpt = 4;
                }
                else if ( prefix == '+' )
                {
                  buf[0] = '+';
                  buf[1] = 'I';
                  buf[2] = 'n';
                  buf[3] = 'f';// "+Inf"
                  bufpt = 4;
                }
                else
                {
                  buf[0] = 'I';
                  buf[1] = 'n';
                  buf[2] = 'f';// "Inf"
                  bufpt = 3;
                }
                length = sqlite3Strlen30( bufpt );// sqlite3Strlen30(bufpt);
                bufpt = 0;
                break;
              }
            }
            bufpt = 0;
            /*
            ** If the field type is etGENERIC, then convert to either etEXP
            ** or etFLOAT, as appropriate.
            */
            flag_exp = xtype == etEXP;
            if ( xtype != etFLOAT )
            {
              realvalue += rounder;
              if ( realvalue >= 10.0 )
              {
                realvalue *= 0.1;
                exp++;
              }
            }
            if ( xtype == etGENERIC )
            {
              flag_rtz = !flag_alternateform;
              if ( exp < -4 || exp > precision )
              {
                xtype = etEXP;
              }
              else
              {
                precision = precision - exp;
                xtype = etFLOAT;
              }
            }
            else
            {
              flag_rtz = false;
            }
            if ( xtype == etEXP )
            {
              e2 = 0;
            }
            else
            {
              e2 = exp;
            }
            nsd = 0;
            flag_dp = ( precision > 0 ? true : false ) | flag_alternateform | flag_altform2;
            /* The sign in front of the number */
            if ( prefix != '\0' )
            {
              buf[bufpt++] = prefix;
            }
            /* Digits prior to the decimal point */
            if ( e2 < 0 )
            {
              buf[bufpt++] = '0';
            }
            else
            {
              for ( ; e2 >= 0; e2-- )
              {
                buf[bufpt++] = (char)( et_getdigit( ref realvalue, ref nsd ) + '0' ); // *(bufpt++) = et_getdigit(ref realvalue, ref nsd);
              }

            }
            /* The decimal point */
            if ( flag_dp )
            {
              buf[bufpt++] = '.';
            }
            /* "0" digits after the decimal point but before the first
            ** significant digit of the number */
            for ( e2++; e2 < 0; precision--, e2++ )
            {
              Debug.Assert( precision > 0 );
              buf[bufpt++] = '0';
            }
            /* Significant digits after the decimal point */
            while ( ( precision-- ) > 0 )
            {
              buf[bufpt++] = (char)( et_getdigit( ref realvalue, ref nsd ) + '0' ); // *(bufpt++) = et_getdigit(&realvalue, nsd);
            }
            /* Remove trailing zeros and the "." if no digits follow the "." */
            if ( flag_rtz && flag_dp )
            {
              while ( buf[bufpt - 1] == '0' )
                buf[--bufpt] = '\0';
              Debug.Assert( bufpt > 0 );
              if ( buf[bufpt - 1] == '.' )
              {
                if ( flag_altform2 )
                {
                  buf[( bufpt++ )] = '0';
                }
                else
                {
                  buf[( --bufpt )] = '0';
                }
              }
            }
            /* Add the "eNNN" suffix */
            if ( flag_exp || xtype == etEXP )
            {
              buf[bufpt++] = aDigits[infop.charset];
              if ( exp < 0 )
              {
                buf[bufpt++] = '-';
                exp = -exp;
              }
              else
              {
                buf[bufpt++] = '+';
              }
              if ( exp >= 100 )
              {
                buf[bufpt++] = (char)( exp / 100 + '0' );                /* 100's digit */
                exp %= 100;
              }
              buf[bufpt++] = (char)( exp / 10 + '0' );                     /* 10's digit */
              buf[bufpt++] = (char)( exp % 10 + '0' );                     /* 1's digit */
            }
            //bufpt = 0;

            /* The converted number is in buf[] and zero terminated. Output it.
            ** Note that the number is in the usual order, not reversed as with
            ** integer conversions. */
            length = bufpt;//length = (int)(bufpt-buf);
            bufpt = 0;

            /* Special case:  Add leading zeros if the flag_zeropad flag is
            ** set and we are not left justified */
            if ( flag_zeropad && !flag_leftjustify && length < width )
            {
              int i;
              int nPad = width - length;
              for ( i = width; i >= nPad; i-- )
              {
                buf[bufpt + i] = buf[bufpt + i - nPad];
              }
              i = ( prefix != '\0' ? 1 : 0 );
              while ( nPad-- != 0 )
                buf[( bufpt++ ) + i] = '0';
              length = width;
              bufpt = 0;
            }
#endif //* !defined(SQLITE_OMIT_FLOATING_POINT) */
            break;
          case etSIZE:
            ap[0] = pAccum.nChar; // *(va_arg(ap,int*)) = pAccum.nChar;
            length = width = 0;
            break;
          case etPERCENT:
            buf[0] = '%';
            bufpt = 0;
            length = 1;
            break;
          case etCHARX:
            c = (char)va_arg( ap, "char" );
            buf[0] = (char)c;
            if ( precision >= 0 )
            {
              for ( idx = 1; idx < precision; idx++ )
                buf[idx] = (char)c;
              length = precision;
            }
            else
            {
              length = 1;
            }
            bufpt = 0;
            break;
          case etSTRING:
          case etDYNSTRING:
            bufpt = 0;//
            string bufStr = (string)va_arg( ap, "string" );
            if ( bufStr.Length > buf.Length )
              buf = new char[bufStr.Length];
            bufStr.ToCharArray().CopyTo( buf, 0 );
            bufpt = bufStr.Length;
            if ( bufpt == 0 )
            {
              buf[0] = '\0';
            }
            else if ( xtype == etDYNSTRING )
            {
              //              zExtra = bufpt;
            }
            if ( precision >= 0 )
            {
              for ( length = 0; length < precision && length < bufStr.Length && buf[length] != 0; length++ )
              {
              }
              //length += precision;
            }
            else
            {
              length = sqlite3Strlen30( bufpt );
            }
            bufpt = 0;
            break;
          case etSQLESCAPE:
          case etSQLESCAPE2:
          case etSQLESCAPE3:
            {
              int i;
              int j;
              int k;
              int n;
              bool isnull;
              bool needQuote;
              char ch;
              char q = ( ( xtype == etSQLESCAPE3 ) ? '"' : '\'' );   /* Quote character */
              string escarg = (string)va_arg( ap, "char*" ) + '\0';
              isnull = ( escarg == "" || escarg == "NULL\0" );
              if ( isnull )
                escarg = ( xtype == etSQLESCAPE2 ) ? "NULL\0" : "(NULL)\0";
              k = precision;
              for ( i = n = 0; k != 0 && ( ch = escarg[i] ) != 0; i++, k-- )
              {
                if ( ch == q )
                  n++;
              }
              needQuote = !isnull && ( xtype == etSQLESCAPE2 );
              n += i + 1 + ( needQuote ? 2 : 0 );
              if ( n > etBUFSIZE )
              {
                buf = new char[n];//bufpt = zExtra = sqlite3Malloc(n);
                //if ( bufpt == 0 )
                //{
                //  pAccum->mallocFailed = 1;
                //  return;
                //}
                bufpt = 0; //Start of Buffer
              }
              else
              {
                //bufpt = buf;
                bufpt = 0; //Start of Buffer
              }
              j = 0;
              if ( needQuote )
                buf[bufpt + j++] = q;
              k = i;
              for ( i = 0; i < k; i++ )
              {
                buf[bufpt + j++] = ch = escarg[i];
                if ( ch == q )
                  buf[bufpt + j++] = ch;
              }
              if ( needQuote )
                buf[bufpt + j++] = q;
              buf[bufpt + j] = '\0';
              length = j;
              /* The precision in %q and %Q means how many input characters to
              ** consume, not the length of the output...
              ** if( precision>=0 && precision<length ) length = precision; */
              break;
            }
          case etTOKEN:
            {
              Token pToken = (Token)va_arg( ap, "Token" );
              if ( pToken != null )
              {
                sqlite3StrAccumAppend( pAccum, pToken.z.ToString(), (int)pToken.n );
              }
              length = width = 0;
              break;
            }
          case etSRCLIST:
            {
              SrcList pSrc = (SrcList)va_arg( ap, "SrcList" );
              int k = (int)va_arg( ap, "int" );
              SrcList_item pItem = pSrc.a[k];
              Debug.Assert( k >= 0 && k < pSrc.nSrc );
              if ( pItem.zDatabase != null )
              {
                sqlite3StrAccumAppend( pAccum, pItem.zDatabase, -1 );
                sqlite3StrAccumAppend( pAccum, ".", 1 );
              }
              sqlite3StrAccumAppend( pAccum, pItem.zName, -1 );
              length = width = 0;
              break;
            }
          default:
            {
              Debug.Assert( xtype == etINVALID );
              return;
            }
        }/* End switch over the format type */
        /*
        ** The text of the conversion is pointed to by "bufpt" and is
        ** "length" characters long.  The field width is "width".  Do
        ** the output.
        */
        if ( !flag_leftjustify )
        {
          int nspace;
          nspace = width - length;// -2;
          if ( nspace > 0 )
          {
            appendSpace( pAccum, nspace );
          }
        }
        if ( length > 0 )
        {
          sqlite3StrAccumAppend( pAccum, new string( buf, bufpt, length ), length );
        }
        if ( flag_leftjustify )
        {
          int nspace;
          nspace = width - length;
          if ( nspace > 0 )
          {
            appendSpace( pAccum, nspace );
          }
        }
        //if( zExtra ){
        //  sqlite3DbFree(db,ref  zExtra);
        //}
      }/* End for loop over the format string */
    } /* End of function */
Beispiel #4
0
 public static extern int32_t va_list_test(va_list ap);
Beispiel #5
0
 public static void va_end(va_list argp)
 {
 }
Beispiel #6
0
 // First attempt
 public static void va_start(va_list argp, object dontcare)
 {
 }