]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[script] Add do-while loops
authorCharlie Brej <cbrej@cs.man.ac.uk>
Sun, 4 Oct 2009 16:36:22 +0000 (17:36 +0100)
committerroot <cbrej@cs.man.ac.uk>
Sun, 4 Oct 2009 16:36:22 +0000 (17:36 +0100)
Format is:
    do {operations} while (condition);
or
    do operation; while (condition);

Like in C, the semicolon at the end is necessary.

src/plugins/splash/script/script-execute.c
src/plugins/splash/script/script-parse.c
src/plugins/splash/script/script.h

index 0ab15cf49af43903ee8512ee2679a911dbc9b959..161186f1ae110c531470c2da675772dc38c0b388 100644 (file)
@@ -658,18 +658,26 @@ script_return_t script_execute (script_state_t *state,
           break;
         }
 
+      case SCRIPT_OP_TYPE_DO_WHILE:
       case SCRIPT_OP_TYPE_WHILE:
       case SCRIPT_OP_TYPE_FOR:
         {
-          script_obj_t *obj;
+          script_obj_t *obj = NULL;
+          bool cond = false;
+          if (op->type == SCRIPT_OP_TYPE_DO_WHILE) cond = true;
           while (1)
             {
-              obj = script_evaluate (state, op->data.cond_op.cond);
-              if (script_obj_as_bool (obj))
+              if (!cond)
+                {
+                  obj = script_evaluate (state, op->data.cond_op.cond);
+                  cond = script_obj_as_bool (obj);
+                  script_obj_unref (obj);
+                }
+               
+              if (cond)
                 {
                   script_obj_unref (reply.object);
                   reply = script_execute (state, op->data.cond_op.op1);
-                  script_obj_unref (obj);
                   switch (reply.type)
                     {
                       case SCRIPT_RETURN_TYPE_NORMAL:
@@ -693,9 +701,9 @@ script_return_t script_execute (script_state_t *state,
                 }
               else
                 {
-                  script_obj_unref (obj);
                   break;
                 }
+              cond = false;
             }
           break;
         }
index 8e9a355976c0ec4d06437463a863aef3b2415be2..1e02ac5df302a77d7f6f120dcdb2401b4ad81af4 100644 (file)
@@ -592,6 +592,57 @@ static script_op_t *script_parse_if_while (script_scan_t *scan)
   return op;
 }
 
+static script_op_t *script_parse_do_while (script_scan_t *scan)
+{
+  script_scan_token_t *curtoken = script_scan_get_current_token (scan);
+
+  if (!script_scan_token_is_identifier_of_value (curtoken, "do"))
+    return NULL;
+  script_debug_location_t location = curtoken->location;
+  curtoken = script_scan_get_next_token (scan);
+  script_op_t *cond_op = script_parse_op (scan);
+  curtoken = script_scan_get_current_token (scan);
+
+  if (!script_scan_token_is_identifier_of_value (curtoken, "while"))
+    {
+      script_parse_error (&curtoken->location,
+                          "Expected a 'while' after a 'do' block");
+      return NULL;
+    }
+  curtoken = script_scan_get_next_token (scan);
+
+  if (!script_scan_token_is_symbol_of_value (curtoken, '('))
+    {
+      script_parse_error (&curtoken->location,
+                          "Expected a '(' at the start of a do-while condition block");
+      return NULL;
+    }
+  curtoken = script_scan_get_next_token (scan);
+  script_exp_t *cond = script_parse_exp (scan);
+  curtoken = script_scan_get_current_token (scan);
+  if (!cond)
+    {
+      script_parse_error (&curtoken->location, "Expected a valid condition expression");
+      return NULL;
+    }
+  if (!script_scan_token_is_symbol_of_value (curtoken, ')'))
+    {
+      script_parse_error (&curtoken->location,
+                          "Expected a ')' at the end of a condition block");
+      return NULL;
+    }
+  curtoken = script_scan_get_next_token (scan);
+  if (!script_scan_token_is_symbol_of_value (curtoken, ';'))
+    {
+      script_parse_error (&curtoken->location,
+                          "Expected a ';' after a do-whileexpression");
+      return NULL;
+    }
+  script_scan_get_next_token (scan);
+  script_op_t *op = script_parse_new_op_cond (SCRIPT_OP_TYPE_DO_WHILE, cond, cond_op, NULL, &location);
+  return op;
+}
+
 static script_op_t *script_parse_for (script_scan_t *scan)
 {
   script_scan_token_t *curtoken = script_scan_get_current_token (scan);
@@ -734,6 +785,8 @@ static script_op_t *script_parse_op (script_scan_t *scan)
   if (reply) return reply;
   reply = script_parse_if_while (scan);
   if (reply) return reply;
+  reply = script_parse_do_while (scan);
+  if (reply) return reply;
   reply = script_parse_for (scan);
   if (reply) return reply;
   reply = script_parse_return (scan);
@@ -880,6 +933,7 @@ void script_parse_op_free (script_op_t *op)
 
       case SCRIPT_OP_TYPE_IF:
       case SCRIPT_OP_TYPE_WHILE:
+      case SCRIPT_OP_TYPE_DO_WHILE:
       case SCRIPT_OP_TYPE_FOR:
         script_parse_exp_free (op->data.cond_op.cond);
         script_parse_op_free  (op->data.cond_op.op1);
index 45254bd6ef83b875d61594374c634e25a84b8bf3..e4f6958ba1dfcbec444b57bb55257750e0175798 100644 (file)
@@ -191,6 +191,7 @@ typedef enum
   SCRIPT_OP_TYPE_OP_BLOCK,
   SCRIPT_OP_TYPE_IF,
   SCRIPT_OP_TYPE_WHILE,
+  SCRIPT_OP_TYPE_DO_WHILE,
   SCRIPT_OP_TYPE_FOR,
   SCRIPT_OP_TYPE_RETURN,
   SCRIPT_OP_TYPE_FAIL,