Beispiel #1
0
 private void ResetState()
 {
     _varesc  = VariableEscapeState.Flag;
     _escape  = EngineState.Regular;
     _numsign = false;
     _signed  = false;
     _aleft   = false;
     _0pad    = false;
     _aindex  = 0;
     _cindex  = 0;
     _wdh     = "";
     _prc     = "";
 }
Beispiel #2
0
        private string ProcessCharacters(string chars, object[] args)
        {
            char first = chars[0];

            switch (_escape)
            {
            case EngineState.Regular:
                switch (first)
                {
                case '\\':
                    _escape = EngineState.BackslashEscape;

                    return("");

                case '%':
                    _escape = EngineState.VariableEscape;
                    _varesc = VariableEscapeState.Flag;

                    return("");

                default:
                    return(chars);
                }

            case EngineState.BackslashEscape:
                _escape = EngineState.Regular;

                switch (first)
                {
                case 'r':
                    return("\r");

                case 'n':
                    return("\n");

                case 't':
                    return("\t");

                case 'v':
                    return("\x0b");

                case 'b':
                    return("\x08");

                case 'a':
                    return("\x07");

                case 'f':
                    return("\x0c");

                case 'd':
                    return("\x7f");

                case '0':
                    return("\0");

                case '\\':
                    return("\\");

                case 'x':
                    string hex = GetNextChars(2);

                    return(((char)int.Parse(hex, NumberStyles.HexNumber)).ToString());

                case 'u':
                    string unc = GetNextChars(4);

                    return(((char)int.Parse(unc, NumberStyles.HexNumber)).ToString());

                default:
                    return(chars);
                }

            case EngineState.VariableEscape:
                switch (_varesc)
                {
                case VariableEscapeState.Flag:
                    switch (first)
                    {
                    case '-':
                        _aleft = true;

                        break;

                    case '+':
                        _signed = true;

                        break;

                    case '0':
                        _varesc = VariableEscapeState.Width;
                        _0pad   = true;

                        break;

                    case '#':
                        _numsign = true;

                        break;

                    default:
                        if (char.IsDigit(first))
                        {
                            _varesc = VariableEscapeState.Width;
                        }
                        else if (first == '.')
                        {
                            _varesc = VariableEscapeState.Precision;
                        }
                        else
                        {
                            _varesc = VariableEscapeState.Type;
                            BackPaddle();
                        }

                        break;
                    }

                    return("");

                case VariableEscapeState.Width:
                    if (char.IsDigit(first))
                    {
                        _wdh += first;
                    }
                    else if (first == '.')
                    {
                        _varesc = VariableEscapeState.Precision;
                    }
                    else
                    {
                        _varesc = VariableEscapeState.Type;
                        BackPaddle();
                    }

                    return("");

                case VariableEscapeState.Precision:
                    if (char.IsDigit(first))
                    {
                        _prc += first;
                    }
                    else
                    {
                        _varesc = VariableEscapeState.Type;
                        BackPaddle();
                    }

                    return("");

                case VariableEscapeState.Type:
                    object param     = (_aindex < args.Length ? args[_aindex] : null) ?? AutoItVariantType.Empty;
                    long   precision = long.Parse('0' + _prc);
                    long   width     = long.Parse('0' + _wdh);
                    string prefix    = "";
                    string res       = "";
                    char?  sig       = null;

                    _aindex++;
                    _escape = EngineState.Regular;

                    switch (first)
                    {
                    case 'd':
                    case 'i':
                    {
                        long val = (long)param;

                        if (val < 0)
                        {
                            sig   = '-';
                            val   = -val;
                            _0pad = false;
                        }
                        else if (_signed)
                        {
                            sig = '+';
                        }

                        res = val.ToString();

                        break;
                    }

                    case 'u':
                        res = ((ulong)param).ToString();

                        break;

                    case 'x':
                    case 'X':
                        res = ((ulong)param).ToString(first.ToString());

                        if (_numsign)
                        {
                            prefix = $"0{first}";
                        }

                        break;

                    case 'o':
                    case 'O':
                        res = Convert.ToString((long)param, 8);

                        if (_numsign)
                        {
                            prefix = "0";
                        }

                        break;

                    case 'b':
                    case 'B':
                        res = Convert.ToString((long)param, 2);

                        if (_numsign)
                        {
                            prefix = "0b";
                        }

                        break;

                    case 'f':
                    case 'F':
                    case 'g':
                    case 'G':
                        res = ((decimal)param).ToString();

                        if ((_numsign || precision > 0) && !res.Contains("."))
                        {
                            res += ".0";
                        }

                        int idx = res.IndexOf('.');

                        if ((idx > 0) && (precision > 0) && (res.Length - (idx + 1) < precision))
                        {
                            res += new string('0', (int)(precision - res.Length + idx + 1));             // TODO: ?
                        }
                        if (char.ToLower(first) == 'f')
                        {
                            res = res.Remove((int)(idx + precision));
                        }

                        break;

                    case 'e':
                    case 'E':

                        // TODO
#warning TODO

                        break;

                    case 'a':
                    case 'A':
                        if (param is AutoItVariantType variant)
                        {
                            _0pad = false;

                            if (variant.IsString)
                            {
                                res = variant.ToString();
                            }
                            else if (variant.IsArray)
                            {
                                res = variant.ToArrayString();
                            }
                            else if (variant.IsObject)
                            {
                                res = variant.ToCOMString();
                            }

                            break;
                        }
                        else
                        {
                            goto case 's';
                        }

                    case 's':
                        _0pad = false;
                        res   = param.ToString();

                        break;

                    default:
                        throw new InvalidOperationException();
                    }

                    if (sig is char c)
                    {
                        prefix += c;
                    }

                    if (res.Length + prefix.Length < width)
                    {
                        if (_aleft)
                        {
                            res = prefix + res + new string(' ', (int)(width - res.Length));
                        }
                        else if (_0pad)
                        {
                            res = prefix + new string('0', (int)(width - res.Length)) + res;
                        }
                        else
                        {
                            res = new string(' ', (int)(width - res.Length)) + prefix + res;
                        }
                    }

                    return(res);
                }

                break;
            }

            throw new InvalidOperationException();
        }