Example #1
0
        public RString SubAt(params object[] args)
        {
            bool    iter    = false;
            RString repl    = null;
            bool    tainted = false;

/*
 *          if (args != null && args.Length == 1 && ruby.IsBlockGiven)
 *          {
 *              iter = true;
 *          }
 *          else
 */
            if (args != null && args.Length == 2)
            {
                repl    = StringToRString(ruby, args[1]);
                tainted = repl.IsTainted;
            }
            else
            {
                throw new eArgError(String.Format("wrong # of arguments({0} for 2)",
                                                  (args == null) ? 0 : args.Length));
            }
            RRegexp pat = GetPat(args[0]);

            if (pat.Search(ptr, 0, false, IsTainted) >= 0)
            {
                RThread    th    = ruby.GetCurrentContext();
                RMatchData match = (RMatchData)th.BackRef;
                int        beg   = match.Begin(0);
                int        len   = match.End(0) - beg;
                if (iter)
                {
/*
 *                  RRegexpClass.matchBusy(match);
 *                  repl = RString.AsRString(ruby, ruby.Yield(match[0]));
 *                  th.BackRef = match;        // rescue from yield.
 */
                }
                else
                {
                    repl = new RString(ruby, match.Sub(repl.ToString(), ptr));
                }
                if (repl.IsTainted)
                {
                    tainted = true;
                }
                StringBuilder sb = new StringBuilder(ptr);
                sb.Remove(beg, len);
                sb.Insert(beg, repl.ptr, 1);
                ptr = sb.ToString();
                if (tainted)
                {
                    Taint();
                }
                return(this);
            }
            return(null);
        }
Example #2
0
        static internal object s_quote(RBasic r, params object[] args)
        {
            if (args.Length < 1 || args.Length > 2)
            {
                throw new eArgError("wront # of argument");
            }
            string p = RString.ToString(r.ruby, args[0]);

            return(Regex.Escape(p));
        }
Example #3
0
        static internal object initialize(RBasic r, params object[] args)
        {
            if (args.Length < 1 || args.Length > 3)
            {
                throw new eArgError("wrong # of argument");
            }
            RegexOptions flag = RegexOptions.None;

            if (args.Length >= 2)
            {
                if (args[1] is int || args[1] is RegexOptions)
                {
                    flag = (RegexOptions)(int)args[1];
                }
                else if (args[1] is RFixnum)
                {
                    flag = (RegexOptions)((RFixnum)args[1]).ToInt();
                }
                else if (RBasic.RTest(args[1]))
                {
                    flag = RegexOptions.IgnoreCase;
                }
            }
            if (args.Length == 3)
            {
                // ignore char set
            }
            NetRuby ruby = r.ruby;
            RRegexp self = (RRegexp)r;

            if (args[0] is RRegexp)
            {
                RRegexp re = (RRegexp)args[0];
                re.Check();
                self.Initialize(re, flag);
            }
            else
            {
                string p = RString.ToString(ruby, args[0]);
                self.Initialize(p, flag);
            }
            return(self);
        }
Example #4
0
        static internal object match(RBasic r, params object[] args)
        {
            if (args[0] == null)
            {
                return(null);
            }
            NetRuby rb     = r.ruby;
            string  s      = RString.ToString(rb, args[0]);
            bool    infect = false;

            if (args[0] is RBasic && ((RBasic)args[0]).IsTainted)
            {
                infect = true;
            }
            int start = ((RRegexp)r).Search(s, 0, false, infect);

            if (start < 0)
            {
                return(null);
            }
            return(start);
        }
Example #5
0
        internal static object sprintf(RBasic r, params object[] args)
        {
            NetRuby ruby = r.ruby;

            PFlag  flags   = PFlag.NONE;
            bool   tainted = false;
            object ofmt;
            int    nextarg = getarg(args, 0, out ofmt);

            if (ofmt is RBasic)
            {
                tainted = ((RBasic)ofmt).IsTainted;
            }
            string fmt = ofmt.ToString();
            string result = String.Empty;
            int    width, prec;

            for (int i = 0; i < fmt.Length; i++)
            {
                int n, ix;
                for (ix = i; ix < fmt.Length && fmt[ix] != '%'; ix++)
                {
                    ;
                }
                result += fmt.Substring(i, ix - i);
                if (ix >= fmt.Length)
                {
                    break;
                }
                i     = ix + 1;
                width = prec = -1;
retry:
                switch (fmt[i])
                {
                case ' ':
                    flags |= PFlag.SPACE;
                    i++;
                    goto retry;

                case '#':
                    flags |= PFlag.SHARP;
                    i++;
                    goto retry;

                case '+':
                    flags |= PFlag.PLUS;
                    i++;
                    goto retry;

                case '-':
                    flags |= PFlag.MINUS;
                    i++;
                    goto retry;

                case '0':
                    flags |= PFlag.ZERO;
                    i++;
                    goto retry;

                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    n = 0;
                    for (; i < fmt.Length && Char.IsDigit(fmt[i]); i++)
                    {
                        n = 10 * n + (int)Char.GetNumericValue(fmt[i]);
                    }
                    if (i >= fmt.Length)
                    {
                        throw new ArgumentException("malformed format string - %%[0-9]");
                    }
                    if (fmt[i] == '$')
                    {
                        nextarg = n;
                        i++;
                        goto retry;
                    }
                    width  = n;
                    flags |= PFlag.WIDTH;
                    goto retry;

                case '*':
                    if ((flags & PFlag.WIDTH) != 0)
                    {
                        throw new ArgumentException("width given twice");
                    }
                    flags |= PFlag.WIDTH;
                    width  = getaster(fmt, ref i, ref nextarg, args);
                    if (width < 0)
                    {
                        flags |= PFlag.MINUS;
                        width  = -width;
                    }
                    i++;
                    goto retry;

                case '.':
                    if ((flags & PFlag.PREC) != 0)
                    {
                        throw new ArgumentException("precision given twice");
                    }
                    flags |= PFlag.PREC;
                    prec   = 0;
                    i++;
                    if (fmt[i] == '*')
                    {
                        prec = getaster(fmt, ref i, ref nextarg, args);
                        if (prec < 0)          /* ignore negative precision */
                        {
                            flags &= ~PFlag.PREC;
                        }
                        i++;
                        goto retry;
                    }
                    for (; i < fmt.Length && Char.IsDigit(fmt[i]); i++)
                    {
                        prec = 10 * prec + (int)Char.GetNumericValue(fmt[i]);
                    }
                    if (i >= fmt.Length)
                    {
                        throw new ArgumentException("malformed format string - %%.[0-9]");
                    }
                    goto retry;

                case '\n':
                    i--;
                    goto case '%';

                case '\0':
                case '%':
                    if (flags != PFlag.NONE)
                    {
                        throw new ArgumentException("illegal format character - %%");
                    }
                    result += '%';
                    break;

                case 'c': {
                    object val;
                    nextarg = getarg(args, nextarg, out val);
                    if ((flags & PFlag.MINUS) == 0)
                    {
                        if (width > 0)
                        {
                            result = result.PadRight(result.Length + width);
                        }
                    }
                    char c = (char)Convert.ToInt32(val);
                    result += c;
                    result  = result.PadRight(result.Length + width);
                    break;
                }

                case 's': {
                    object arg;
                    nextarg = getarg(args, nextarg, out arg);
                    RString rs = RString.AsRString(ruby, arg);
                    if (rs.IsTainted)
                    {
                        tainted = true;
                    }
                    int len = rs.Length;
                    if ((flags & PFlag.PREC) != 0)
                    {
                        if (prec < len)
                        {
                            len = prec;
                        }
                    }
                    if ((flags & PFlag.WIDTH) != 0)
                    {
                        if (width > len)
                        {
                            width -= len;
                            if ((flags & PFlag.MINUS) == 0)
                            {
                                if (width > 0)
                                {
                                    result = result.PadRight(result.Length + width);
                                }
                            }
                            result += rs.ToString();
                            if ((flags & PFlag.MINUS) != 0)
                            {
                                if (width > 0)
                                {
                                    result = result.PadRight(result.Length + width);
                                }
                            }
                            break;
                        }
                    }
                    result += rs.ToString().Substring(0, len);
                    break;
                }

                case 'd':
                case 'i':
                case 'o':
                case 'x':
                case 'X':
                case 'b':
                case 'u': {
                    char   sc = '\0';
                    char   ch = fmt[i];
                    object val;
                    nextarg = getarg(args, nextarg, out val);
                    bool   sign   = false;
                    bool   bignum = false;
                    long   num    = 0;
                    string prefix = String.Empty;
                    string s      = String.Empty;
                    switch (ch)
                    {
                    case 'd':
                    case 'i':
                        sign = true; break;

                    case 'o':
                    case 'x':
                    case 'X':
                    case 'b':
                    case 'u':
                    default:
                        if ((flags & (PFlag.PLUS | PFlag.SPACE)) != 0)
                        {
                            sign = true;
                        }
                        break;
                    }
                    if ((flags & PFlag.SHARP) != 0)
                    {
                        if (fmt[i] == 'o')
                        {
                            prefix = "0";
                        }
                        else if (fmt[i] == 'x')
                        {
                            prefix = "0x";
                        }
                        else if (fmt[i] == 'X')
                        {
                            prefix = "0X";
                        }
                        else if (fmt[i] == 'b')
                        {
                            prefix = "0b";
                        }
                        if (prefix.Length > 0)
                        {
                            width -= prefix.Length;
                        }
                    }
bin_retry:
                    if (val is RFloat)
                    {
                        val = ((RFloat)val).ToInteger();
                        goto bin_retry;
                    }
                    else if (val is double)
                    {
                        val = RFloat.ToInteger(ruby, (double)val);
                        goto bin_retry;
                    }
                    else if (val is string)
                    {
                        val = RInteger.StringToInteger(ruby, (string)val, 0);
                        goto bin_retry;
                    }
                    else if (val is RString)
                    {
                        val = ((RString)val).ToInteger();
                        goto bin_retry;
                    }
                    else if (val is int)
                    {
                        num = (long)(int)val;
                    }
                    else if (val is long)
                    {
                        num = (long)val;
                    }
                    else if (val is uint)
                    {
                        num = (long)(uint)val;
                    }
                    else if (val is RBignum)
                    {
                        bignum = true;
                    }
                    else
                    {
                        num = RInteger.ToLong(ruby, val);
                    }
                    int bas = 0;
                    if (ch == 'u' || ch == 'd' || ch == 'i')
                    {
                        bas = 10;
                    }
                    else if (ch == 'x' || ch == 'X')
                    {
                        bas = 16;
                    }
                    else if (ch == 'o')
                    {
                        bas = 8;
                    }
                    else if (ch == 'b')
                    {
                        bas = 2;
                    }
                    if (!bignum)
                    {
                        if (sign)
                        {
                            if (ch == 'i')
                            {
                                ch = 'd';            /* %d and %i are identical */
                            }
                            if (num < 0)
                            {
                                num = -num;
                                sc  = '-';
                                width--;
                            }
                            else if ((flags & PFlag.PLUS) != 0)
                            {
                                sc = '+';
                                width--;
                            }
                            else if ((flags & PFlag.SPACE) != 0)
                            {
                                sc = ' ';
                                width--;
                            }
                            s = Convert.ToString(num, bas);
                            goto format_integer;
                        }
                        else
                        {
                            s = Convert.ToString(num, bas);
                            goto format_integer;
                        }
                    }
                    // bignum
                    RBignum big = (RBignum)val;
                    if (sign)
                    {
                        s = big.ToRString(bas).ToString();
                        if (s[0] == '-')
                        {
                            s  = s.Substring(1);
                            sc = '-';
                            width--;
                        }
                        else if ((flags & PFlag.PLUS) != 0)
                        {
                            sc = '+';
                            width--;
                        }
                        else if ((flags & PFlag.SPACE) != 0)
                        {
                            sc = ' ';
                            width--;
                        }
                        goto format_integer;
                    }
                    if (big.Sign == false)
                    {
                        big = (RBignum)big.Clone();
                        big.TwoComp();
                    }
                    s = big.ToRString(bas).ToString();
                    if (s[0] == '-')
                    {
                        s = remove_sign_bits(s.Substring(1), bas);
                        StringBuilder sb = new StringBuilder(s.Length + 3);
                        sb.Append("..");
                        switch (bas)
                        {
                        case 16:
                            if (s[0] != 'f')
                            {
                                sb.Append('f');
                            }
                            break;

                        case 8:
                            if (s[0] != '7')
                            {
                                sb.Append('7');
                            }
                            break;
                        }
                        sb.Append(s);
                        s = sb.ToString();
                    }

format_integer:
                    int pos = -1;
                    int len = s.Length;

                    if (ch == 'X')
                    {
                        s = s.ToUpper();
                    }
                    if (prec < len)
                    {
                        prec = len;
                    }
                    width -= prec;
                    if ((flags & (PFlag.ZERO | PFlag.MINUS)) == 0 && s[0] != '.')
                    {
                        if (width > 0)
                        {
                            s = s.PadLeft(s.Length + width);
                        }
                    }
                    if (sc != '\0')
                    {
                        result += sc;
                    }
                    if (prefix.Length > 0)
                    {
                        result += prefix;
                        if (pos != 0)
                        {
                            pos += prefix.Length;
                        }
                    }
                    if ((flags & PFlag.MINUS) == 0)
                    {
                        char c = ' ';

                        if (s[0] == '.')
                        {
                            c = '.';
                            if ((flags & PFlag.PREC) != 0 && prec > len)
                            {
                                pos = result.Length;
                            }
                            else
                            {
                                pos = result.Length + 2;
                            }
                        }
                        else if ((flags & PFlag.ZERO) != 0)
                        {
                            c = '0';
                        }
                        if (width > 0)
                        {
                            result = result.PadRight(result.Length + width, c);
                        }
                    }
                    if (len < prec)
                    {
                        if (width > 0)
                        {
                            result = result.PadRight(result.Length + (prec - len), (s[0] == '.'?'.':'0'));
                        }
                    }
                    result += s;
                    if (width > 0)
                    {
                        result = result.PadRight(result.Length + width);
                    }
                    break;
                }

                case 'f':
                case 'g':
                case 'G':
                case 'e':
                case 'E': {
                    object val;
                    nextarg = getarg(args, nextarg, out val);
                    double fval = 0.0;

                    if (val is RString || val is string)
                    {
                        fval = Convert.ToDouble(((RString)val).ToString());
                    }
                    else if (val is int || val is long || val is uint)
                    {
                        fval = Convert.ToDouble(val);
                    }
                    else if (val is RFloat)
                    {
                        fval = ((RFloat)val).Double;
                    }
                    else if (val is double)
                    {
                        fval = (double)val;
                    }

                    string buf;
                    if (fmt[i] != 'e' && fmt[i] != 'E')
                    {
                        buf = new String(fmt[i], 1);
                        if ((flags & PFlag.PREC) != 0)
                        {
                            buf += prec.ToString();
                        }
                    }
                    else
                    {
                        buf = "#";
                        if ((flags & PFlag.SHARP) != 0)
                        {
                            buf += ".0";
                        }
                        buf += fmt[i];
                        if ((flags & PFlag.PLUS) != 0)
                        {
                            buf += '+';
                        }
                        if ((flags & PFlag.PREC) != 0)
                        {
                            buf += new String('0', prec);
                        }
                        else
                        {
                            buf += '0';
                        }
                    }
                    buf = fval.ToString(buf);
                    if ((flags & PFlag.WIDTH) != 0)
                    {
                    }
                    result += buf;
                    break;
                }

                default:
                    throw new ArgumentException(String.Format("malformed format string - %{0}", fmt[i]));
                }
                flags = PFlag.NONE;
            }
            if (tainted)
            {
                return(new RString(ruby, result, true));
            }
            return(result);
        }
Example #6
0
        public RString GsubAt(params object[] args)
        {
            bool    iter    = false;
            RString repl    = null;
            bool    tainted = false;

/*
 *          if (args != null && args.Length == 1 && ruby.IsBlockGiven)
 *          {
 *              iter = true;
 *          }
 *          else
 */
            if (args != null && args.Length == 2)
            {
                repl    = StringToRString(ruby, args[1]);
                tainted = repl.IsTainted;
            }
            else
            {
                throw new eArgError(String.Format("wrong # of arguments({0} for 2)",
                                                  (args == null) ? 0 : args.Length));
            }
            RRegexp pat = GetPat(args[0]);
            int     beg = pat.Search(ptr, 0, false, IsTainted);

            if (beg < 0)
            {
                return(null);
            }

            StringBuilder sb     = new StringBuilder();
            RThread       th     = ruby.GetCurrentContext();
            int           offset = 0;
            RMatchData    match  = null;

            while (beg >= 0)
            {
                string val;
                match = (RMatchData)th.BackRef;
                beg   = match.Begin(0);
                int len = match.End(0) - beg;

                /*
                 * if (iter)
                 * {
                 *
                 *  RRegexpClass.matchBusy(match);
                 *  repl = RString.AsRString(ruby, ruby.Yield(match[0]));
                 *  th.BackRef = match;        // rescue from yield.
                 *  if (repl.IsTainted) tainted = true;
                 *  val = repl.ToString();
                 *
                 * }
                 * else
                 */
                {
                    val = match.Sub(repl.ToString(), ptr);
                }
                if (beg > offset)
                {
                    sb.Append(ptr, offset, beg - offset);
                }
                sb.Append(val);
                if (len == 0)
                {
                    if (ptr.Length > match.End(0))
                    {
                        sb.Append(ptr, match.End(0), 1);
                    }
                    offset = beg + 1;
                }
                else
                {
                    offset = beg + len;
                }
                if (offset > ptr.Length)
                {
                    break;
                }
                beg = pat.Search(ptr, offset, false, IsTainted);
            }
            if (ptr.Length > offset)
            {
                sb.Append(ptr, offset, ptr.Length - offset);
            }
            th.BackRef = match;        // rescue from yield.
            ptr        = sb.ToString();
            if (tainted)
            {
                Taint();
            }
            return(this);
        }