X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=modules%2Fml-string.cc;h=b06d6f2d41cbea7efc4913709231d42c5b2ade46;hb=2e7dce06a7136647d7ac3e012f15c30e6e6cf96a;hp=6ed87419d43fcbdaf4c3fc4dc44e3047030569e3;hpb=fa2c7371d35d1bed1d13e551b966e12b4a725bea;p=hmh%2Fhhml.git diff --git a/modules/ml-string.cc b/modules/ml-string.cc index 6ed8741..b06d6f2 100644 --- a/modules/ml-string.cc +++ b/modules/ml-string.cc @@ -1,5 +1,6 @@ #include "ml-string.h" #include "ml.h" +#include "ml-texp.h" #include "mlenv.h" #include "motorenv.h" #include "motoroutput.h" @@ -22,9 +23,202 @@ */ /*DOC: +===eq=== + (eq STRING STRING...) -> 1 or NIL + (string-eq STRING STRING...) -> 1 or NIL + +全てのSTRINGが同じ時、1を返す。 + +*/ +//#AFUNC eq ml_string_eq +//#AFUNC string-eq ml_string_eq +//#WIKIFUNC eq +//#WIKIFUNC string-eq +MNode* ml_string_eq (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring v1, v2; + + if (! arg) + throw (uErrorWrongNumber); + + v1 = eval_str (arg->car (), mlenv); + nextNode (arg); + while (arg) { + v2 = eval_str (arg->car (), mlenv); + if (v1 == v2) { + } else { + return newMNode_bool (false); + } + nextNode (arg); + } + return newMNode_bool (true); +} + +/*DOC: +===ne=== + (ne STRING STRING) -> 1 or NIL + (string-ne STRING STRING) -> 1 or NIL + +STRINGが異なる時、1を返す。 + +*/ +//#AFUNC ne ml_string_ne +//#AFUNC string-ne ml_string_ne +//#WIKIFUNC ne +//#WIKIFUNC string-ne +MNode* ml_string_ne (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring v1, v2; + + if (! arg) + throw (uErrorWrongNumber); + + v1 = eval_str (arg->car (), mlenv); + nextNode (arg); + if (! arg) + throw (uErrorWrongNumber); + v2 = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + return newMNode_bool (v1 != v2); +} + +//#AFUNC lt ml_string_lt +//#AFUNC string-lt ml_string_lt +//#WIKIFUNC lt +//#WIKIFUNC string-lt +MNode* ml_string_lt (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring v1, v2; + + if (! arg) + throw (uErrorWrongNumber); + v1 = eval_str (arg->car (), mlenv); + nextNodeNonNil (arg); + v2 = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + return newMNode_bool (v1 < v2); +} + +//#AFUNC le ml_string_le +//#AFUNC string-le ml_string_le +//#WIKIFUNC le +//#WIKIFUNC string-le +MNode* ml_string_le (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring v1, v2; + + if (! arg) + throw (uErrorWrongNumber); + v1 = eval_str (arg->car (), mlenv); + nextNodeNonNil (arg); + v2 = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + return newMNode_bool (v1 <= v2); +} + +//#AFUNC gt ml_string_gt +//#AFUNC string-gt ml_string_gt +//#WIKIFUNC gt +//#WIKIFUNC string-gt +MNode* ml_string_gt (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring v1, v2; + + if (! arg) + throw (uErrorWrongNumber); + v1 = eval_str (arg->car (), mlenv); + nextNodeNonNil (arg); + v2 = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + return newMNode_bool (v1 > v2); +} + +//#AFUNC ge ml_string_ge +//#AFUNC string-ge ml_string_ge +//#WIKIFUNC ge +//#WIKIFUNC string-ge +MNode* ml_string_ge (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring v1, v2; + + if (! arg) + throw (uErrorWrongNumber); + v1 = eval_str (arg->car (), mlenv); + nextNodeNonNil (arg); + v2 = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + return newMNode_bool (v1 >= v2); +} + +/*DOC: +===emptyp=== + (emptyp TEXT...) -> 1 or NIL + +文字列TEXTの長さが0の時、1を返す。 + +*/ +//#AFUNC emptyp ml_emptyp +//#WIKIFUNC emptyp +MNode* ml_emptyp (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring u; + + if (! arg) + throw (uErrorWrongNumber); + + while (arg) { + u = eval_str (arg->car (), mlenv); + nextNode (arg); + if (u.size () > 0) + return newMNode_bool (false); + } + return newMNode_bool (true); +} + +/*DOC: +===not-emptyp=== + (not-emptyp TEXT...) -> 1 or NIL + +文字列TEXTの長さが0でない時、1を返す。 + +*/ +//#AFUNC not-emptyp ml_not_emptyp +//#WIKIFUNC not-emptyp +MNode* ml_not_emptyp (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring u; + + if (! arg) + throw (uErrorWrongNumber); + + while (arg) { + u = eval_str (arg->car (), mlenv); + nextNode (arg); + if (u.size () == 0) + return newMNode_bool (false); + } + return newMNode_bool (true); +} + +/*DOC: ===concat=== (concat STRING...) -> STRING -パラメータの文字列を連結して一つの文字列を返す。 +パラメータの文字列STRINGを連結して一つの文字列を返す。 */ //#AFUNC concat ml_concat @@ -34,7 +228,7 @@ MNode* ml_concat (MNode* cell, MlEnv* mlenv) { AutoDelete a1; a1 = new ustring; - a1 ()->reserve (256); +// a1 ()->reserve (256); while (arg) { a1 ()->append (eval_str (arg->car (), mlenv)); @@ -47,6 +241,8 @@ MNode* ml_concat (MNode* cell, MlEnv* mlenv) { ===megabyte=== (megabyte NUMBER) -> STRING +数値NUMBERをK、M、G、T、P単位(1024の倍数)の文字列に変換する。 + */ //#AFUNC megabyte ml_megabyte //#WIKIFUNC megabyte @@ -101,6 +297,8 @@ MNode* ml_megabyte (MNode* cell, MlEnv* mlenv) { ===c3=== (c3 INTEGER) -> STRING +数値INTEGERを3桁ごとにカンマ区切りの文字列に変換する。 + */ //#AFUNC c3 ml_c3 //#WIKIFUNC c3 @@ -142,10 +340,10 @@ MNode* ml_regexp_match (MNode* cell, MlEnv* mlenv) { setParams (arg, 2, ¶ms, kwlist, &keywords, NULL); reg = eval_str (params[0], mlenv); text = eval_str (params[1], mlenv); - if (eval_bool (keywords[0], mlenv)) + if (keywords[0] && eval_bool (keywords[0], mlenv)) f |= boost::regex_constants::icase; - ans = wsearch_env (mlenv, text, reg, f); + ans = wsearch_env (mlenv->regenv, text, reg, f); return newMNode_bool (ans); } @@ -169,8 +367,8 @@ MNode* ml_match_string (MNode* cell, MlEnv* mlenv) { if (arg) throw (uErrorWrongNumber); - if (0 <= n && n < mlenv->regmatch.size ()) { - ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[n].first, mlenv->regmatch[n].second)))); + if (0 <= n && n < mlenv->regenv.regmatch.size ()) { + ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regenv.regmatch[n].first, mlenv->regenv.regmatch[n].second)))); } return ans; @@ -186,12 +384,12 @@ MNode* ml_match_string (MNode* cell, MlEnv* mlenv) { MNode* ml_prematch (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); MNode* ans = NULL; - std::wstring::const_iterator b = mlenv->regtext.begin (); + std::wstring::const_iterator b = mlenv->regenv.regtext.begin (); if (arg) throw (uErrorWrongNumber); - ans = newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regmatch[0].first)))); + ans = newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regenv.regmatch[0].first)))); return ans; } @@ -206,12 +404,12 @@ MNode* ml_prematch (MNode* cell, MlEnv* mlenv) { MNode* ml_postmatch (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); MNode* ans = NULL; - std::wstring::const_iterator e = mlenv->regtext.end (); + std::wstring::const_iterator e = mlenv->regenv.regtext.end (); if (arg) throw (uErrorWrongNumber); - ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[0].second, e)))); + ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regenv.regmatch[0].second, e)))); return ans; } @@ -226,9 +424,10 @@ MNode* ml_postmatch (MNode* cell, MlEnv* mlenv) { MNode* ml_string_filter (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); ustring reg; - ustring t; + ustring text; boost::wregex::flag_type f = boost::regex_constants::normal; size_t max = 0; + MNodePtr t; std::vector params; std::vector keywords; static paramList kwlist[] = { @@ -239,17 +438,20 @@ MNode* ml_string_filter (MNode* cell, MlEnv* mlenv) { setParams (arg, 2, ¶ms, kwlist, &keywords, NULL); reg = eval_str (params[0], mlenv); - t = eval_str (params[1], mlenv); - if (eval_bool (keywords[0], mlenv)) + text = eval_str (params[1], mlenv); + if (keywords[0] && eval_bool (keywords[0], mlenv)) f |= boost::regex_constants::icase; - if (eval_bool (keywords[1], mlenv)) { - max = eval_int (keywords[1], mlenv); - if (max < 0) + if (evkw (1, t)) { + int num = to_int (t ()); + if (num < 0) { max = 0; + } else { + max = num; + } } - if (wsearch_env (mlenv, t, reg, f)) { - ustring ans = wtou (std::wstring (mlenv->regmatch[0].first, mlenv->regmatch[0].second)); + if (wsearch_env (mlenv->regenv, text, reg, f)) { + ustring ans = wtou (std::wstring (mlenv->regenv.regmatch[0].first, mlenv->regenv.regmatch[0].second)); if (max > 0) { substring (ans, 0, max, true, ans); } @@ -288,11 +490,11 @@ MNode* ml_regexp_replace (MNode* cell, MlEnv* mlenv) { reg = eval_str (params[0], mlenv); to = eval_str (params[1], mlenv); text = eval_str (params[2], mlenv); - if (eval_bool (keywords[0], mlenv)) + if (keywords[0] && eval_bool (keywords[0], mlenv)) f |= boost::regex_constants::icase; - if (eval_bool (keywords[1], mlenv)) + if (keywords[1] && eval_bool (keywords[1], mlenv)) fglobal = true; - if (eval_bool (keywords[2], mlenv)) + if (keywords[2] && eval_bool (keywords[2], mlenv)) fglobal = true; if (! fglobal) @@ -325,14 +527,14 @@ MNode* ml_regexp_split (MNode* cell, MlEnv* mlenv) { setParams (arg, 2, ¶ms, kwlist, &keywords, NULL); reg = eval_str (params[0], mlenv); text = eval_str (params[1], mlenv); - if (eval_bool (keywords[0], mlenv)) + if (keywords[0] && eval_bool (keywords[0], mlenv)) f |= boost::regex_constants::icase; - if (wsearch_env (mlenv, text, reg, f)) { - std::wstring::const_iterator b = mlenv->regtext.begin (); - std::wstring::const_iterator e = mlenv->regtext.end (); - ans.append (newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regmatch[0].first))))); - ans.append (newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[0].second, e))))); + if (wsearch_env (mlenv->regenv, text, reg, f)) { + std::wstring::const_iterator b = mlenv->regenv.regtext.begin (); + std::wstring::const_iterator e = mlenv->regenv.regtext.end (); + ans.append (newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regenv.regmatch[0].first))))); + ans.append (newMNode_str (new ustring (wtou (std::wstring (mlenv->regenv.regmatch[0].second, e))))); } else { ans.append (newMNode_str (new ustring (text))); ans.append (NULL); @@ -343,7 +545,8 @@ MNode* ml_regexp_split (MNode* cell, MlEnv* mlenv) { /*DOC: ===split=== - (split REGEX STRING) -> STRING_LIST + (split REGEX STRING [#keep] [#i]) -> STRING_LIST + (split REGEX STRING #vector [#keep] [#i]) -> STRING_VECTOR */ //#AFUNC split ml_split @@ -351,42 +554,73 @@ MNode* ml_regexp_split (MNode* cell, MlEnv* mlenv) { MNode* ml_split (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); ustring reg; - ustring t; - MNodeList ans; - - if (! arg) - throw (uErrorWrongNumber); - - reg = eval_str (arg->car (), mlenv); - nextNodeNonNil (arg); - t = eval_str (arg->car (), mlenv); - nextNode (arg); - - if (arg) - throw (uErrorWrongNumber); - - try { - std::wstring wt = utow (t); - std::wstring wreg = utow (reg); - boost::wregex wre (wreg); - WSplitter sp (wt, wre); - size_t m = wt.length () + 1; + ustring text; + bool flagKeep = false; + bool flagVector = false; + ListMakerPtr ans; + std::vector params; + std::vector keywords; + static paramList kwlist[] = { + {CharConst ("keep"), true}, // 空フィールドの削除をしない + {CharConst ("vector"), true}, +// {CharConst ("i"), true}, + {NULL, 0, 0} + }; - while (sp.next ()) { - ans.append (newMNode_str (new ustring (sp.cur ()))); - m --; - if (m == 0) - throw (uErrorRegexp); + setParams (arg, 2, ¶ms, kwlist, &keywords, NULL); + reg = eval_str (params[0], mlenv); + text = eval_str (params[1], mlenv); + if (keywords[0] && eval_bool (keywords[0], mlenv)) + flagKeep = true; + if (keywords[1] && eval_bool (keywords[1], mlenv)) + flagVector = true; +// if (keywords[1] && eval_bool (keywords[1], mlenv)) +// flagReg |= boost::regex_constants::icase; + if (flagVector) + ans = new ListMakerVector; + else + ans = new ListMakerList; + + if (reg.length () == 0) { + uiterator b = text.begin (); + uiterator e = text.end (); + uiterator s; + while (b < e) { + s = b; + nextChar (b, e); + ans.append (newMNode_str (new ustring (s, b))); + } + } else { + try { + std::wstring wt = utow (text); + std::wstring wreg = utow (reg); + boost::wregex wre (wreg); + WSplitter sp (wt, wre); + size_t m = wt.length () + 1; + + bool (WSplitter::*nfn)(); + if (flagKeep) + nfn = &WSplitter::nextSep; + else + nfn = &WSplitter::next; + while ((sp.*nfn) ()) { + ans.append (newMNode_str (new ustring (sp.cur ()))); + m --; + if (m == 0) + throw (uErrorRegexp); + } + if (flagKeep) + ans.append (newMNode_str (new ustring (sp.cur ()))); + } catch (boost::regex_error& err) { + throw (uErrorRegexp); } - } catch (boost::regex_error& err) { - throw (uErrorRegexp); } return ans.release (); } /*DOC: ===string-join=== - (string-join TEXT [STRING | ARRAY | LIST]...) -> STRING + (string-join TEXT [STRING | ARRAY | LIST | VECTOR]...) -> STRING */ //#AFUNC string-join ml_string_join @@ -435,6 +669,16 @@ MNode* ml_string_join (MNode* cell, MlEnv* mlenv) { if (! isNil (a->car ())) ans.append (a->car ()->to_string ()); } + } else if (val ()->isVector ()) { + size_t n = val ()->vectorSize (); + size_t i; + for (i = 0; i < n; ++ i) { + if (i > 0) + ans.append (sep); + MNode* a = val ()->vectorGet (i); + if (! isNil (a)) + ans.append (a->to_string ()); + } } else { var = val ()->to_string (); if (c == 0) @@ -474,7 +718,9 @@ MNode* ml_password_match (MNode* cell, MlEnv* mlenv) { /*DOC: ===password-crypt=== - (password-crypt PASSWORD) -> STRING + (password-crypt PASSWORD [#md5 | #sha256 | #sha512]) -> STRING + +deprecated. */ //#AFUNC password-crypt ml_password_crypt @@ -482,15 +728,30 @@ MNode* ml_password_match (MNode* cell, MlEnv* mlenv) { MNode* ml_password_crypt (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); ustring pass; + passCryptFormat format; + std::vector params; + std::vector keywords; + static paramList kwlist[] = { + {CharConst ("md5"), true}, + {CharConst ("sha256"), true}, + {CharConst ("sha512"), true}, +// {CharConst ("bf"), true}, + {NULL, 0, 0} + }; - if (! arg) - throw (uErrorWrongNumber); - pass = eval_str (arg->car (), mlenv); - nextNode (arg); - if (arg) - throw (uErrorWrongNumber); - - return newMNode_str (new ustring (passCrypt (pass))); + format = FORMAT_MD5; + setParams (arg, 1, ¶ms, kwlist, &keywords, NULL); + pass = eval_str (params[0], mlenv); + if (keywords[0] && eval_bool (keywords[0], mlenv)) + format = FORMAT_MD5; + if (keywords[1] && eval_bool (keywords[1], mlenv)) + format = FORMAT_SHA256; + if (keywords[2] && eval_bool (keywords[2], mlenv)) + format = FORMAT_SHA512; +// if (keywords[3] && eval_bool (keywords[3], mlenv)) +// format = FORMAT_BF; + + return newMNode_str (new ustring (passCrypt (pass, format))); } /*DOC: @@ -498,6 +759,8 @@ MNode* ml_password_crypt (MNode* cell, MlEnv* mlenv) { (substring STR INDEX LENGTH) -> STRING (substring STR INDEX) -> STRING +INDEX number of the first character of STR is 0. + */ //#AFUNC substring ml_substring //#WIKIFUNC substring @@ -530,6 +793,48 @@ MNode* ml_substring (MNode* cell, MlEnv* mlenv) { } /*DOC: +===tail-substring=== + (tail-substring STR INDEX LENGTH) -> STRING + (tail-substring STR INDEX) -> STRING + +INDEX number of the last character of STR is 0. + +*/ +//#AFUNC tail-substring ml_tail_substring +//#WIKIFUNC tail-substring +MNode* ml_tail_substring (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring str; + size_t index; + size_t length; + int mode; + ustring ans; + + if (! arg) + throw (uErrorWrongNumber); + str = eval_str (arg->car (), mlenv); + nextNodeNonNil (arg); + index = eval_int (arg->car (), mlenv); + nextNode (arg); + if (arg) { + mode = 3; + length = eval_int (arg->car (), mlenv); + nextNode (arg); + } else { + mode = 2; + } + if (arg) + throw (uErrorWrongNumber); + + size_t s = strLength (str); + if (mode == 3) + substring (str, s - index - 1, length, 1, ans); + else + substring (str, s - index - 1, 0, 0, ans); + return newMNode_str (new ustring (ans)); +} + +/*DOC: ===length=== (length STRING) -> NUMBER @@ -553,6 +858,29 @@ MNode* ml_length (MNode* cell, MlEnv* mlenv) { } /*DOC: +===byte-length=== + (byte-length STRING) -> NUMBER + +*/ +//#AFUNC byte-length ml_byte_length +//#WIKIFUNC byte-length +MNode* ml_byte_length (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring str; + size_t ans; + + if (! arg) + throw (uErrorWrongNumber); + str = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + ans = str.length (); + return newMNode_num (ans); +} + +/*DOC: ===pad0=== (pad0 NUMBER STRING) -> STRING (pad0 NUMBER STRING_LIST) -> STRING_LIST @@ -785,30 +1113,55 @@ MNode* ml_to_string (MNode* cell, MlEnv* mlenv) { } /*DOC: -===dump-to-sexp=== +===to-symbol=== + (to-symbol STRING) -> SYMBOL + +*/ +//#AFUNC to-symbol ml_to_symbol +//#WIKIFUNC to-symbol +MNode* ml_to_symbol (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + MNodePtr text; + + if (! arg) + throw (uErrorWrongNumber); + text = eval (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + + if (text ()) { + if (text ()->isSym ()) { + return text.release (); + } else { + return newMNode_sym (new ustring (text ()->to_string ())); + } + } else { + return NULL; + } +} + +/*DOC: +===dump-to-texp, dump-to-sexp=== + (dump-to-texp OBJECT...) -> STRING (dump-to-sexp OBJECT...) -> STRING */ -//#AFUNC dump-to-sexp ml_dump_to_sexp +//#AFUNC dump-to-texp ml_dump_to_texp +//#AFUNC dump-to-sexp ml_dump_to_texp +//#WIKIFUNC dump-to-texp //#WIKIFUNC dump-to-sexp -MNode* ml_dump_to_sexp (MNode* cell, MlEnv* mlenv) { +MNode* ml_dump_to_texp (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); MNodePtr e; ustring text; while (arg) { -// text = eval_str (arg->car (), mlenv); e = eval (arg->car (), mlenv); nextNode (arg); if (text.length () > 0) text.append (CharConst (" ")); - if (isNil (e ())) { - text.append (uNil2); - } else if (e ()->isStr ()) { - text.append (uQ2).append (slashEncode (*e ()->str)).append (uQ2); - } else { - text.append (e ()->to_string ()); - } + text.append (dump_to_texp (e ())); } return newMNode_str (new ustring (text)); } @@ -816,19 +1169,21 @@ MNode* ml_dump_to_sexp (MNode* cell, MlEnv* mlenv) { /*DOC: //===to-sexp=== // (to-sexp STRING) -> OBJECT -===read-sexp=== +===read-texp, read-sexp=== (read-sexp STRING) -> OBJECT + (read-texp STRING) -> OBJECT */ // //#AFUNC to-sexp ml_to_sexp // //#WIKIFUNC to-sexp -//#AFUNC read-sexp ml_read_sexp +//#AFUNC read-texp ml_read_texp +//#AFUNC read-sexp ml_read_texp +//#WIKIFUNC read-texp //#WIKIFUNC read-sexp -//MNode* ml_to_sexp (MNode* cell, MlEnv* mlenv) { -MNode* ml_read_sexp (MNode* cell, MlEnv* mlenv) { +MNode* ml_read_texp (MNode* cell, MlEnv* mlenv) { MNode* arg = cell->cdr (); ustring text; - MotorSexp ml (NULL); + MotorTexp ml (NULL); if (! arg) throw (uErrorWrongNumber); @@ -864,7 +1219,8 @@ MNode* ml_is_ascii63 (MNode* cell, MlEnv* mlenv) { if (arg) throw (uErrorWrongNumber); - ans = checkASCII (text); +// ans = checkASCII (text); + ans = matchASCII (text.begin (), text.end ()); return newMNode_bool (ans); } @@ -893,9 +1249,9 @@ MNode* ml_sort_string (MNode* cell, MlEnv* mlenv) { setParams (arg, 1, ¶ms, kwlist, &keywords, NULL); h = eval (params[0], mlenv); - if (eval_bool (keywords[0], mlenv)) + if (keywords[0] && eval_bool (keywords[0], mlenv)) fdesc = false; - if (eval_bool (keywords[1], mlenv)) + if (keywords[1] && eval_bool (keywords[1], mlenv)) fdesc = true; a = h (); @@ -1015,3 +1371,26 @@ MNode* ml_to_lower (MNode* cell, MlEnv* mlenv) { return newMNode_str (new ustring (toLower (text))); } + +/*DOC: +===hex-to-dec=== + (hex-to-dec STRING) -> NUMBER + +*/ +//#AFUNC hex-to-dec ml_hex_to_dec +//#WIKIFUNC hex-to-dec +MNode* ml_hex_to_dec (MNode* cell, MlEnv* mlenv) { + MNode* arg = cell->cdr (); + ustring text; + + if (! arg) + throw (uErrorWrongNumber); + text = eval_str (arg->car (), mlenv); + nextNode (arg); + if (arg) + throw (uErrorWrongNumber); + if (text.length () > 8) + throw (uErrorBadArg); + + return newMNode_num (hextoul (text.begin (), text.end ())); +}