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 (concat STRING...) -> STRING
27 パラメータの文字列を連結して一つの文字列を返す。
30 //#AFUNC concat ml_concat
32 MNode* ml_concat (MNode* cell, MlEnv* mlenv) {
33 MNode* arg = cell->cdr ();
34 AutoDelete<ustring> a1;
37 // a1 ()->reserve (256);
40 a1 ()->append (eval_str (arg->car (), mlenv));
43 return newMNode_str (a1.release ());
48 (megabyte NUMBER) -> STRING
51 //#AFUNC megabyte ml_megabyte
53 MNode* ml_megabyte (MNode* cell, MlEnv* mlenv) {
54 MNode* arg = cell->cdr ();
59 throw (uErrorWrongNumber);
61 val = eval_double (arg->car (), mlenv);
64 throw (uErrorWrongNumber);
68 return newMNode_str (new ustring (u));
70 val = floor (val / 1024. * 10.) / 10.;
73 u.append (CharConst ("K"));
74 return newMNode_str (new ustring (u));
76 val = floor (val / 1024. * 10. ) / 10.;
79 u.append (CharConst ("M"));
80 return newMNode_str (new ustring (u));
82 val = floor (val / 1024. * 10.) / 10.;
85 u.append (CharConst ("G"));
86 return newMNode_str (new ustring (u));
88 val = floor (val / 1024. * 10.) / 10.;
91 u.append (CharConst ("T"));
92 return newMNode_str (new ustring (u));
94 val = floor (val / 1024. * 10.) / 10.;
96 u.append (CharConst ("P"));
97 return newMNode_str (new ustring (u));
102 (c3 INTEGER) -> STRING
107 MNode* ml_c3 (MNode* cell, MlEnv* mlenv) {
108 MNode* arg = cell->cdr ();
112 throw (uErrorWrongNumber);
114 u = eval_str (arg->car (), mlenv);
117 throw (uErrorWrongNumber);
119 return newMNode_str (new ustring (c3 (u)));
124 (regexp-match REGEX TEXT [#i | :i BOOL]) -> BOOL
127 //#AFUNC regexp-match ml_regexp_match
128 //#WIKIFUNC regexp-match
129 MNode* ml_regexp_match (MNode* cell, MlEnv* mlenv) {
130 MNode* arg = cell->cdr ();
133 boost::wregex::flag_type f = boost::regex_constants::normal;
135 std::vector<MNode*> params;
136 std::vector<MNode*> keywords;
137 static paramList kwlist[] = {
138 {CharConst ("i"), true},
142 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
143 reg = eval_str (params[0], mlenv);
144 text = eval_str (params[1], mlenv);
145 if (keywords[0] && eval_bool (keywords[0], mlenv))
146 f |= boost::regex_constants::icase;
148 ans = wsearch_env (mlenv, text, reg, f);
150 return newMNode_bool (ans);
155 (match-string NUM) -> STRING
158 //#AFUNC match-string ml_match_string
159 //#WIKIFUNC match-string
160 MNode* ml_match_string (MNode* cell, MlEnv* mlenv) {
161 MNode* arg = cell->cdr ();
166 throw (uErrorWrongNumber);
167 n = eval_int (arg->car (), mlenv);
170 throw (uErrorWrongNumber);
172 if (0 <= n && n < mlenv->regmatch.size ()) {
173 ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[n].first, mlenv->regmatch[n].second))));
184 //#AFUNC prematch ml_prematch
186 MNode* ml_prematch (MNode* cell, MlEnv* mlenv) {
187 MNode* arg = cell->cdr ();
189 std::wstring::const_iterator b = mlenv->regtext.begin ();
192 throw (uErrorWrongNumber);
194 ans = newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regmatch[0].first))));
201 (postmatch) -> STRING
204 //#AFUNC postmatch ml_postmatch
205 //#WIKIFUNC postmatch
206 MNode* ml_postmatch (MNode* cell, MlEnv* mlenv) {
207 MNode* arg = cell->cdr ();
209 std::wstring::const_iterator e = mlenv->regtext.end ();
212 throw (uErrorWrongNumber);
214 ans = newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[0].second, e))));
221 (string-filter REGEX STRING [#i | :i BOOL] [:max NUM]) -> STRING
224 //#AFUNC string-filter ml_string_filter
225 //#WIKIFUNC string-filter
226 MNode* ml_string_filter (MNode* cell, MlEnv* mlenv) {
227 MNode* arg = cell->cdr ();
230 boost::wregex::flag_type f = boost::regex_constants::normal;
233 std::vector<MNode*> params;
234 std::vector<MNode*> keywords;
235 static paramList kwlist[] = {
236 {CharConst ("i"), true},
237 {CharConst ("max"), false},
241 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
242 reg = eval_str (params[0], mlenv);
243 text = eval_str (params[1], mlenv);
244 if (keywords[0] && eval_bool (keywords[0], mlenv))
245 f |= boost::regex_constants::icase;
252 if (wsearch_env (mlenv, text, reg, f)) {
253 ustring ans = wtou (std::wstring (mlenv->regmatch[0].first, mlenv->regmatch[0].second));
255 substring (ans, 0, max, true, ans);
257 return newMNode_str (new ustring (ans));
259 return NULL; // unmatched
265 (regexp-replace REGEX TO_TEXT TEXT [#i | :i BOOL] [#g | #global | :g BOOL | :global BOOL]) -> TEXT
268 //#AFUNC regexp-replace ml_regexp_replace
269 //#WIKIFUNC regexp-replace
270 MNode* ml_regexp_replace (MNode* cell, MlEnv* mlenv) {
271 MNode* arg = cell->cdr ();
275 boost::wregex::flag_type f = boost::regex_constants::normal;
276 boost::match_flag_type mf = boost::regex_constants::match_default;
277 bool fglobal = false;
279 std::vector<MNode*> params;
280 std::vector<MNode*> keywords;
281 static paramList kwlist[] = {
282 {CharConst ("i"), true},
283 {CharConst ("g"), true},
284 {CharConst ("global"), true},
288 setParams (arg, 3, ¶ms, kwlist, &keywords, NULL);
289 reg = eval_str (params[0], mlenv);
290 to = eval_str (params[1], mlenv);
291 text = eval_str (params[2], mlenv);
292 if (keywords[0] && eval_bool (keywords[0], mlenv))
293 f |= boost::regex_constants::icase;
294 if (keywords[1] && eval_bool (keywords[1], mlenv))
296 if (keywords[2] && eval_bool (keywords[2], mlenv))
300 mf |= boost::regex_constants::format_first_only;
301 ans = wreplace (text, reg, to, f, mf);
303 return newMNode_str (new ustring (ans));
308 (regexp-split REGEX STRING [#i | :i BOOL]) -> (PREMATCH_STRING POSTMATCH_STRING)
311 //#AFUNC regexp-split ml_regexp_split
312 //#WIKIFUNC regexp-split
313 MNode* ml_regexp_split (MNode* cell, MlEnv* mlenv) {
314 MNode* arg = cell->cdr ();
317 boost::wregex::flag_type f = boost::regex_constants::normal;
319 std::vector<MNode*> params;
320 std::vector<MNode*> keywords;
321 static paramList kwlist[] = {
322 {CharConst ("i"), true},
326 setParams (arg, 2, ¶ms, kwlist, &keywords, NULL);
327 reg = eval_str (params[0], mlenv);
328 text = eval_str (params[1], mlenv);
329 if (keywords[0] && eval_bool (keywords[0], mlenv))
330 f |= boost::regex_constants::icase;
332 if (wsearch_env (mlenv, text, reg, f)) {
333 std::wstring::const_iterator b = mlenv->regtext.begin ();
334 std::wstring::const_iterator e = mlenv->regtext.end ();
335 ans.append (newMNode_str (new ustring (wtou (std::wstring (b, mlenv->regmatch[0].first)))));
336 ans.append (newMNode_str (new ustring (wtou (std::wstring (mlenv->regmatch[0].second, e)))));
338 ans.append (newMNode_str (new ustring (text)));
342 return ans.release ();
347 (split REGEX STRING) -> STRING_LIST
350 //#AFUNC split ml_split
352 MNode* ml_split (MNode* cell, MlEnv* mlenv) {
353 MNode* arg = cell->cdr ();
359 throw (uErrorWrongNumber);
361 reg = eval_str (arg->car (), mlenv);
362 nextNodeNonNil (arg);
363 t = eval_str (arg->car (), mlenv);
367 throw (uErrorWrongNumber);
370 std::wstring wt = utow (t);
371 std::wstring wreg = utow (reg);
372 boost::wregex wre (wreg);
373 WSplitter sp (wt, wre);
374 size_t m = wt.length () + 1;
377 ans.append (newMNode_str (new ustring (sp.cur ())));
380 throw (uErrorRegexp);
382 } catch (boost::regex_error& err) {
383 throw (uErrorRegexp);
385 return ans.release ();
390 (string-join TEXT [STRING | ARRAY | LIST]...) -> STRING
393 //#AFUNC string-join ml_string_join
394 //#WIKIFUNC string-join
395 MNode* ml_string_join (MNode* cell, MlEnv* mlenv) {
396 MNode* arg = cell->cdr ();
406 throw (uErrorWrongNumber);
408 sep = eval_str (arg->car (), mlenv);
409 nextNodeNonNil (arg);
412 val = eval (arg->car (), mlenv);
416 if (val ()->isSym ()) {
417 var = val ()->to_string ();
419 n = mlenv->getArySize (var);
420 for (i = 1; i <= n; i ++) {
425 v = mlenv->getAry (var, i);
427 ans.append (v->to_string ());
429 } else if (val ()->isCons ()) {
431 for (; a && a->isCons (); a = a->cdr ()) {
436 if (! isNil (a->car ()))
437 ans.append (a->car ()->to_string ());
440 var = val ()->to_string ();
449 return newMNode_str (new ustring (ans));
454 (password-match PASSWORD CRYPT) -> BOOL
457 //#AFUNC password-match ml_password_match
458 //#WIKIFUNC password-match
459 MNode* ml_password_match (MNode* cell, MlEnv* mlenv) {
460 MNode* arg = cell->cdr ();
465 throw (uErrorWrongNumber);
466 pass = eval_str (arg->car (), mlenv);
467 nextNodeNonNil (arg);
468 cpass = eval_str (arg->car (), mlenv);
471 throw (uErrorWrongNumber);
473 return newMNode_bool (passMatch (pass, cpass));
478 (password-crypt PASSWORD) -> STRING
481 //#AFUNC password-crypt ml_password_crypt
482 //#WIKIFUNC password-crypt
483 MNode* ml_password_crypt (MNode* cell, MlEnv* mlenv) {
484 MNode* arg = cell->cdr ();
488 throw (uErrorWrongNumber);
489 pass = eval_str (arg->car (), mlenv);
492 throw (uErrorWrongNumber);
494 return newMNode_str (new ustring (passCrypt (pass)));
499 (substring STR INDEX LENGTH) -> STRING
500 (substring STR INDEX) -> STRING
503 //#AFUNC substring ml_substring
504 //#WIKIFUNC substring
505 MNode* ml_substring (MNode* cell, MlEnv* mlenv) {
506 MNode* arg = cell->cdr ();
514 throw (uErrorWrongNumber);
515 str = eval_str (arg->car (), mlenv);
516 nextNodeNonNil (arg);
517 index = eval_int (arg->car (), mlenv);
521 length = eval_int (arg->car (), mlenv);
527 throw (uErrorWrongNumber);
529 substring (str, index, length, mode == 3, ans);
530 return newMNode_str (new ustring (ans));
535 (length STRING) -> NUMBER
538 //#AFUNC length ml_length
540 MNode* ml_length (MNode* cell, MlEnv* mlenv) {
541 MNode* arg = cell->cdr ();
546 throw (uErrorWrongNumber);
547 str = eval_str (arg->car (), mlenv);
550 throw (uErrorWrongNumber);
552 ans = strLength (str);
553 return newMNode_num (ans);
558 (pad0 NUMBER STRING) -> STRING
559 (pad0 NUMBER STRING_LIST) -> STRING_LIST
560 (pad0 NUMBER_LIST STRING_LIST) -> STRING_LIST
563 //#AFUNC pad0 ml_pad0
565 MNode* ml_pad0 (MNode* cell, MlEnv* mlenv) {
566 MNode* arg = cell->cdr ();
575 throw (uErrorWrongNumber);
576 num = np = eval (arg->car (), mlenv);
577 nextNodeNonNil (arg);
578 val = vp = eval (arg->car (), mlenv);
581 throw (uErrorWrongNumber);
589 n = to_int (np->car ());
595 ans.append (newMNode_str (new ustring (zeroPad (n, to_string (vp->car ())))));
597 if (vp && ! vp->isCons ())
600 return ans.release ();
604 n = to_int (np->car ());
608 return newMNode_str (new ustring (zeroPad (n, to_string (vp))));
617 (ellipsis NUM STRING) -> STRING
620 //#AFUNC ellipsis ml_ellipsis
622 MNode* ml_ellipsis (MNode* cell, MlEnv* mlenv) {
623 MNode* arg = cell->cdr ();
628 throw (uErrorWrongNumber);
629 num = eval_int (arg->car (), mlenv);
630 nextNodeNonNil (arg);
631 str = eval_str (arg->car (), mlenv);
634 throw (uErrorWrongNumber);
636 str = ellipsis (str, num);
637 return newMNode_str (new ustring (str));
642 (string-format FORMAT LIST-OF-ARGS) -> STRING
643 (string-format FORMAT ARGS...) -> STRING
645 |h:format|h:sample|h:note|
647 |${''NUM'':hex:''NUM''}|${1:hex:4}||
648 |${''NUM'':HEX:''NUM''}|${1:HEX:4}||
649 |${''NUM'':int:''NUM''}|${1:int:5}||
650 |${''NUM'':int:''NUM'':c}|${1:int:5:c}||
651 |${''NUM'':int:''NUM'':comma}|${1:int:5:comma}||
652 |${''NUM'':int:''NUM'':clip}|${1:int:5:clip}||
653 |${''NUM'':int:''NUM'':0}|${1:int:5:0}||
654 |${''NUM'':float:''NUM'':''NUM''}|${1:float:4:3}||
655 |${''NUM'':string:''NUM''}|${1:string:20}||
656 |${''NUM'':string:''NUM'':right}|${1:string:20:right}||
657 |${''NUM'':month}|${1:month}|Jan, Feb,...|
658 |${''NUM'':Month}|${1:Month}|January, February,...|
659 |${''NUM'':week}|${1:week}|Sun, Mon,...|
660 |${''NUM'':Week}|${1:Week}|Sunday, Monday,...|
663 //#AFUNC string-format ml_string_format
664 //#WIKIFUNC string-format
665 MNode* ml_string_format (MNode* cell, MlEnv* mlenv) {
666 MNode* arg = cell->cdr ();
668 boost::ptr_vector<MNodePtr> par;
672 throw (uErrorWrongNumber);
673 format = eval_str (arg->car (), mlenv);
676 a = eval (arg->car (), mlenv);
677 if (a && a->isCons ()) {
681 par.push_back (new MNodePtr);
682 par.back () = a->car ();
686 par.push_back (new MNodePtr);
692 return newMNode_str (new ustring (formatString (format, par)));
697 (random-key) -> STRING
700 //#AFUNC random-key ml_random_key
701 //#WIKIFUNC random-key
702 MNode* ml_random_key (MNode* cell, MlEnv* mlenv) {
703 MNode* arg = cell->cdr ();
706 throw (uErrorWrongNumber);
708 return newMNode_str (new ustring (randomKey ()));
712 ===date-format, gmdate-format===
713 (date-format FORMAT INTEGER) -> STRING
714 (gmdate-format FORMAT INTEGER) -> STRING
725 //#AFUNC date-format ml_date_format
726 //#WIKIFUNC date-format
727 MNode* ml_date_format (MNode* cell, MlEnv* mlenv) {
728 MNode* arg = cell->cdr ();
734 throw (uErrorWrongNumber);
735 format = eval_str (arg->car (), mlenv);
736 nextNodeNonNil (arg);
737 tm = eval_int (arg->car (), mlenv);
740 throw (uErrorWrongNumber);
742 localtime_r (&tm, &tmv);
743 return newMNode_str (new ustring (formatDateString (format, tmv)));
746 //#AFUNC gmdate-format ml_gmdate_format
747 //#WIKIFUNC gmdate-format
748 MNode* ml_gmdate_format (MNode* cell, MlEnv* mlenv) {
749 MNode* arg = cell->cdr ();
755 throw (uErrorWrongNumber);
756 format = eval_str (arg->car (), mlenv);
757 nextNodeNonNil (arg);
758 tm = eval_int (arg->car (), mlenv);
761 throw (uErrorWrongNumber);
763 gmtime_r (&tm, &tmv);
764 return newMNode_str (new ustring (formatDateString (format, tmv)));
769 (to-string OBJECT) -> STRING
772 //#AFUNC to-string ml_to_string
773 //#WIKIFUNC to-string
774 MNode* ml_to_string (MNode* cell, MlEnv* mlenv) {
775 MNode* arg = cell->cdr ();
779 throw (uErrorWrongNumber);
780 text = eval_str (arg->car (), mlenv);
783 throw (uErrorWrongNumber);
785 return newMNode_str (new ustring (text));
790 (dump-to-sexp OBJECT...) -> STRING
793 //#AFUNC dump-to-sexp ml_dump_to_sexp
794 //#WIKIFUNC dump-to-sexp
795 MNode* ml_dump_to_sexp (MNode* cell, MlEnv* mlenv) {
796 MNode* arg = cell->cdr ();
801 // text = eval_str (arg->car (), mlenv);
802 e = eval (arg->car (), mlenv);
804 if (text.length () > 0)
805 text.append (CharConst (" "));
806 text.append (dump_to_sexp (e ()));
808 return newMNode_str (new ustring (text));
813 // (to-sexp STRING) -> OBJECT
815 (read-sexp STRING) -> OBJECT
818 // //#AFUNC to-sexp ml_to_sexp
819 // //#WIKIFUNC to-sexp
820 //#AFUNC read-sexp ml_read_sexp
821 //#WIKIFUNC read-sexp
822 //MNode* ml_to_sexp (MNode* cell, MlEnv* mlenv) {
823 MNode* ml_read_sexp (MNode* cell, MlEnv* mlenv) {
824 MNode* arg = cell->cdr ();
829 throw (uErrorWrongNumber);
830 text = eval_str (arg->car (), mlenv);
833 throw (uErrorWrongNumber);
837 if (ml.top.isCons () && ml.top.cdr ()->isCons ())
838 return mlenv->retval = ml.top.cdr ()->car ();
845 (is-ascii63 STRING) -> BOOL
848 //#AFUNC is-ascii63 ml_is_ascii63
849 //#WIKIFUNC is-ascii63
850 MNode* ml_is_ascii63 (MNode* cell, MlEnv* mlenv) {
851 MNode* arg = cell->cdr ();
856 throw (uErrorWrongNumber);
857 text = eval_str (arg->car (), mlenv);
860 throw (uErrorWrongNumber);
862 ans = checkASCII (text);
864 return newMNode_bool (ans);
869 (sort-string LIST [#asc] [#desc]) -> LIST
872 //#AFUNC sort-string ml_sort_string
873 //#WIKIFUNC sort-string
874 MNode* ml_sort_string (MNode* cell, MlEnv* mlenv) {
875 MNode* arg = cell->cdr ();
879 std::vector<MNode*> list;
881 std::vector<MNode*> params;
882 std::vector<MNode*> keywords;
883 static paramList kwlist[] = {
884 {CharConst ("asc"), true},
885 {CharConst ("desc"), true},
889 setParams (arg, 1, ¶ms, kwlist, &keywords, NULL);
890 h = eval (params[0], mlenv);
891 if (keywords[0] && eval_bool (keywords[0], mlenv))
893 if (keywords[1] && eval_bool (keywords[1], mlenv))
899 if (a->car () && a->car ()->isStr ()) {
900 list.push_back (a->car ());
902 list.push_back (NULL);
911 int n = list.size ();
912 for (i = 1; i < n; i ++) {
928 else if (fdesc ^ (*list[k]->str >= *list[j]->str))
930 // swap (v[k], v[j]);
931 a = list[j]; list[j] = list[k]; list[k] = a;
935 for (; n > 0; n --) {
936 // swap (v[0], v[n - 1]);
937 a = list[n - 1]; list[n - 1] = list[0]; list[0] = a;
938 for (i = 1; i < n - 1; i ++) {
942 // if (! list[k] || ! list[j])
956 else if (fdesc ^ (*list[k]->str >= *list[j]->str))
958 // swap (v[k], v[j]);
959 a = list[j]; list[j] = list[k]; list[k] = a;
966 for (i = 0; i < n; i ++) {
967 ans.append (list[i]);
969 return ans.release ();
974 (to-upper STRING) -> STRING
977 //#AFUNC to-upper ml_to_upper
979 MNode* ml_to_upper (MNode* cell, MlEnv* mlenv) {
980 MNode* arg = cell->cdr ();
984 throw (uErrorWrongNumber);
985 text = eval_str (arg->car (), mlenv);
988 throw (uErrorWrongNumber);
990 return newMNode_str (new ustring (toUpper (text)));
995 (to-lower STRING) -> STRING
998 //#AFUNC to-lower ml_to_lower
1000 MNode* ml_to_lower (MNode* cell, MlEnv* mlenv) {
1001 MNode* arg = cell->cdr ();
1005 throw (uErrorWrongNumber);
1006 text = eval_str (arg->car (), mlenv);
1009 throw (uErrorWrongNumber);
1011 return newMNode_str (new ustring (toLower (text)));