return rv;
}
+ static inline struct f_inst *
+ f_generate_path_mask(struct f_path_mask *t)
+ {
+ for (struct f_path_mask *tt = t; tt; tt = tt->next) {
+ if (tt->kind == PM_ASN_EXPR) {
+ struct f_inst *mrv = f_new_inst(FI_PATHMASK_CONSTRUCT);
+ mrv->a1.p = t;
+ return mrv;
+ }
+ }
+
+ NEW_F_VAL;
+ val->type = T_PATH_MASK;
+ val->val.path_mask = t;
+
+ struct f_inst *rv = f_new_inst(FI_CONSTANT_INDIRECT);
+ rv->a1.p = val;
+
+ return rv;
+ }
+
+/*
+ * Remove all new lines and doubled whitespaces
+ * and convert all tabulators to spaces
+ * and return a copy of string
+ */
+char *
+assert_copy_expr(const char *start, size_t len)
+{
+ /* XXX: Allocates maybe a little more memory than we really finally need */
+ char *str = cfg_alloc(len + 1);
+
+ char *dst = str;
+ const char *src = start - 1;
+ const char *end = start + len;
+ while (++src < end)
+ {
+ if (*src == '\n')
+ continue;
+
+ /* Skip doubled whitespaces */
+ if (src != start)
+ {
+ const char *prev = src - 1;
+ if ((*src == ' ' || *src == '\t') && (*prev == ' ' || *prev == '\t'))
+ continue;
+ }
+
+ if (*src == '\t')
+ *dst = ' ';
+ else
+ *dst = *src;
+
+ dst++;
+ }
+ *dst = '\0';
+
+ return str;
+}
+
+/*
+ * assert_done - create f_instruction of bt_assert
+ * @expr: expression in bt_assert()
+ * @start: pointer to first char of test expression
+ * @end: pointer to the last char of test expression
+ */
+static struct f_inst *
+assert_done(struct f_inst *expr, const char *start, const char *end)
+{
+ struct f_inst *i;
+ i = f_new_inst(FI_ASSERT);
+ i->a1.p = expr;
+
+ if (end >= start)
+ {
+ i->a2.p = assert_copy_expr(start, end - start + 1);
+ }
+ else
+ {
+ /* this is a break of lexer buffer */
+ i->a2.p = "???";
+ }
+
+ return i;
+}
CF_DECLS