1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168 |
- Sk.builtin.interned = {};
- /**
- * @constructor
- * @param {*} x
- * @extends Sk.builtin.object
- */
- Sk.builtin.str = function (x) {
- var ret;
- if (x === undefined) {
- x = "";
- }
- if (x instanceof Sk.builtin.str) {
- return x;
- }
- if (!(this instanceof Sk.builtin.str)) {
- return new Sk.builtin.str(x);
- }
- // convert to js string
- if (x === true) {
- ret = "True";
- } else if (x === false) {
- ret = "False";
- } else if ((x === null) || (x instanceof Sk.builtin.none)) {
- ret = "None";
- } else if (x instanceof Sk.builtin.bool) {
- if (x.v) {
- ret = "True";
- } else {
- ret = "False";
- }
- } else if (typeof x === "number") {
- ret = x.toString();
- if (ret === "Infinity") {
- ret = "inf";
- } else if (ret === "-Infinity") {
- ret = "-inf";
- }
- } else if (typeof x === "string") {
- ret = x;
- } else if (x.tp$str !== undefined) {
- ret = x.tp$str();
- if (!(ret instanceof Sk.builtin.str)) {
- throw new Sk.builtin.ValueError("__str__ didn't return a str");
- }
- return ret;
- } else {
- return Sk.misceval.objectRepr(x);
- }
- // interning required for strings in py
- if (Sk.builtin.interned["1" + ret]) {
- return Sk.builtin.interned["1" + ret];
- }
- this.__class__ = Sk.builtin.str;
- this.v = ret;
- this["v"] = this.v;
- Sk.builtin.interned["1" + ret] = this;
- return this;
- };
- goog.exportSymbol("Sk.builtin.str", Sk.builtin.str);
- Sk.abstr.setUpInheritance("str", Sk.builtin.str, Sk.builtin.seqtype);
- Sk.builtin.str.prototype.mp$subscript = function (index) {
- var ret;
- if (Sk.misceval.isIndex(index)) {
- index = Sk.misceval.asIndex(index);
- if (index < 0) {
- index = this.v.length + index;
- }
- if (index < 0 || index >= this.v.length) {
- throw new Sk.builtin.IndexError("string index out of range");
- }
- return new Sk.builtin.str(this.v.charAt(index));
- } else if (index instanceof Sk.builtin.slice) {
- ret = "";
- index.sssiter$(this, function (i, wrt) {
- if (i >= 0 && i < wrt.v.length) {
- ret += wrt.v.charAt(i);
- }
- });
- return new Sk.builtin.str(ret);
- } else {
- throw new Sk.builtin.TypeError("string indices must be integers, not " + Sk.abstr.typeName(index));
- }
- };
- Sk.builtin.str.prototype.sq$length = function () {
- return this.v.length;
- };
- Sk.builtin.str.prototype.sq$concat = function (other) {
- var otypename;
- if (!other || !Sk.builtin.checkString(other)) {
- otypename = Sk.abstr.typeName(other);
- throw new Sk.builtin.TypeError("cannot concatenate 'str' and '" + otypename + "' objects");
- }
- return new Sk.builtin.str(this.v + other.v);
- };
- Sk.builtin.str.prototype.nb$add = Sk.builtin.str.prototype.sq$concat;
- Sk.builtin.str.prototype.nb$inplace_add = Sk.builtin.str.prototype.sq$concat;
- Sk.builtin.str.prototype.sq$repeat = function (n) {
- var i;
- var ret;
- if (!Sk.misceval.isIndex(n)) {
- throw new Sk.builtin.TypeError("can't multiply sequence by non-int of type '" + Sk.abstr.typeName(n) + "'");
- }
- n = Sk.misceval.asIndex(n);
- ret = "";
- for (i = 0; i < n; ++i) {
- ret += this.v;
- }
- return new Sk.builtin.str(ret);
- };
- Sk.builtin.str.prototype.nb$multiply = Sk.builtin.str.prototype.sq$repeat;
- Sk.builtin.str.prototype.nb$inplace_multiply = Sk.builtin.str.prototype.sq$repeat;
- Sk.builtin.str.prototype.sq$item = function () {
- goog.asserts.fail();
- };
- Sk.builtin.str.prototype.sq$slice = function (i1, i2) {
- i1 = Sk.builtin.asnum$(i1);
- i2 = Sk.builtin.asnum$(i2);
- if (i1 < 0) {
- i1 = 0;
- }
- return new Sk.builtin.str(this.v.substr(i1, i2 - i1));
- };
- Sk.builtin.str.prototype.sq$contains = function (ob) {
- if (!(ob instanceof Sk.builtin.str)) {
- throw new Sk.builtin.TypeError("TypeError: 'In <string> requires string as left operand");
- }
- return this.v.indexOf(ob.v) != -1;
- };
- Sk.builtin.str.prototype.__iter__ = new Sk.builtin.func(function (self) {
- return new Sk.builtin.str_iter_(self);
- });
- Sk.builtin.str.prototype.tp$iter = function () {
- return new Sk.builtin.str_iter_(this);
- };
- Sk.builtin.str.prototype.tp$richcompare = function (other, op) {
- if (!(other instanceof Sk.builtin.str)) {
- return undefined;
- }
- switch (op) {
- case "Lt":
- return this.v < other.v;
- case "LtE":
- return this.v <= other.v;
- case "Eq":
- return this.v === other.v;
- case "NotEq":
- return this.v !== other.v;
- case "Gt":
- return this.v > other.v;
- case "GtE":
- return this.v >= other.v;
- default:
- goog.asserts.fail();
- }
- };
- Sk.builtin.str.prototype["$r"] = function () {
- // single is preferred
- var ashex;
- var c;
- var i;
- var ret;
- var len;
- var quote = "'";
- //jshint ignore:start
- if (this.v.indexOf("'") !== -1 && this.v.indexOf('"') === -1) {
- quote = '"';
- }
- //jshint ignore:end
- len = this.v.length;
- ret = quote;
- for (i = 0; i < len; ++i) {
- c = this.v.charAt(i);
- if (c === quote || c === "\\") {
- ret += "\\" + c;
- } else if (c === "\t") {
- ret += "\\t";
- } else if (c === "\n") {
- ret += "\\n";
- } else if (c === "\r") {
- ret += "\\r";
- } else if (c < " " || c >= 0x7f) {
- ashex = c.charCodeAt(0).toString(16);
- if (ashex.length < 2) {
- ashex = "0" + ashex;
- }
- ret += "\\x" + ashex;
- } else {
- ret += c;
- }
- }
- ret += quote;
- return new Sk.builtin.str(ret);
- };
- Sk.builtin.str.re_escape_ = function (s) {
- var c;
- var i;
- var ret = [];
- var re = /^[A-Za-z0-9]+$/;
- for (i = 0; i < s.length; ++i) {
- c = s.charAt(i);
- if (re.test(c)) {
- ret.push(c);
- } else {
- if (c === "\\000") {
- ret.push("\\000");
- } else {
- ret.push("\\" + c);
- }
- }
- }
- return ret.join("");
- };
- Sk.builtin.str.prototype["lower"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("lower", arguments, 1, 1);
- return new Sk.builtin.str(self.v.toLowerCase());
- });
- Sk.builtin.str.prototype["upper"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("upper", arguments, 1, 1);
- return new Sk.builtin.str(self.v.toUpperCase());
- });
- Sk.builtin.str.prototype["capitalize"] = new Sk.builtin.func(function (self) {
- var i;
- var cap;
- var orig;
- Sk.builtin.pyCheckArgs("capitalize", arguments, 1, 1);
- orig = self.v;
- if (orig.length === 0) {
- return new Sk.builtin.str("");
- }
- cap = orig.charAt(0).toUpperCase();
- for (i = 1; i < orig.length; i++) {
- cap += orig.charAt(i).toLowerCase();
- }
- return new Sk.builtin.str(cap);
- });
- Sk.builtin.str.prototype["join"] = new Sk.builtin.func(function (self, seq) {
- var it, i;
- var arrOfStrs;
- Sk.builtin.pyCheckArgs("join", arguments, 2, 2);
- Sk.builtin.pyCheckType("seq", "iterable", Sk.builtin.checkIterable(seq));
- arrOfStrs = [];
- for (it = seq.tp$iter(), i = it.tp$iternext(); i !== undefined; i = it.tp$iternext()) {
- if (i.constructor !== Sk.builtin.str) {
- throw new Sk.builtin.TypeError("TypeError: sequence item " + arrOfStrs.length + ": expected string, " + typeof i + " found");
- }
- arrOfStrs.push(i.v);
- }
- return new Sk.builtin.str(arrOfStrs.join(self.v));
- });
- Sk.builtin.str.prototype["split"] = new Sk.builtin.func(function (self, on, howmany) {
- var splits;
- var index;
- var match;
- var result;
- var s;
- var str;
- var regex;
- Sk.builtin.pyCheckArgs("split", arguments, 1, 3);
- if ((on === undefined) || (on instanceof Sk.builtin.none)) {
- on = null;
- }
- if ((on !== null) && !Sk.builtin.checkString(on)) {
- throw new Sk.builtin.TypeError("expected a string");
- }
- if ((on !== null) && on.v === "") {
- throw new Sk.builtin.ValueError("empty separator");
- }
- if ((howmany !== undefined) && !Sk.builtin.checkInt(howmany)) {
- throw new Sk.builtin.TypeError("an integer is required");
- }
- howmany = Sk.builtin.asnum$(howmany);
- regex = /[\s]+/g;
- str = self.v;
- if (on === null) {
- str = goog.string.trimLeft(str);
- } else {
- // Escape special characters in "on" so we can use a regexp
- s = on.v.replace(/([.*+?=|\\\/()\[\]\{\}^$])/g, "\\$1");
- regex = new RegExp(s, "g");
- }
- // This is almost identical to re.split,
- // except how the regexp is constructed
- result = [];
- index = 0;
- splits = 0;
- while ((match = regex.exec(str)) != null) {
- if (match.index === regex.lastIndex) {
- // empty match
- break;
- }
- result.push(new Sk.builtin.str(str.substring(index, match.index)));
- index = regex.lastIndex;
- splits += 1;
- if (howmany && (splits >= howmany)) {
- break;
- }
- }
- str = str.substring(index);
- if (on !== null || (str.length > 0)) {
- result.push(new Sk.builtin.str(str));
- }
- return new Sk.builtin.list(result);
- });
- Sk.builtin.str.prototype["strip"] = new Sk.builtin.func(function (self, chars) {
- var regex;
- var pattern;
- Sk.builtin.pyCheckArgs("strip", arguments, 1, 2);
- if ((chars !== undefined) && !Sk.builtin.checkString(chars)) {
- throw new Sk.builtin.TypeError("strip arg must be None or str");
- }
- if (chars === undefined) {
- pattern = /^\s+|\s+$/g;
- } else {
- regex = Sk.builtin.str.re_escape_(chars.v);
- pattern = new RegExp("^[" + regex + "]+|[" + regex + "]+$", "g");
- }
- return new Sk.builtin.str(self.v.replace(pattern, ""));
- });
- Sk.builtin.str.prototype["lstrip"] = new Sk.builtin.func(function (self, chars) {
- var regex;
- var pattern;
- Sk.builtin.pyCheckArgs("lstrip", arguments, 1, 2);
- if ((chars !== undefined) && !Sk.builtin.checkString(chars)) {
- throw new Sk.builtin.TypeError("lstrip arg must be None or str");
- }
- if (chars === undefined) {
- pattern = /^\s+/g;
- } else {
- regex = Sk.builtin.str.re_escape_(chars.v);
- pattern = new RegExp("^[" + regex + "]+", "g");
- }
- return new Sk.builtin.str(self.v.replace(pattern, ""));
- });
- Sk.builtin.str.prototype["rstrip"] = new Sk.builtin.func(function (self, chars) {
- var regex;
- var pattern;
- Sk.builtin.pyCheckArgs("rstrip", arguments, 1, 2);
- if ((chars !== undefined) && !Sk.builtin.checkString(chars)) {
- throw new Sk.builtin.TypeError("rstrip arg must be None or str");
- }
- if (chars === undefined) {
- pattern = /\s+$/g;
- } else {
- regex = Sk.builtin.str.re_escape_(chars.v);
- pattern = new RegExp("[" + regex + "]+$", "g");
- }
- return new Sk.builtin.str(self.v.replace(pattern, ""));
- });
- Sk.builtin.str.prototype["partition"] = new Sk.builtin.func(function (self, sep) {
- var pos;
- var sepStr;
- Sk.builtin.pyCheckArgs("partition", arguments, 2, 2);
- Sk.builtin.pyCheckType("sep", "string", Sk.builtin.checkString(sep));
- sepStr = new Sk.builtin.str(sep);
- pos = self.v.indexOf(sepStr.v);
- if (pos < 0) {
- return new Sk.builtin.tuple([self, Sk.builtin.str.$emptystr, Sk.builtin.str.$emptystr]);
- }
- return new Sk.builtin.tuple([
- new Sk.builtin.str(self.v.substring(0, pos)),
- sepStr,
- new Sk.builtin.str(self.v.substring(pos + sepStr.v.length))]);
- });
- Sk.builtin.str.prototype["rpartition"] = new Sk.builtin.func(function (self, sep) {
- var pos;
- var sepStr;
- Sk.builtin.pyCheckArgs("rpartition", arguments, 2, 2);
- Sk.builtin.pyCheckType("sep", "string", Sk.builtin.checkString(sep));
- sepStr = new Sk.builtin.str(sep);
- pos = self.v.lastIndexOf(sepStr.v);
- if (pos < 0) {
- return new Sk.builtin.tuple([Sk.builtin.str.$emptystr, Sk.builtin.str.$emptystr, self]);
- }
- return new Sk.builtin.tuple([
- new Sk.builtin.str(self.v.substring(0, pos)),
- sepStr,
- new Sk.builtin.str(self.v.substring(pos + sepStr.v.length))]);
- });
- Sk.builtin.str.prototype["count"] = new Sk.builtin.func(function (self, pat, start, end) {
- var normaltext;
- var ctl;
- var slice;
- var m;
- Sk.builtin.pyCheckArgs("count", arguments, 2, 4);
- if (!Sk.builtin.checkString(pat)) {
- throw new Sk.builtin.TypeError("expected a character buffer object");
- }
- if ((start !== undefined) && !Sk.builtin.checkInt(start)) {
- throw new Sk.builtin.TypeError("slice indices must be integers or None or have an __index__ method");
- }
- if ((end !== undefined) && !Sk.builtin.checkInt(end)) {
- throw new Sk.builtin.TypeError("slice indices must be integers or None or have an __index__ method");
- }
- if (start === undefined) {
- start = 0;
- } else {
- start = Sk.builtin.asnum$(start);
- start = start >= 0 ? start : self.v.length + start;
- }
- if (end === undefined) {
- end = self.v.length;
- } else {
- end = Sk.builtin.asnum$(end);
- end = end >= 0 ? end : self.v.length + end;
- }
- normaltext = pat.v.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
- m = new RegExp(normaltext, "g");
- slice = self.v.slice(start, end);
- ctl = slice.match(m);
- if (!ctl) {
- return new Sk.builtin.int_(0);
- } else {
- return new Sk.builtin.int_(ctl.length);
- }
- });
- Sk.builtin.str.prototype["ljust"] = new Sk.builtin.func(function (self, len, fillchar) {
- var newstr;
- Sk.builtin.pyCheckArgs("ljust", arguments, 2, 3);
- if (!Sk.builtin.checkInt(len)) {
- throw new Sk.builtin.TypeError("integer argument exepcted, got " + Sk.abstr.typeName(len));
- }
- if ((fillchar !== undefined) && (!Sk.builtin.checkString(fillchar) || fillchar.v.length !== 1)) {
- throw new Sk.builtin.TypeError("must be char, not " + Sk.abstr.typeName(fillchar));
- }
- if (fillchar === undefined) {
- fillchar = " ";
- } else {
- fillchar = fillchar.v;
- }
- len = Sk.builtin.asnum$(len);
- if (self.v.length >= len) {
- return self;
- } else {
- newstr = Array.prototype.join.call({length: Math.floor(len - self.v.length) + 1}, fillchar);
- return new Sk.builtin.str(self.v + newstr);
- }
- });
- Sk.builtin.str.prototype["rjust"] = new Sk.builtin.func(function (self, len, fillchar) {
- var newstr;
- Sk.builtin.pyCheckArgs("rjust", arguments, 2, 3);
- if (!Sk.builtin.checkInt(len)) {
- throw new Sk.builtin.TypeError("integer argument exepcted, got " + Sk.abstr.typeName(len));
- }
- if ((fillchar !== undefined) && (!Sk.builtin.checkString(fillchar) || fillchar.v.length !== 1)) {
- throw new Sk.builtin.TypeError("must be char, not " + Sk.abstr.typeName(fillchar));
- }
- if (fillchar === undefined) {
- fillchar = " ";
- } else {
- fillchar = fillchar.v;
- }
- len = Sk.builtin.asnum$(len);
- if (self.v.length >= len) {
- return self;
- } else {
- newstr = Array.prototype.join.call({length: Math.floor(len - self.v.length) + 1}, fillchar);
- return new Sk.builtin.str(newstr + self.v);
- }
- });
- Sk.builtin.str.prototype["center"] = new Sk.builtin.func(function (self, len, fillchar) {
- var newstr;
- var newstr1;
- Sk.builtin.pyCheckArgs("center", arguments, 2, 3);
- if (!Sk.builtin.checkInt(len)) {
- throw new Sk.builtin.TypeError("integer argument exepcted, got " + Sk.abstr.typeName(len));
- }
- if ((fillchar !== undefined) && (!Sk.builtin.checkString(fillchar) || fillchar.v.length !== 1)) {
- throw new Sk.builtin.TypeError("must be char, not " + Sk.abstr.typeName(fillchar));
- }
- if (fillchar === undefined) {
- fillchar = " ";
- } else {
- fillchar = fillchar.v;
- }
- len = Sk.builtin.asnum$(len);
- if (self.v.length >= len) {
- return self;
- } else {
- newstr1 = Array.prototype.join.call({length: Math.floor((len - self.v.length) / 2) + 1}, fillchar);
- newstr = newstr1 + self.v + newstr1;
- if (newstr.length < len) {
- newstr = newstr + fillchar;
- }
- return new Sk.builtin.str(newstr);
- }
- });
- Sk.builtin.str.prototype["find"] = new Sk.builtin.func(function (self, tgt, start, end) {
- var idx;
- Sk.builtin.pyCheckArgs("find", arguments, 2, 4);
- if (!Sk.builtin.checkString(tgt)) {
- throw new Sk.builtin.TypeError("expected a character buffer object");
- }
- if ((start !== undefined) && !Sk.builtin.checkInt(start)) {
- throw new Sk.builtin.TypeError("slice indices must be integers or None or have an __index__ method");
- }
- if ((end !== undefined) && !Sk.builtin.checkInt(end)) {
- throw new Sk.builtin.TypeError("slice indices must be integers or None or have an __index__ method");
- }
- if (start === undefined) {
- start = 0;
- } else {
- start = Sk.builtin.asnum$(start);
- start = start >= 0 ? start : self.v.length + start;
- }
- if (end === undefined) {
- end = self.v.length;
- } else {
- end = Sk.builtin.asnum$(end);
- end = end >= 0 ? end : self.v.length + end;
- }
- idx = self.v.indexOf(tgt.v, start);
- idx = ((idx >= start) && (idx < end)) ? idx : -1;
- return new Sk.builtin.int_(idx);
- });
- Sk.builtin.str.prototype["index"] = new Sk.builtin.func(function (self, tgt, start, end) {
- var idx;
- Sk.builtin.pyCheckArgs("index", arguments, 2, 4);
- idx = Sk.misceval.callsim(self["find"], self, tgt, start, end);
- if (Sk.builtin.asnum$(idx) === -1) {
- throw new Sk.builtin.ValueError("substring not found");
- }
- return idx;
- });
- Sk.builtin.str.prototype["rfind"] = new Sk.builtin.func(function (self, tgt, start, end) {
- var idx;
- Sk.builtin.pyCheckArgs("rfind", arguments, 2, 4);
- if (!Sk.builtin.checkString(tgt)) {
- throw new Sk.builtin.TypeError("expected a character buffer object");
- }
- if ((start !== undefined) && !Sk.builtin.checkInt(start)) {
- throw new Sk.builtin.TypeError("slice indices must be integers or None or have an __index__ method");
- }
- if ((end !== undefined) && !Sk.builtin.checkInt(end)) {
- throw new Sk.builtin.TypeError("slice indices must be integers or None or have an __index__ method");
- }
- if (start === undefined) {
- start = 0;
- } else {
- start = Sk.builtin.asnum$(start);
- start = start >= 0 ? start : self.v.length + start;
- }
- if (end === undefined) {
- end = self.v.length;
- } else {
- end = Sk.builtin.asnum$(end);
- end = end >= 0 ? end : self.v.length + end;
- }
- idx = self.v.lastIndexOf(tgt.v, end);
- idx = (idx !== end) ? idx : self.v.lastIndexOf(tgt.v, end - 1);
- idx = ((idx >= start) && (idx < end)) ? idx : -1;
- return new Sk.builtin.int_(idx);
- });
- Sk.builtin.str.prototype["rindex"] = new Sk.builtin.func(function (self, tgt, start, end) {
- var idx;
- Sk.builtin.pyCheckArgs("rindex", arguments, 2, 4);
- idx = Sk.misceval.callsim(self["rfind"], self, tgt, start, end);
- if (Sk.builtin.asnum$(idx) === -1) {
- throw new Sk.builtin.ValueError("substring not found");
- }
- return idx;
- });
- Sk.builtin.str.prototype["startswith"] = new Sk.builtin.func(function (self, tgt) {
- Sk.builtin.pyCheckArgs("startswith", arguments, 2, 2);
- Sk.builtin.pyCheckType("tgt", "string", Sk.builtin.checkString(tgt));
- return new Sk.builtin.bool( self.v.indexOf(tgt.v) === 0);
- });
- // http://stackoverflow.com/questions/280634/endswith-in-javascript
- Sk.builtin.str.prototype["endswith"] = new Sk.builtin.func(function (self, tgt) {
- Sk.builtin.pyCheckArgs("endswith", arguments, 2, 2);
- Sk.builtin.pyCheckType("tgt", "string", Sk.builtin.checkString(tgt));
- return new Sk.builtin.bool( self.v.indexOf(tgt.v, self.v.length - tgt.v.length) !== -1);
- });
- Sk.builtin.str.prototype["replace"] = new Sk.builtin.func(function (self, oldS, newS, count) {
- var c;
- var patt;
- Sk.builtin.pyCheckArgs("replace", arguments, 3, 4);
- Sk.builtin.pyCheckType("oldS", "string", Sk.builtin.checkString(oldS));
- Sk.builtin.pyCheckType("newS", "string", Sk.builtin.checkString(newS));
- if ((count !== undefined) && !Sk.builtin.checkInt(count)) {
- throw new Sk.builtin.TypeError("integer argument expected, got " +
- Sk.abstr.typeName(count));
- }
- count = Sk.builtin.asnum$(count);
- patt = new RegExp(Sk.builtin.str.re_escape_(oldS.v), "g");
- if ((count === undefined) || (count < 0)) {
- return new Sk.builtin.str(self.v.replace(patt, newS.v));
- }
- c = 0;
- function replacer (match) {
- c++;
- if (c <= count) {
- return newS.v;
- }
- return match;
- }
- return new Sk.builtin.str(self.v.replace(patt, replacer));
- });
- Sk.builtin.str.prototype["zfill"] = new Sk.builtin.func(function (self, len) {
- var str = self.v;
- var ret;
- var zeroes;
- var offset;
- var pad = "";
- Sk.builtin.pyCheckArgs("zfill", arguments, 2, 2);
- if (! Sk.builtin.checkInt(len)) {
- throw new Sk.builtin.TypeError("integer argument exepected, got " + Sk.abstr.typeName(len));
- }
- // figure out how many zeroes are needed to make the proper length
- zeroes = len.v - str.length;
- // offset by 1 if there is a +/- at the beginning of the string
- offset = (str[0] === "+" || str[0] === "-") ? 1 : 0;
- for(var i = 0; i < zeroes; i++){
- pad += "0";
- }
- // combine the string and the zeroes
- ret = str.substr(0, offset) + pad + str.substr(offset);
- return new Sk.builtin.str(ret);
- });
- Sk.builtin.str.prototype["isdigit"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("isdigit", arguments, 1, 1);
- return new Sk.builtin.bool( /^\d+$/.test(self.v));
- });
- Sk.builtin.str.prototype["isspace"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("isspace", arguments, 1, 1);
- return new Sk.builtin.bool( /^\s+$/.test(self.v));
- });
- Sk.builtin.str.prototype["expandtabs"] = new Sk.builtin.func(function (self, tabsize) {
- // var input = self.v;
- // var expanded = "";
- // var split;
- // var spacestr = "";
- // var spacerem;
- var spaces;
- var expanded;
- Sk.builtin.pyCheckArgs("expandtabs", arguments, 1, 2);
- if ((tabsize !== undefined) && ! Sk.builtin.checkInt(tabsize)) {
- throw new Sk.builtin.TypeError("integer argument exepected, got " + Sk.abstr.typeName(tabsize));
- }
- if (tabsize === undefined) {
- tabsize = 8;
- } else {
- tabsize = Sk.builtin.asnum$(tabsize);
- }
- spaces = (new Array(tabsize + 1)).join(" ");
- expanded = self.v.replace(/([^\r\n\t]*)\t/g, function(a, b) {
- return b + spaces.slice(b.length % tabsize);
- });
- return new Sk.builtin.str(expanded);
- });
- Sk.builtin.str.prototype["swapcase"] = new Sk.builtin.func(function (self) {
- var ret;
- Sk.builtin.pyCheckArgs("swapcase", arguments, 1, 1);
- ret = self.v.replace(/[a-z]/gi, function(c) {
- var lc = c.toLowerCase();
- return lc === c ? c.toUpperCase() : lc;
- });
- return new Sk.builtin.str(ret);
- });
- Sk.builtin.str.prototype["splitlines"] = new Sk.builtin.func(function (self, keepends) {
- var data = self.v;
- var i = 0;
- var j = i;
- var selflen = self.v.length;
- var strs_w = [];
- var ch;
- var eol;
- var sol = 0;
- var slice;
- Sk.builtin.pyCheckArgs("splitlines", arguments, 1, 2);
- if ((keepends !== undefined) && ! Sk.builtin.checkBool(keepends)) {
- throw new Sk.builtin.TypeError("boolean argument expected, got " + Sk.abstr.typeName(keepends));
- }
- if (keepends === undefined) {
- keepends = false;
- } else {
- keepends = keepends.v;
- }
- for (i = 0; i < selflen; i ++) {
- ch = data.charAt(i);
- if (data.charAt(i + 1) === "\n" && ch === "\r") {
- eol = i + 2;
- slice = data.slice(sol, eol);
- if (! keepends) {
- slice = slice.replace(/(\r|\n)/g, "");
- }
- strs_w.push(new Sk.builtin.str(slice));
- sol = eol;
- } else if ((ch === "\n" && data.charAt(i - 1) !== "\r") || ch === "\r") {
- eol = i + 1;
- slice = data.slice(sol, eol);
- if (! keepends) {
- slice = slice.replace(/(\r|\n)/g, "");
- }
- strs_w.push(new Sk.builtin.str(slice));
- sol = eol;
- }
- }
- if (sol < selflen) {
- eol = selflen;
- slice = data.slice(sol, eol);
- if (! keepends) {
- slice = slice.replace(/(\r|\n)/g, "");
- }
- strs_w.push(new Sk.builtin.str(slice));
- }
- return new Sk.builtin.list(strs_w);
- });
- Sk.builtin.str.prototype["title"] = new Sk.builtin.func(function (self) {
- var ret;
- Sk.builtin.pyCheckArgs("title", arguments, 1, 1);
- ret = self.v.replace(/[a-z][a-z]*/gi, function(str) {
- return str[0].toUpperCase() + str.substr(1).toLowerCase();
- });
- return new Sk.builtin.str(ret);
- });
- Sk.builtin.str.prototype["isalpha"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("isalpha", arguments, 1, 1);
- return new Sk.builtin.bool( self.v.length && goog.string.isAlpha(self.v));
- });
- Sk.builtin.str.prototype["isalnum"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("isalnum", arguments, 1, 1);
- return new Sk.builtin.bool( self.v.length && goog.string.isAlphaNumeric(self.v));
- });
- // does not account for unicode numeric values
- Sk.builtin.str.prototype["isnumeric"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("isnumeric", arguments, 1, 1);
- return new Sk.builtin.bool( self.v.length && goog.string.isNumeric(self.v));
- });
- Sk.builtin.str.prototype["islower"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("islower", arguments, 1, 1);
- return new Sk.builtin.bool( self.v.length && /[a-z]/.test(self.v) && !/[A-Z]/.test(self.v));
- });
- Sk.builtin.str.prototype["isupper"] = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("isupper", arguments, 1, 1);
- return new Sk.builtin.bool( self.v.length && !/[a-z]/.test(self.v) && /[A-Z]/.test(self.v));
- });
- Sk.builtin.str.prototype["istitle"] = new Sk.builtin.func(function (self) {
- // Comparing to str.title() seems the most intuitive thing, but it fails on "",
- // Other empty-ish strings with no change.
- var input = self.v;
- var cased = false;
- var previous_is_cased = false;
- var pos;
- var ch;
- Sk.builtin.pyCheckArgs("istitle", arguments, 1, 1);
- for (pos = 0; pos < input.length; pos ++) {
- ch = input.charAt(pos);
- if (! /[a-z]/.test(ch) && /[A-Z]/.test(ch)) {
- if (previous_is_cased) {
- return new Sk.builtin.bool( false);
- }
- previous_is_cased = true;
- cased = true;
- } else if (/[a-z]/.test(ch) && ! /[A-Z]/.test(ch)) {
- if (! previous_is_cased) {
- return new Sk.builtin.bool( false);
- }
- cased = true;
- } else {
- previous_is_cased = false;
- }
- }
- return new Sk.builtin.bool( cased);
- });
- Sk.builtin.str.prototype.nb$remainder = function (rhs) {
- // % format op. rhs can be a value, a tuple, or something with __getitem__ (dict)
- // From http://docs.python.org/library/stdtypes.html#string-formatting the
- // format looks like:
- // 1. The '%' character, which marks the start of the specifier.
- // 2. Mapping key (optional), consisting of a parenthesised sequence of characters (for example, (somename)).
- // 3. Conversion flags (optional), which affect the result of some conversion types.
- // 4. Minimum field width (optional). If specified as an '*' (asterisk), the actual width is read from the next
- // element of the tuple in values, and the object to convert comes after the minimum field width and optional
- // precision. 5. Precision (optional), given as a '.' (dot) followed by the precision. If specified as '*' (an
- // asterisk), the actual width is read from the next element of the tuple in values, and the value to convert comes
- // after the precision. 6. Length modifier (optional). 7. Conversion type. length modifier is ignored
- var ret;
- var replFunc;
- var index;
- var regex;
- if (rhs.constructor !== Sk.builtin.tuple && (rhs.mp$subscript === undefined || rhs.constructor === Sk.builtin.str)) {
- rhs = new Sk.builtin.tuple([rhs]);
- }
- // general approach is to use a regex that matches the format above, and
- // do an re.sub with a function as replacement to make the subs.
- // 1 2222222222222222 33333333 444444444 5555555555555 66666 777777777777777777
- regex = /%(\([a-zA-Z0-9]+\))?([#0 +\-]+)?(\*|[0-9]+)?(\.(\*|[0-9]+))?[hlL]?([diouxXeEfFgGcrs%])/g;
- index = 0;
- replFunc = function (substring, mappingKey, conversionFlags, fieldWidth, precision, precbody, conversionType) {
- var result;
- var convName;
- var convValue;
- var base;
- var r;
- var mk;
- var value;
- var handleWidth;
- var formatNumber;
- var alternateForm;
- var precedeWithSign;
- var blankBeforePositive;
- var leftAdjust;
- var zeroPad;
- var i;
- fieldWidth = Sk.builtin.asnum$(fieldWidth);
- precision = Sk.builtin.asnum$(precision);
- if (mappingKey === undefined || mappingKey === "") {
- i = index++;
- } // ff passes '' not undef for some reason
- if (precision === "") { // ff passes '' here aswell causing problems with G,g, etc.
- precision = undefined;
- }
- zeroPad = false;
- leftAdjust = false;
- blankBeforePositive = false;
- precedeWithSign = false;
- alternateForm = false;
- if (conversionFlags) {
- if (conversionFlags.indexOf("-") !== -1) {
- leftAdjust = true;
- } else if (conversionFlags.indexOf("0") !== -1) {
- zeroPad = true;
- }
- if (conversionFlags.indexOf("+") !== -1) {
- precedeWithSign = true;
- } else if (conversionFlags.indexOf(" ") !== -1) {
- blankBeforePositive = true;
- }
- alternateForm = conversionFlags.indexOf("#") !== -1;
- }
- if (precision) {
- precision = parseInt(precision.substr(1), 10);
- }
- formatNumber = function (n, base) {
- var precZeroPadded;
- var prefix;
- var didSign;
- var neg;
- var r;
- var j;
- base = Sk.builtin.asnum$(base);
- neg = false;
- didSign = false;
- if (typeof n === "number") {
- if (n < 0) {
- n = -n;
- neg = true;
- }
- r = n.toString(base);
- } else if (n instanceof Sk.builtin.float_) {
- r = n.str$(base, false);
- if (r.length > 2 && r.substr(-2) === ".0") {
- r = r.substr(0, r.length - 2);
- }
- neg = n.nb$isnegative();
- } else if (n instanceof Sk.builtin.int_) {
- r = n.str$(base, false);
- neg = n.nb$isnegative();
- } else if (n instanceof Sk.builtin.lng) {
- r = n.str$(base, false);
- neg = n.nb$isnegative(); // neg = n.size$ < 0; RNL long.js change
- }
- goog.asserts.assert(r !== undefined, "unhandled number format");
- precZeroPadded = false;
- if (precision) {
- //print("r.length",r.length,"precision",precision);
- for (j = r.length; j < precision; ++j) {
- r = "0" + r;
- precZeroPadded = true;
- }
- }
- prefix = "";
- if (neg) {
- prefix = "-";
- } else if (precedeWithSign) {
- prefix = "+" + prefix;
- } else if (blankBeforePositive) {
- prefix = " " + prefix;
- }
- if (alternateForm) {
- if (base === 16) {
- prefix += "0x";
- } else if (base === 8 && !precZeroPadded && r !== "0") {
- prefix += "0";
- }
- }
- return [prefix, r];
- };
- handleWidth = function (args) {
- var totLen;
- var prefix = args[0];
- var r = args[1];
- var j;
- if (fieldWidth) {
- fieldWidth = parseInt(fieldWidth, 10);
- totLen = r.length + prefix.length;
- if (zeroPad) {
- for (j = totLen; j < fieldWidth; ++j) {
- r = "0" + r;
- }
- } else if (leftAdjust) {
- for (j = totLen; j < fieldWidth; ++j) {
- r = r + " ";
- }
- } else {
- for (j = totLen; j < fieldWidth; ++j) {
- prefix = " " + prefix;
- }
- }
- }
- return prefix + r;
- };
- //print("Rhs:",rhs, "ctor", rhs.constructor);
- if (rhs.constructor === Sk.builtin.tuple) {
- value = rhs.v[i];
- } else if (rhs.mp$subscript !== undefined && mappingKey !== undefined) {
- mk = mappingKey.substring(1, mappingKey.length - 1);
- //print("mk",mk);
- value = rhs.mp$subscript(new Sk.builtin.str(mk));
- } else if (rhs.constructor === Sk.builtin.dict || rhs.constructor === Sk.builtin.list) {
- // new case where only one argument is provided
- value = rhs;
- } else {
- throw new Sk.builtin.AttributeError(rhs.tp$name + " instance has no attribute 'mp$subscript'");
- }
- base = 10;
- if (conversionType === "d" || conversionType === "i") {
- return handleWidth(formatNumber(value, 10));
- } else if (conversionType === "o") {
- return handleWidth(formatNumber(value, 8));
- } else if (conversionType === "x") {
- return handleWidth(formatNumber(value, 16));
- } else if (conversionType === "X") {
- return handleWidth(formatNumber(value, 16)).toUpperCase();
- } else if (conversionType === "f" || conversionType === "F" || conversionType === "e" || conversionType === "E" || conversionType === "g" || conversionType === "G") {
- convValue = Sk.builtin.asnum$(value);
- if (typeof convValue === "string") {
- convValue = Number(convValue);
- }
- if (convValue === Infinity) {
- return "inf";
- }
- if (convValue === -Infinity) {
- return "-inf";
- }
- if (isNaN(convValue)) {
- return "nan";
- }
- convName = ["toExponential", "toFixed", "toPrecision"]["efg".indexOf(conversionType.toLowerCase())];
- if (precision === undefined || precision === "") {
- if (conversionType === "e" || conversionType === "E") {
- precision = 6;
- } else if (conversionType === "f" || conversionType === "F") {
- precision = 7;
- }
- }
- result = (convValue)[convName](precision); // possible loose of negative zero sign
- // apply sign to negative zeros, floats only!
- if(Sk.builtin.checkFloat(value)) {
- if(convValue === 0 && 1/convValue === -Infinity) {
- result = "-" + result; // add sign for zero
- }
- }
- if ("EFG".indexOf(conversionType) !== -1) {
- result = result.toUpperCase();
- }
- return handleWidth(["", result]);
- } else if (conversionType === "c") {
- if (typeof value === "number") {
- return String.fromCharCode(value);
- } else if (value instanceof Sk.builtin.int_) {
- return String.fromCharCode(value.v);
- } else if (value instanceof Sk.builtin.float_) {
- return String.fromCharCode(value.v);
- } else if (value instanceof Sk.builtin.lng) {
- return String.fromCharCode(value.str$(10, false)[0]);
- } else if (value.constructor === Sk.builtin.str) {
- return value.v.substr(0, 1);
- } else {
- throw new Sk.builtin.TypeError("an integer is required");
- }
- } else if (conversionType === "r") {
- r = Sk.builtin.repr(value);
- if (precision) {
- return r.v.substr(0, precision);
- }
- return r.v;
- } else if (conversionType === "s") {
- r = new Sk.builtin.str(value);
- if (precision) {
- return r.v.substr(0, precision);
- }
- if(fieldWidth) {
- r.v = handleWidth([" ", r.v]);
- }
- return r.v;
- } else if (conversionType === "%") {
- return "%";
- }
- };
- ret = this.v.replace(regex, replFunc);
- return new Sk.builtin.str(ret);
- };
- /**
- * @constructor
- * @param {Object} obj
- */
- Sk.builtin.str_iter_ = function (obj) {
- if (!(this instanceof Sk.builtin.str_iter_)) {
- return new Sk.builtin.str_iter_(obj);
- }
- this.$index = 0;
- this.$obj = obj.v.slice();
- this.sq$length = this.$obj.length;
- this.tp$iter = this;
- this.tp$iternext = function () {
- if (this.$index >= this.sq$length) {
- return undefined;
- }
- return new Sk.builtin.str(this.$obj.substr(this.$index++, 1));
- };
- this.$r = function () {
- return new Sk.builtin.str("iterator");
- };
- return this;
- };
- Sk.abstr.setUpInheritance("iterator", Sk.builtin.str_iter_, Sk.builtin.object);
- Sk.builtin.str_iter_.prototype.__class__ = Sk.builtin.str_iter_;
- Sk.builtin.str_iter_.prototype.__iter__ = new Sk.builtin.func(function (self) {
- Sk.builtin.pyCheckArgs("__iter__", arguments, 0, 0, true, false);
- return self;
- });
- Sk.builtin.str_iter_.prototype["next"] = new Sk.builtin.func(function (self) {
- var ret = self.tp$iternext();
- if (ret === undefined) {
- throw new Sk.builtin.StopIteration();
- }
- return ret;
- });
|