5 #include "motoroutput.h"
6 #include "util_const.h"
7 #include "util_check.h"
8 #include "util_random.h"
9 #include "util_string.h"
10 #include "util_wsplitter.h"
16 #include <boost/ptr_container/ptr_vector.hpp>
26 (eq STRING STRING...) -> 1 or NIL
27 (string-eq STRING STRING...) -> 1 or NIL
32 //#AFUNC eq ml_string_eq
33 //#AFUNC string-eq ml_string_eq
36 MNode* ml_string_eq (MNode* cell, MlEnv* mlenv) {
37 MNode* arg = cell->cdr ();
41 throw (uErrorWrongNumber);
43 v1 = eval_str (arg->car (), mlenv);
46 v2 = eval_str (arg->car (), mlenv);
49 return newMNode_bool (false);
53 return newMNode_bool (true);
58 (ne STRING STRING) -> 1 or NIL
59 (string-ne STRING STRING) -> 1 or NIL
64 //#AFUNC ne ml_string_ne
65 //#AFUNC string-ne ml_string_ne
68 MNode* ml_string_ne (MNode* cell, MlEnv* mlenv) {
69 MNode* arg = cell->cdr ();
73 throw (uErrorWrongNumber);
75 v1 = eval_str (arg->car (), mlenv);
78 throw (uErrorWrongNumber);
79 v2 = eval_str (arg->car (), mlenv);
82 throw (uErrorWrongNumber);
84 return newMNode_bool (v1 != v2);
87 //#AFUNC lt ml_string_lt
88 //#AFUNC string-lt ml_string_lt
91 MNode* ml_string_lt (MNode* cell, MlEnv* mlenv) {
92 MNode* arg = cell->cdr ();
96 throw (uErrorWrongNumber);
97 v1 = eval_str (arg->car (), mlenv);
99 v2 = eval_str (arg->car (), mlenv);
102 throw (uErrorWrongNumber);
104 return newMNode_bool (v1 < v2);
107 //#AFUNC le ml_string_le
108 //#AFUNC string-le ml_string_le
110 //#WIKIFUNC string-le
111 MNode* ml_string_le (MNode* cell, MlEnv* mlenv) {
112 MNode* arg = cell->cdr ();
116 throw (uErrorWrongNumber);
117 v1 = eval_str (arg->car (), mlenv);
118 nextNodeNonNil (arg);
119 v2 = eval_str (arg->car (), mlenv);
122 throw (uErrorWrongNumber);
124 return newMNode_bool (v1 <= v2);
127 //#AFUNC gt ml_string_gt
128 //#AFUNC string-gt ml_string_gt
130 //#WIKIFUNC string-gt
131 MNode* ml_string_gt (MNode* cell, MlEnv* mlenv) {
132 MNode* arg = cell->cdr ();
136 throw (uErrorWrongNumber);
137 v1 = eval_str (arg->car (), mlenv);
138 nextNodeNonNil (arg);
139 v2 = eval_str (arg->car (), mlenv);
142 throw (uErrorWrongNumber);
144 return newMNode_bool (v1 > v2);
147 //#AFUNC ge ml_string_ge
148 //#AFUNC string-ge ml_string_ge
150 //#WIKIFUNC string-ge
151 MNode* ml_string_ge (MNode* cell, MlEnv* mlenv) {
152 MNode* arg = cell->cdr ();
156 throw (uErrorWrongNumber);
157 v1 = eval_str (arg->car (), mlenv);
158 nextNodeNonNil (arg);
159 v2 = eval_str (arg->car (), mlenv);
162 throw (uErrorWrongNumber);
164 return newMNode_bool (v1 >= v2);
169 (emptyp TEXT...) -> 1 or NIL
174 //#AFUNC emptyp ml_emptyp
176 MNode* ml_emptyp (MNode* cell, MlEnv* mlenv) {
177 MNode* arg = cell->cdr ();
181 throw (uErrorWrongNumber);
184 u = eval_str (arg->car (), mlenv);
187 return newMNode_bool (false);
189 return newMNode_bool (true);
194 (not-emptyp TEXT...) -> 1 or NIL
196 文字列TEXTの長さが0でない時、1を返す。
199 //#AFUNC not-emptyp ml_not_emptyp
200 //#WIKIFUNC not-emptyp
201 MNode* ml_not_emptyp (MNode* cell, MlEnv* mlenv) {
202 MNode* arg = cell->cdr ();
206 throw (uErrorWrongNumber);
209 u = eval_str (arg->car (), mlenv);
212 return newMNode_bool (false);
214 return newMNode_bool (true);
219 (concat STRING...) -> STRING
220 パラメータの文字列STRINGを連結して一つの文字列を返す。
223 //#AFUNC concat ml_concat
225 MNode* ml_concat (MNode* cell, MlEnv* mlenv) {
226 MNode* arg = cell->cdr ();
227 AutoDelete<ustring> a1;
230 // a1 ()->reserve (256);
233 a1 ()->append (eval_str (arg->car (), mlenv));
236 return newMNode_str (a1.release ());
241 (megabyte NUMBER) -> STRING
243 数値NUMBERをK、M、G、T、P単位(1024の倍数)の文字列に変換する。
246 //#AFUNC megabyte ml_megabyte
248 MNode* ml_megabyte (MNode* cell, MlEnv* mlenv) {
249 MNode* arg = cell->cdr ();
254 throw (uErrorWrongNumber);
256 val = eval_double (arg->car (), mlenv);
259 throw (uErrorWrongNumber);
262 u = to_ustring (val);
263 return newMNode_str (new ustring (u));
265 val = floor (val / 1024. * 10.) / 10.;
267 u = to_ustring (val);
268 u.append (CharConst ("K"));
269 return newMNode_str (new ustring (u));
271 val = floor (val / 1024. * 10. ) / 10.;
273 u = to_ustring (val);
274 u.append (CharConst ("M"));
275 return newMNode_str (new ustring (u));
277 val = floor (val / 1024. * 10.) / 10.;
279 u = to_ustring (val);
280 u.append (CharConst ("G"));
281 return newMNode_str (new ustring (u));
283 val = floor (val / 1024. * 10.) / 10.;
285 u = to_ustring (val);
286 u.append (CharConst ("T"));
287 return newMNode_str (new ustring (u));
289 val = floor (val / 1024. * 10.) / 10.;
290 u = to_ustring (val);
291 u.append (CharConst ("P"));
292 return newMNode_str (new ustring (u));
297 (c3 INTEGER) -> STRING
299 数値INTEGERを3桁ごとにカンマ区切りの文字列に変換する。
304 MNode* ml_c3 (MNode* cell, MlEnv* mlenv) {
305 MNode* arg = cell->cdr ();
309 throw (uErrorWrongNumber);
311 u = eval_str (arg->car (), mlenv);
314 throw (uErrorWrongNumber);
316 return newMNode_str (new ustring (c3 (u)));
321 (regexp-match REGEX TEXT [#i | :i BOOL]) -> BOOL
324 //#AFUNC regexp-match ml_regexp_match
325 //#WIKIFUNC regexp-match
326 MNode* ml_regexp_match (MNode* cell, MlEnv* mlenv) {
327 MNode* arg = cell->cdr ();
330 boost::wregex::flag_type f = boost::regex_constants::normal;
332 std::vector<MNode*> params;
333 std::vector<MNode*> keywords;
334 static paramList kwlist[] = {
335 {CharConst ("i"), true},
339 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
340 reg = eval_str (params[0], mlenv);
341 text = eval_str (params[1], mlenv);
342 if (keywords[0] && eval_bool (keywords[0], mlenv))
343 f |= boost::regex_constants::icase;
345 ans = wsearch_env (mlenv, text, reg, f);
347 return newMNode_bool (ans);
352 (match-string NUM) -> STRING
355 //#AFUNC match-string ml_match_string
356 //#WIKIFUNC match-string
357 MNode* ml_match_string (MNode* cell, MlEnv* mlenv) {
358 MNode* arg = cell->cdr ();
363 throw (uErrorWrongNumber);
364 n = eval_int (arg->car (), mlenv);
367 throw (uErrorWrongNumber);
369 if (0 <= n && n < mlenv->regmatch.size ()) {
370 ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[n].first, mlenv->regmatch[n].second))));
381 //#AFUNC prematch ml_prematch
383 MNode* ml_prematch (MNode* cell, MlEnv* mlenv) {
384 MNode* arg = cell->cdr ();
386 std::wstring::const_iterator b = mlenv->regtext.begin ();
389 throw (uErrorWrongNumber);
391 ans = newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regmatch[0].first))));
398 (postmatch) -> STRING
401 //#AFUNC postmatch ml_postmatch
402 //#WIKIFUNC postmatch
403 MNode* ml_postmatch (MNode* cell, MlEnv* mlenv) {
404 MNode* arg = cell->cdr ();
406 std::wstring::const_iterator e = mlenv->regtext.end ();
409 throw (uErrorWrongNumber);
411 ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[0].second, e))));
418 (string-filter REGEX STRING [#i | :i BOOL] [:max NUM]) -> STRING
421 //#AFUNC string-filter ml_string_filter
422 //#WIKIFUNC string-filter
423 MNode* ml_string_filter (MNode* cell, MlEnv* mlenv) {
424 MNode* arg = cell->cdr ();
427 boost::wregex::flag_type f = boost::regex_constants::normal;
430 std::vector<MNode*> params;
431 std::vector<MNode*> keywords;
432 static paramList kwlist[] = {
433 {CharConst ("i"), true},
434 {CharConst ("max"), false},
438 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
439 reg = eval_str (params[0], mlenv);
440 text = eval_str (params[1], mlenv);
441 if (keywords[0] && eval_bool (keywords[0], mlenv))
442 f |= boost::regex_constants::icase;
449 if (wsearch_env (mlenv, text, reg, f)) {
450 ustring ans = wtou (std::wstring (mlenv->regmatch[0].first, mlenv->regmatch[0].second));
452 substring (ans, 0, max, true, ans);
454 return newMNode_str (new ustring (ans));
456 return NULL; // unmatched
462 (regexp-replace REGEX TO_TEXT TEXT [#i | :i BOOL] [#g | #global | :g BOOL | :global BOOL]) -> TEXT
465 //#AFUNC regexp-replace ml_regexp_replace
466 //#WIKIFUNC regexp-replace
467 MNode* ml_regexp_replace (MNode* cell, MlEnv* mlenv) {
468 MNode* arg = cell->cdr ();
472 boost::wregex::flag_type f = boost::regex_constants::normal;
473 boost::match_flag_type mf = boost::regex_constants::match_default;
474 bool fglobal = false;
476 std::vector<MNode*> params;
477 std::vector<MNode*> keywords;
478 static paramList kwlist[] = {
479 {CharConst ("i"), true},
480 {CharConst ("g"), true},
481 {CharConst ("global"), true},
485 setParams (arg, 3, ¶ms, kwlist, &keywords, NULL);
486 reg = eval_str (params[0], mlenv);
487 to = eval_str (params[1], mlenv);
488 text = eval_str (params[2], mlenv);
489 if (keywords[0] && eval_bool (keywords[0], mlenv))
490 f |= boost::regex_constants::icase;
491 if (keywords[1] && eval_bool (keywords[1], mlenv))
493 if (keywords[2] && eval_bool (keywords[2], mlenv))
497 mf |= boost::regex_constants::format_first_only;
498 ans = wreplace (text, reg, to, f, mf);
500 return newMNode_str (new ustring (ans));
505 (regexp-split REGEX STRING [#i | :i BOOL]) -> (PREMATCH_STRING POSTMATCH_STRING)
508 //#AFUNC regexp-split ml_regexp_split
509 //#WIKIFUNC regexp-split
510 MNode* ml_regexp_split (MNode* cell, MlEnv* mlenv) {
511 MNode* arg = cell->cdr ();
514 boost::wregex::flag_type f = boost::regex_constants::normal;
516 std::vector<MNode*> params;
517 std::vector<MNode*> keywords;
518 static paramList kwlist[] = {
519 {CharConst ("i"), true},
523 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
524 reg = eval_str (params[0], mlenv);
525 text = eval_str (params[1], mlenv);
526 if (keywords[0] && eval_bool (keywords[0], mlenv))
527 f |= boost::regex_constants::icase;
529 if (wsearch_env (mlenv, text, reg, f)) {
530 std::wstring::const_iterator b = mlenv->regtext.begin ();
531 std::wstring::const_iterator e = mlenv->regtext.end ();
532 ans.append (newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regmatch[0].first)))));
533 ans.append (newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[0].second, e)))));
535 ans.append (newMNode_str (new ustring (text)));
539 return ans.release ();
544 (split REGEX STRING) -> STRING_LIST
547 //#AFUNC split ml_split
549 MNode* ml_split (MNode* cell, MlEnv* mlenv) {
550 MNode* arg = cell->cdr ();
555 std::vector<MNode*> params;
556 std::vector<MNode*> keywords;
557 static paramList kwlist[] = {
558 {CharConst ("keep"), true}, // 空フィールドの削除をしない
562 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
563 reg = eval_str (params[0], mlenv);
564 text = eval_str (params[1], mlenv);
565 if (keywords[0] && eval_bool (keywords[0], mlenv))
569 std::wstring wt = utow (text);
570 std::wstring wreg = utow (reg);
571 boost::wregex wre (wreg);
572 WSplitter sp (wt, wre);
573 size_t m = wt.length () + 1;
575 bool (WSplitter::*nfn)();
577 nfn = &WSplitter::nextSep;
579 nfn = &WSplitter::next;
580 while ((sp.*nfn) ()) {
581 ans.append (newMNode_str (new ustring (sp.cur ())));
584 throw (uErrorRegexp);
587 ans.append (newMNode_str (new ustring (sp.cur ())));
588 } catch (boost::regex_error& err) {
589 throw (uErrorRegexp);
591 return ans.release ();
596 (string-join TEXT [STRING | ARRAY | LIST]...) -> STRING
599 //#AFUNC string-join ml_string_join
600 //#WIKIFUNC string-join
601 MNode* ml_string_join (MNode* cell, MlEnv* mlenv) {
602 MNode* arg = cell->cdr ();
612 throw (uErrorWrongNumber);
614 sep = eval_str (arg->car (), mlenv);
615 nextNodeNonNil (arg);
618 val = eval (arg->car (), mlenv);
622 if (val ()->isSym ()) {
623 var = val ()->to_string ();
625 n = mlenv->getArySize (var);
626 for (i = 1; i <= n; i ++) {
631 v = mlenv->getAry (var, i);
633 ans.append (v->to_string ());
635 } else if (val ()->isCons ()) {
637 for (; a && a->isCons (); a = a->cdr ()) {
642 if (! isNil (a->car ()))
643 ans.append (a->car ()->to_string ());
646 var = val ()->to_string ();
655 return newMNode_str (new ustring (ans));
660 (password-match PASSWORD CRYPT) -> BOOL
663 //#AFUNC password-match ml_password_match
664 //#WIKIFUNC password-match
665 MNode* ml_password_match (MNode* cell, MlEnv* mlenv) {
666 MNode* arg = cell->cdr ();
671 throw (uErrorWrongNumber);
672 pass = eval_str (arg->car (), mlenv);
673 nextNodeNonNil (arg);
674 cpass = eval_str (arg->car (), mlenv);
677 throw (uErrorWrongNumber);
679 return newMNode_bool (passMatch (pass, cpass));
684 (password-crypt PASSWORD) -> STRING
687 //#AFUNC password-crypt ml_password_crypt
688 //#WIKIFUNC password-crypt
689 MNode* ml_password_crypt (MNode* cell, MlEnv* mlenv) {
690 MNode* arg = cell->cdr ();
694 throw (uErrorWrongNumber);
695 pass = eval_str (arg->car (), mlenv);
698 throw (uErrorWrongNumber);
700 return newMNode_str (new ustring (passCrypt (pass)));
705 (substring STR INDEX LENGTH) -> STRING
706 (substring STR INDEX) -> STRING
709 //#AFUNC substring ml_substring
710 //#WIKIFUNC substring
711 MNode* ml_substring (MNode* cell, MlEnv* mlenv) {
712 MNode* arg = cell->cdr ();
720 throw (uErrorWrongNumber);
721 str = eval_str (arg->car (), mlenv);
722 nextNodeNonNil (arg);
723 index = eval_int (arg->car (), mlenv);
727 length = eval_int (arg->car (), mlenv);
733 throw (uErrorWrongNumber);
735 substring (str, index, length, mode == 3, ans);
736 return newMNode_str (new ustring (ans));
741 (length STRING) -> NUMBER
744 //#AFUNC length ml_length
746 MNode* ml_length (MNode* cell, MlEnv* mlenv) {
747 MNode* arg = cell->cdr ();
752 throw (uErrorWrongNumber);
753 str = eval_str (arg->car (), mlenv);
756 throw (uErrorWrongNumber);
758 ans = strLength (str);
759 return newMNode_num (ans);
764 (pad0 NUMBER STRING) -> STRING
765 (pad0 NUMBER STRING_LIST) -> STRING_LIST
766 (pad0 NUMBER_LIST STRING_LIST) -> STRING_LIST
769 //#AFUNC pad0 ml_pad0
771 MNode* ml_pad0 (MNode* cell, MlEnv* mlenv) {
772 MNode* arg = cell->cdr ();
781 throw (uErrorWrongNumber);
782 num = np = eval (arg->car (), mlenv);
783 nextNodeNonNil (arg);
784 val = vp = eval (arg->car (), mlenv);
787 throw (uErrorWrongNumber);
795 n = to_int (np->car ());
801 ans.append (newMNode_str (new ustring (zeroPad (n, to_string (vp->car ())))));
803 if (vp && ! vp->isCons ())
806 return ans.release ();
810 n = to_int (np->car ());
814 return newMNode_str (new ustring (zeroPad (n, to_string (vp))));
823 (ellipsis NUM STRING) -> STRING
826 //#AFUNC ellipsis ml_ellipsis
828 MNode* ml_ellipsis (MNode* cell, MlEnv* mlenv) {
829 MNode* arg = cell->cdr ();
834 throw (uErrorWrongNumber);
835 num = eval_int (arg->car (), mlenv);
836 nextNodeNonNil (arg);
837 str = eval_str (arg->car (), mlenv);
840 throw (uErrorWrongNumber);
842 str = ellipsis (str, num);
843 return newMNode_str (new ustring (str));
848 (string-format FORMAT LIST-OF-ARGS) -> STRING
849 (string-format FORMAT ARGS...) -> STRING
851 |h:format|h:sample|h:note|
853 |${''NUM'':hex:''NUM''}|${1:hex:4}||
854 |${''NUM'':HEX:''NUM''}|${1:HEX:4}||
855 |${''NUM'':int:''NUM''}|${1:int:5}||
856 |${''NUM'':int:''NUM'':c}|${1:int:5:c}||
857 |${''NUM'':int:''NUM'':comma}|${1:int:5:comma}||
858 |${''NUM'':int:''NUM'':clip}|${1:int:5:clip}||
859 |${''NUM'':int:''NUM'':0}|${1:int:5:0}||
860 |${''NUM'':float:''NUM'':''NUM''}|${1:float:4:3}||
861 |${''NUM'':string:''NUM''}|${1:string:20}||
862 |${''NUM'':string:''NUM'':right}|${1:string:20:right}||
863 |${''NUM'':month}|${1:month}|Jan, Feb,...|
864 |${''NUM'':Month}|${1:Month}|January, February,...|
865 |${''NUM'':week}|${1:week}|Sun, Mon,...|
866 |${''NUM'':Week}|${1:Week}|Sunday, Monday,...|
869 //#AFUNC string-format ml_string_format
870 //#WIKIFUNC string-format
871 MNode* ml_string_format (MNode* cell, MlEnv* mlenv) {
872 MNode* arg = cell->cdr ();
874 boost::ptr_vector<MNodePtr> par;
878 throw (uErrorWrongNumber);
879 format = eval_str (arg->car (), mlenv);
882 a = eval (arg->car (), mlenv);
883 if (a && a->isCons ()) {
887 par.push_back (new MNodePtr);
888 par.back () = a->car ();
892 par.push_back (new MNodePtr);
898 return newMNode_str (new ustring (formatString (format, par)));
903 (random-key) -> STRING
906 //#AFUNC random-key ml_random_key
907 //#WIKIFUNC random-key
908 MNode* ml_random_key (MNode* cell, MlEnv* mlenv) {
909 MNode* arg = cell->cdr ();
912 throw (uErrorWrongNumber);
914 return newMNode_str (new ustring (randomKey ()));
918 ===date-format, gmdate-format===
919 (date-format FORMAT INTEGER) -> STRING
920 (gmdate-format FORMAT INTEGER) -> STRING
931 //#AFUNC date-format ml_date_format
932 //#WIKIFUNC date-format
933 MNode* ml_date_format (MNode* cell, MlEnv* mlenv) {
934 MNode* arg = cell->cdr ();
940 throw (uErrorWrongNumber);
941 format = eval_str (arg->car (), mlenv);
942 nextNodeNonNil (arg);
943 tm = eval_int (arg->car (), mlenv);
946 throw (uErrorWrongNumber);
948 localtime_r (&tm, &tmv);
949 return newMNode_str (new ustring (formatDateString (format, tmv)));
952 //#AFUNC gmdate-format ml_gmdate_format
953 //#WIKIFUNC gmdate-format
954 MNode* ml_gmdate_format (MNode* cell, MlEnv* mlenv) {
955 MNode* arg = cell->cdr ();
961 throw (uErrorWrongNumber);
962 format = eval_str (arg->car (), mlenv);
963 nextNodeNonNil (arg);
964 tm = eval_int (arg->car (), mlenv);
967 throw (uErrorWrongNumber);
969 gmtime_r (&tm, &tmv);
970 return newMNode_str (new ustring (formatDateString (format, tmv)));
975 (to-string OBJECT) -> STRING
978 //#AFUNC to-string ml_to_string
979 //#WIKIFUNC to-string
980 MNode* ml_to_string (MNode* cell, MlEnv* mlenv) {
981 MNode* arg = cell->cdr ();
985 throw (uErrorWrongNumber);
986 text = eval_str (arg->car (), mlenv);
989 throw (uErrorWrongNumber);
991 return newMNode_str (new ustring (text));
996 (to-symbol STRING) -> SYMBOL
999 //#AFUNC to-symbol ml_to_symbol
1000 //#WIKIFUNC to-symbol
1001 MNode* ml_to_symbol (MNode* cell, MlEnv* mlenv) {
1002 MNode* arg = cell->cdr ();
1006 throw (uErrorWrongNumber);
1007 text = eval (arg->car (), mlenv);
1010 throw (uErrorWrongNumber);
1013 if (text ()->isSym ()) {
1014 return text.release ();
1016 return newMNode_sym (new ustring (text ()->to_string ()));
1021 // return newMNode_str (new ustring (text));
1026 (dump-to-sexp OBJECT...) -> STRING
1029 //#AFUNC dump-to-sexp ml_dump_to_sexp
1030 //#WIKIFUNC dump-to-sexp
1031 MNode* ml_dump_to_sexp (MNode* cell, MlEnv* mlenv) {
1032 MNode* arg = cell->cdr ();
1037 // text = eval_str (arg->car (), mlenv);
1038 e = eval (arg->car (), mlenv);
1040 if (text.length () > 0)
1041 text.append (CharConst (" "));
1042 text.append (dump_to_sexp (e ()));
1044 return newMNode_str (new ustring (text));
1049 // (to-sexp STRING) -> OBJECT
1051 (read-sexp STRING) -> OBJECT
1054 // //#AFUNC to-sexp ml_to_sexp
1055 // //#WIKIFUNC to-sexp
1056 //#AFUNC read-sexp ml_read_sexp
1057 //#WIKIFUNC read-sexp
1058 //MNode* ml_to_sexp (MNode* cell, MlEnv* mlenv) {
1059 MNode* ml_read_sexp (MNode* cell, MlEnv* mlenv) {
1060 MNode* arg = cell->cdr ();
1062 MotorSexp ml (NULL);
1065 throw (uErrorWrongNumber);
1066 text = eval_str (arg->car (), mlenv);
1069 throw (uErrorWrongNumber);
1073 if (ml.top.isCons () && ml.top.cdr ()->isCons ())
1074 return mlenv->retval = ml.top.cdr ()->car ();
1081 (is-ascii63 STRING) -> BOOL
1084 //#AFUNC is-ascii63 ml_is_ascii63
1085 //#WIKIFUNC is-ascii63
1086 MNode* ml_is_ascii63 (MNode* cell, MlEnv* mlenv) {
1087 MNode* arg = cell->cdr ();
1092 throw (uErrorWrongNumber);
1093 text = eval_str (arg->car (), mlenv);
1096 throw (uErrorWrongNumber);
1098 ans = checkASCII (text);
1100 return newMNode_bool (ans);
1105 (sort-string LIST [#asc] [#desc]) -> LIST
1108 //#AFUNC sort-string ml_sort_string
1109 //#WIKIFUNC sort-string
1110 MNode* ml_sort_string (MNode* cell, MlEnv* mlenv) {
1111 MNode* arg = cell->cdr ();
1115 std::vector<MNode*> list;
1117 std::vector<MNode*> params;
1118 std::vector<MNode*> keywords;
1119 static paramList kwlist[] = {
1120 {CharConst ("asc"), true},
1121 {CharConst ("desc"), true},
1125 setParams (arg, 1, ¶ms, kwlist, &keywords, NULL);
1126 h = eval (params[0], mlenv);
1127 if (keywords[0] && eval_bool (keywords[0], mlenv))
1129 if (keywords[1] && eval_bool (keywords[1], mlenv))
1135 if (a->car () && a->car ()->isStr ()) {
1136 list.push_back (a->car ());
1138 list.push_back (NULL);
1147 int n = list.size ();
1148 for (i = 1; i < n; i ++) {
1164 else if (fdesc ^ (*list[k]->str >= *list[j]->str))
1166 // swap (v[k], v[j]);
1167 a = list[j]; list[j] = list[k]; list[k] = a;
1171 for (; n > 0; n --) {
1172 // swap (v[0], v[n - 1]);
1173 a = list[n - 1]; list[n - 1] = list[0]; list[0] = a;
1174 for (i = 1; i < n - 1; i ++) {
1178 // if (! list[k] || ! list[j])
1192 else if (fdesc ^ (*list[k]->str >= *list[j]->str))
1194 // swap (v[k], v[j]);
1195 a = list[j]; list[j] = list[k]; list[k] = a;
1202 for (i = 0; i < n; i ++) {
1203 ans.append (list[i]);
1205 return ans.release ();
1210 (to-upper STRING) -> STRING
1213 //#AFUNC to-upper ml_to_upper
1214 //#WIKIFUNC to-upper
1215 MNode* ml_to_upper (MNode* cell, MlEnv* mlenv) {
1216 MNode* arg = cell->cdr ();
1220 throw (uErrorWrongNumber);
1221 text = eval_str (arg->car (), mlenv);
1224 throw (uErrorWrongNumber);
1226 return newMNode_str (new ustring (toUpper (text)));
1231 (to-lower STRING) -> STRING
1234 //#AFUNC to-lower ml_to_lower
1235 //#WIKIFUNC to-lower
1236 MNode* ml_to_lower (MNode* cell, MlEnv* mlenv) {
1237 MNode* arg = cell->cdr ();
1241 throw (uErrorWrongNumber);
1242 text = eval_str (arg->car (), mlenv);
1245 throw (uErrorWrongNumber);
1247 return newMNode_str (new ustring (toLower (text)));