OSDN Git Service

reverseiteratearray, reverseiteratevector wiki command.
authorvisor <visor@users.sourceforge.jp>
Fri, 17 Nov 2017 02:38:26 +0000 (11:38 +0900)
committervisor <visor@users.sourceforge.jp>
Fri, 17 Nov 2017 02:38:26 +0000 (11:38 +0900)
wiki/wikicmd.cc
wiki/wikicmd.h

index 8c656fb..9251485 100644 (file)
@@ -180,6 +180,83 @@ void  wc_doarray (WikiLine* wl, WikiFormat* wiki) {
     }
 }
 
+/*DOC:
+===$reverseiteratearray===
+ $reverseiteratearray:''VAR1'',''VAR2'',...[:''INDEX_VAR'']
+ ...
+ [$noperform]
+ ...
+ $enditerate
+
+逆順に実行する。
+
+*/
+//#WIKICMD     $reverseiteratearray    $noperform      $enditerate     wc_reversedoarray
+void  wc_reversedoarray (WikiLine* wl, WikiFormat* wiki) {
+    WikiMotor  motor (wl->begin, wl->end, wiki);
+    WikiMotorObjVec  objv;
+    WikiMotorObjVecVec  args;
+    std::vector<ustring>  lv;
+    ustring  iv;
+    int  i, n, iu, it;
+    MNodePtr  h;
+
+#ifdef WIKIREPEATPROTECT
+    if (wiki->protectMode && ! wl->fsuper) {
+#ifdef DEBUG
+       std::cerr << "(wiki):(protected)\n";
+#endif /* DEBUG */
+       return;
+    }
+#endif
+
+#ifdef DEBUG
+    std::cerr << "(wiki):" << ustring (wl->begin0, wl->end) << "\n";
+#endif /* DEBUG */
+    motor.compile (objv);
+    objv.splitCharA (':', args);
+    if (args.size () == 1 || args.size () == 2) {
+       WikiMotorObjVecVec  v;
+       args[0]->splitCharA (',', v);
+       for (int i = 0; i < v.size (); i ++)
+           lv.push_back (clipWhite (v[i]->textOut (wiki)));
+       if (args.size () == 2) {
+           iv = clipWhite (args[1]->textOut (wiki));
+       }
+    } else {
+       wiki->errorMsg.append (CharConst ("$iteratearray: wrong number of parameters.\n"));
+    }
+    iu = lv.size ();
+    if (iu > 0) {
+       n = wiki->mlenv->getArySize (lv[0]);
+       if (n > 0) {
+//         for (i = 1; i <= n; i ++) {
+           for (i = n; i >= 1; i --) {
+               for (it = 0; it < iu; it ++) {
+                   wiki->mlenv->setVar (lv[it], wiki->mlenv->getAry (lv[it], i));
+               }
+               if (iv.size () > 0) {
+                   h = newMNode_num (i);
+                   wiki->mlenv->setVar (iv, h ());
+               }
+               do_linevec (wl->block, wiki);
+               for (it = 0; it < iu; it ++) {
+                   wiki->mlenv->setAry (lv[it], i, wiki->mlenv->getVar (lv[it]));
+               }
+           }
+           for (it = 0; it < iu; it ++) {
+               wiki->mlenv->setArySize (lv[it], n);
+           }
+       } else {
+           if (wl->block2 && wl->block2->block)
+               do_linevec (wl->block2->block, wiki);
+       }
+    } else {
+       if (wl->block2 && wl->block2->block)
+           do_linevec (wl->block2->block, wiki);
+    }
+}
+
 /* ============================================================ */
 /*DOC:
 ===$iteratevector===
@@ -271,6 +348,93 @@ void  wc_dovector (WikiLine* wl, WikiFormat* wiki) {
     }
 }
 
+/*DOC:
+===$reverseiteratevector===
+ $reverseiteratevector:''VAR1'',''VAR2'',...[:''INDEX_VAR'']
+ ...
+ [$noperform]
+ ...
+ $enditerate
+
+逆順に実行する。
+
+*/
+//#WIKICMD     $reverseiteratevector   $noperform      $enditerate     wc_reversedovector
+void  wc_reversedovector (WikiLine* wl, WikiFormat* wiki) {
+    WikiMotor  motor (wl->begin, wl->end, wiki);
+    WikiMotorObjVec  objv;
+    WikiMotorObjVecVec  args;
+    std::vector<ustring>  lv;
+    boost::ptr_vector<MNodePtr>  lvv;
+    ustring  iv;
+    int  i, n, iu, it;
+    MNodePtr  h;
+    ustring  s;
+    MNode*  t;
+
+#ifdef WIKIREPEATPROTECT
+    if (wiki->protectMode && ! wl->fsuper) {
+#ifdef DEBUG
+       std::cerr << "(wiki):(protected)\n";
+#endif /* DEBUG */
+       return;
+    }
+#endif
+
+#ifdef DEBUG
+    std::cerr << "(wiki):" << ustring (wl->begin0, wl->end) << "\n";
+#endif /* DEBUG */
+    motor.compile (objv);
+    objv.splitCharA (':', args);
+    if (args.size () == 1 || args.size () == 2) {
+       WikiMotorObjVecVec  v;
+       args[0]->splitCharA (',', v);
+       for (int i = 0; i < v.size (); i ++) {
+           s = clipWhite (v[i]->textOut (wiki));
+           t = wiki->getVar (s);
+           if (isVector (t)) {
+               lv.push_back (s);
+               lvv.push_back (new MNodePtr);
+               lvv.back () = t;
+           } else if (isNil (t)) {
+           } else {
+               wiki->errorMsg.append (CharConst ("$iteratevector: bad value type.\n"));
+           }
+       }
+       if (args.size () == 2) {
+           iv = clipWhite (args[1]->textOut (wiki));
+       }
+    } else {
+       wiki->errorMsg.append (CharConst ("$iteratevector: wrong number of parameters.\n"));
+    }
+    iu = lv.size ();
+    if (iu > 0) {
+       n = lvv[0] ()->vectorSize ();
+       if (n > 0) {
+//         for (i = 0; i < n; ++ i) {
+           for (i = n - 1; i >= 0; -- i) {
+               for (it = 0; it < iu; ++ it) {
+                   wiki->mlenv->setVar (lv[it], lvv[it] ()->vectorGet (i));
+               }
+               if (iv.size () > 0) {
+                   h = newMNode_num (i);
+                   wiki->mlenv->setVar (iv, h ());
+               }
+               do_linevec (wl->block, wiki);
+           }
+           for (it = 0; it < iu; ++ it) {                      // 書き戻す
+               wiki->mlenv->setVar (lv[it], lvv[it] ());
+           }
+       } else {
+           if (wl->block2 && wl->block2->block)
+               do_linevec (wl->block2->block, wiki);
+       }
+    } else {
+       if (wl->block2 && wl->block2->block)
+           do_linevec (wl->block2->block, wiki);
+    }
+}
+
 /* ============================================================ */
 /*DOC:
 ===$iteratetable===
index d6e3012..55f6394 100644 (file)
@@ -9,7 +9,9 @@ class  WikiFormat;
 
 void  wc_repeat (WikiLine* wl, WikiFormat* wiki);
 void  wc_doarray (WikiLine* wl, WikiFormat* wiki);
+void  wc_reversedoarray (WikiLine* wl, WikiFormat* wiki);
 void  wc_dovector (WikiLine* wl, WikiFormat* wiki);
+void  wc_reversedovector (WikiLine* wl, WikiFormat* wiki);
 void  wc_dotable (WikiLine* wl, WikiFormat* wiki);
 void  wc_block (WikiLine* wl, WikiFormat* wiki);
 void  wc_setvar (WikiLine* wl, WikiFormat* wiki);