VirtualBox

Changeset 2161 in kBuild for trunk


Ignore:
Timestamp:
Dec 29, 2008 10:20:11 PM (16 years ago)
Author:
bird
Message:

kmk: Implemented $(for ) and $(while ) loops (C-style). Fixes #73.

Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/kBuild/doc/QuickReference-kmk.html

    r2155 r2161  
    913913$(value var)
    914914</pre>
    915 <p>Evaluate <tt class="docutils literal"><span class="pre">text</span></tt> with <tt class="docutils literal"><span class="pre">var</span></tt> bound to each word in <tt class="docutils literal"><span class="pre">words</span></tt>, and
     915<p>Evaluate <tt class="docutils literal"><span class="pre">body</span></tt> with <tt class="docutils literal"><span class="pre">var</span></tt> bound to each word in <tt class="docutils literal"><span class="pre">words</span></tt>, and
    916916concatenate the results (spaced):</p>
    917917<pre class="literal-block">
    918 $(foreach var,words,text)
     918$(foreach var,words,body)
     919</pre>
     920<p>C-style for-loop. Start by evaluating <tt class="docutils literal"><span class="pre">init</span></tt>. Each iteration will
     921first check whether the <tt class="docutils literal"><span class="pre">condition</span></tt> (<tt class="docutils literal"><span class="pre">kmk</span></tt>-expression) is true,
     922then expand <tt class="docutils literal"><span class="pre">body</span></tt> concatenating the result to the previous iterations
     923(spaced), and finally evaluate <tt class="docutils literal"><span class="pre">next</span></tt>:</p>
     924<pre class="literal-block">
     925$(for init,conditions,next,body)
     926</pre>
     927<p>C-style while-loop. Each iteration will check whether the <tt class="docutils literal"><span class="pre">condition</span></tt>
     928(<tt class="docutils literal"><span class="pre">kmk</span></tt>-expression) is true, then expand <tt class="docutils literal"><span class="pre">body</span></tt> concatenating the
     929result to the previous iterations:</p>
     930<pre class="literal-block">
     931$(while conditions,body)
    919932</pre>
    920933<p>Evaluate the variable <tt class="docutils literal"><span class="pre">var</span></tt> replacing any references to <tt class="docutils literal"><span class="pre">$(1)</span></tt>,
  • trunk/kBuild/doc/QuickReference-kmk.txt

    r2155 r2161  
    555555        $(value var)
    556556
    557     Evaluate ``text`` with ``var`` bound to each word in ``words``, and
     557    Evaluate ``body`` with ``var`` bound to each word in ``words``, and
    558558    concatenate the results (spaced)::
    559559
    560         $(foreach var,words,text)
     560        $(foreach var,words,body)
     561
     562    C-style for-loop. Start by evaluating ``init``. Each iteration will
     563    first check whether the ``condition`` (``kmk``-expression) is true,
     564    then expand ``body`` concatenating the result to the previous iterations
     565    (spaced), and finally evaluate ``next``::
     566
     567        $(for init,conditions,next,body)
     568
     569    C-style while-loop. Each iteration will check whether the ``condition``
     570    (``kmk``-expression) is true, then expand ``body`` concatenating the
     571    result to the previous iterations::
     572
     573        $(while conditions,body)
    561574
    562575    Evaluate the variable ``var`` replacing any references to ``$(1)``,
  • trunk/src/kmk/Makefile.am

    r2151 r2161  
    144144        -DCONFIG_WITH_COMMANDS_FUNC \
    145145        -DCONFIG_WITH_STRING_FUNCTIONS \
     146        -DCONFIG_WITH_LOOP_FUNCTIONS \
    146147        -DCONFIG_PRETTY_COMMAND_PRINTING \
    147148        -DCONFIG_WITH_PRINT_STATS_SWITCH \
  • trunk/src/kmk/Makefile.kmk

    r2151 r2161  
    170170        CONFIG_WITH_PRINTF \
    171171        CONFIG_WITH_STRING_FUNCTIONS \
     172        CONFIG_WITH_LOOP_FUNCTIONS \
    172173        CONFIG_PRETTY_COMMAND_PRINTING \
    173174        CONFIG_WITH_PRINT_STATS_SWITCH \
  • trunk/src/kmk/expreval.c

    r2117 r2161  
    20732073 * Evaluates the given if expression.
    20742074 *
    2075  * @returns -1, 0 or 1.
     2075 * @returns -1, 0 or 1. (GNU make conditional check convention, see read.c.)
    20762076 * @retval  -1 if the expression is invalid.
    20772077 * @retval  0 if the expression is true
    20782078 * @retval  1 if the expression is false.
    20792079 *
    2080  * @param   line    The expression. Can modify this as we like.
     2080 * @param   line    The expression.
    20812081 * @param   flocp   The file location, used for errors.
    20822082 */
    2083 int expr_eval_if_conditionals(char *line, const struct floc *flocp)
     2083int expr_eval_if_conditionals(const char *line, const struct floc *flocp)
    20842084{
    20852085    /*
     
    21152115 * @param   expr    The expression.
    21162116 */
    2117 char *expr_eval_to_string(char *o, char *expr)
     2117char *expr_eval_to_string(char *o, const char *expr)
    21182118{
    21192119    /*
  • trunk/src/kmk/function.c

    r2160 r2161  
    10711071}
    10721072
     1073#ifdef CONFIG_WITH_LOOP_FUNCTIONS
     1074
     1075
     1076/* Helper for func_for that evaluates the INIT and NEXT parts. */
     1077static void
     1078helper_eval (char *text, size_t text_len)
     1079{
     1080    unsigned int buf_len;
     1081    char *buf;
     1082
     1083    install_variable_buffer (&buf, &buf_len);
     1084    eval_buffer (text, text + text_len);
     1085    restore_variable_buffer (buf, buf_len);
     1086}
     1087
     1088/*
     1089  $(for init,condition,next,body)
     1090  */
     1091static char *
     1092func_for (char *o, char **argv, const char *funcname UNUSED)
     1093{
     1094  char        *init     = argv[0];
     1095  const char  *cond     = argv[1];
     1096  const char  *next     = argv[2];
     1097  size_t       next_len = strlen (next);
     1098  char        *next_buf = xmalloc (next_len + 1);
     1099  const char  *body     = argv[3];
     1100  size_t       body_len = strlen (body);
     1101  unsigned int doneany  = 0;
     1102
     1103  push_new_variable_scope ();
     1104
     1105  /* Evaluate INIT. */
     1106
     1107  helper_eval (init, strlen (init));
     1108
     1109  /* Loop till COND is false. */
     1110
     1111  while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
     1112    {
     1113      /* Expand BODY. */
     1114
     1115      if (!doneany)
     1116        doneany = 1;
     1117      else
     1118        o = variable_buffer_output (o, " ", 1);
     1119      variable_expand_string_2 (o, body, body_len, &o);
     1120
     1121      /* Evaluate NEXT. */
     1122
     1123      memcpy (next_buf, next, next_len + 1);
     1124      helper_eval (next_buf, next_len);
     1125    }
     1126
     1127  pop_variable_scope ();
     1128  free (next_buf);
     1129
     1130  return o;
     1131}
     1132
     1133/*
     1134  $(while condition,body)
     1135 */
     1136static char *
     1137func_while (char *o, char **argv, const char *funcname UNUSED)
     1138{
     1139  const char  *cond     = argv[0];
     1140  const char  *body     = argv[1];
     1141  size_t       body_len = strlen (body);
     1142  unsigned int doneany  = 0;
     1143
     1144  push_new_variable_scope ();
     1145
     1146  while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
     1147    {
     1148      if (!doneany)
     1149        doneany = 1;
     1150      else
     1151        o = variable_buffer_output (o, " ", 1);
     1152      variable_expand_string_2 (o, body, body_len, &o);
     1153    }
     1154
     1155  pop_variable_scope ();
     1156
     1157  return o;
     1158}
     1159
     1160
     1161#endif /* CONFIG_WITH_LOOP_FUNCTIONS */
     1162
    10731163struct a_word
    10741164{
     
    48664956  { STRING_SIZE_TUPLE("origin"),        0,  1,  1,  func_origin},
    48674957  { STRING_SIZE_TUPLE("foreach"),       3,  3,  0,  func_foreach},
     4958#ifdef CONFIG_WITH_LOOP_FUNCTIONS
     4959  { STRING_SIZE_TUPLE("for"),           4,  4,  0,  func_for},
     4960  { STRING_SIZE_TUPLE("while"),         2,  2,  0,  func_while},
     4961#endif
    48684962  { STRING_SIZE_TUPLE("call"),          1,  0,  1,  func_call},
    48694963  { STRING_SIZE_TUPLE("info"),          0,  1,  1,  func_error},
  • trunk/src/kmk/make.h

    r2121 r2161  
    911911
    912912#ifdef CONFIG_WITH_IF_CONDITIONALS
    913 extern int expr_eval_if_conditionals(char *line, const struct floc *flocp);
    914 extern char *expr_eval_to_string(char *o, char *expr);
     913extern int expr_eval_if_conditionals(const char *line, const struct floc *flocp);
     914extern char *expr_eval_to_string(char *o, const char *expr);
    915915#endif
    916916
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette