Exemple #1
0
/**
   \brief Apply local context simplification at (OR args[0] ... args[num_args-1])
   Basic idea:
   - Replace args[i] by false in the other arguments
   - If args[i] is of the form (not t), then replace t by true in the other arguments.
   To make sure the simplification is efficient we bound the depth.
*/
bool bool_rewriter::local_ctx_simp(unsigned num_args, expr * const * args, expr_ref & result) {
    expr_ref_vector old_args(m());
    expr_ref_vector new_args(m());
    expr_ref        new_arg(m());
    expr_fast_mark1 neg_lits;
    expr_fast_mark2 pos_lits;
    bool simp     = false;
    bool modified = false;
    bool forward  = true;
    unsigned rounds = 0;

    while (true) {
        rounds++;
#if 0
        if (rounds > 10)
            verbose_stream() << "rounds: " << rounds << "\n";
#endif

#define PUSH_NEW_ARG(ARG) {                     \
    new_args.push_back(ARG);                    \
    if (m().is_not(ARG))                        \
        neg_lits.mark(to_app(ARG)->get_arg(0)); \
    else                                        \
        pos_lits.mark(ARG);                     \
}

#define PROCESS_ARG()                                                                           \
        {                                                                                       \
            expr * arg = args[i];                                                               \
            if (m().is_not(arg) && m().is_or(to_app(arg)->get_arg(0)) &&                        \
                simp_nested_not_or(to_app(to_app(arg)->get_arg(0))->get_num_args(),             \
                                   to_app(to_app(arg)->get_arg(0))->get_args(),                 \
                                   neg_lits,                                                    \
                                   pos_lits,                                                    \
                                   new_arg)) {                                                  \
                modified = true; simp = true;                                                   \
                arg = new_arg;                                                                  \
            }                                                                                   \
            if (simp_nested_eq_ite(arg, neg_lits, pos_lits, new_arg)) {                         \
                modified = true; simp = true;                                                   \
                 arg = new_arg;                                                                 \
            }                                                                                   \
            if (m().is_false(arg))                                                              \
                continue;                                                                       \
            if (m().is_true(arg)) {                                                             \
                result = arg;                                                                   \
                return true;                                                                    \
            }                                                                                   \
            if (m_flat && m().is_or(arg)) {                                                     \
                unsigned sz = to_app(arg)->get_num_args();                                      \
                for (unsigned j = 0; j < sz; j++) {                                             \
                    expr * arg_arg = to_app(arg)->get_arg(j);                                   \
                    PUSH_NEW_ARG(arg_arg);                                                      \
                }                                                                               \
            }                                                                                   \
            else {                                                                              \
                PUSH_NEW_ARG(arg);                                                              \
            }                                                                                   \
        }

        m_local_ctx_cost += 2*num_args;
#if 0
        static unsigned counter = 0;
        counter++;
        if (counter % 10000 == 0)
            verbose_stream() << "local-ctx-cost: " << m_local_ctx_cost << "\n";
#endif

        if (forward) {
            for (unsigned i = 0; i < num_args; i++) {
                PROCESS_ARG();
            }
            forward = false;
        }
        else {
            unsigned i = num_args;
            while (i > 0) {
                --i;
                PROCESS_ARG();
            }
            if (!modified) {
                if (simp) {
                    result = mk_or_app(num_args, args);
                    return true;
                }
                return false; // didn't simplify
            }
            // preserve the original order...
            std::reverse(new_args.c_ptr(), new_args.c_ptr() + new_args.size());
            modified = false;
            forward  = true;
        }
        pos_lits.reset();
        neg_lits.reset();
        old_args.reset();
        old_args.swap(new_args);
        SASSERT(new_args.empty());
        args     = old_args.c_ptr();
        num_args = old_args.size();
    }
}
Exemple #2
0
int build_args(const char *str, int *argc, char ***argv)
{
    bool quote, backslash, endword;
    const char *p;
    bool empty;

    quote = false;
    empty = true;
    backslash = false;
    endword = true;
    *argc = 0;
    *argv = NULL;

    for (p = str; *p != '\0'; ++p) {
        if (*p == '\\') {
            if (backslash) {
                if (endword) {
                    new_arg(argc, argv);
                    endword = false;
                }
                append_str('\\', &(*argv)[*argc - 1]);
                empty = false;
                backslash = false;
            } else {
                backslash = true;
            }
        } else if (*p == '\"') {
            if (backslash) {
                if (endword) {
                    new_arg(argc, argv);
                    endword = false;
                }
                append_str('\"', &(*argv)[*argc - 1]);
                empty = false;
                backslash = false;
            } else {
                endword = true;

                if (quote) {
                    if (empty) {
                        new_arg(argc, argv);
                        append_str('\0', &(*argv)[*argc - 1]);
                    }

                    quote = false;
                } else {
                    quote = true;
                    empty = true;
                }
            }
        } else if (isspace(*p)) {
            if (backslash) {
                if (endword) {
                    new_arg(argc, argv);
                    endword = false;
                }

                append_str(*p, &(*argv)[*argc - 1]);
                empty = false;
                backslash = false;
            } else {
                if (quote) {
                    if (endword) {
                        new_arg(argc, argv);
                        endword = false;
                    }
                    append_str(*p, &(*argv)[*argc - 1]);
                    empty = false;
                } else {
                    endword = true;
                }
            }
        } else {
            if (endword) {
                new_arg(argc, argv);
                endword = false;
            }
            append_str(*p, &(*argv)[*argc - 1]);
            empty = false;
        }
    }

    return 0;
}
Exemple #3
0
/*
 * This function will try to populate an argumentbox.
 * This is slightly difficult due to the numerous different possible
 * input types, ie. v4addr, dotted quad netmask, /netmask, hex netmask,
 * v6addr, interface name etc.
 * This forces to have to try to guess what a user means in some cases.
 * This method can be fairly unforgiving with typos.
 */
struct argbox *get_boxargs(int argc, char *argv[], int argcount, struct argbox *abox_cur)
{
	char expaddr[ARGLEN];
	int x, y;

	/*
	 * We use goto's here *gasp*.
	 */
	while (argv[argcount]) {
		/*
		 * Baaad argument. Error out if this happens.
		 */
		if (strlen(argv[argcount]) > sizeof(expaddr) - 1)
			errx(1, "Invalid argument %s", expaddr);

		strlcpy(expaddr, argv[argcount], sizeof(expaddr));

		/*
		 * Is this a v6 address?
		 */
		x = validate_v6addr(expaddr);
		if (x) {
			strlcpy(abox_cur->str, expaddr, sizeof(abox_cur->str));
			abox_cur->type = AT_V6;
			abox_cur->resolv = 0;
			abox_cur = new_arg(abox_cur);
			goto complete;
		}

		/*
		 * Nope, is it an ipv4 address with a /xx mask?
		 *
		 * NOTE: validate_netmask returns different values if it finds
		 * other types of netmasks to, but we only match on the above
		 * here.
		 */
		x = validate_netmask(expaddr);
		if (x == 2) {
			strlcpy(abox_cur->str, expaddr, sizeof(abox_cur->str));
			abox_cur->type = AT_V4;
			abox_cur->resolv = 0;
			abox_cur = new_arg(abox_cur);
			goto complete;
		}

		/*
		 * No, so is it a plain ipv4 address?
		 */
		x = validate_v4addr(expaddr);
		if (x) {
			y = 0;
			/*
			 * It is, does that mean the next argument is a
			 * netmask?
			 */
			if (argcount + 1 < argc)
				y = validate_netmask(argv[argcount + 1]);
			/*
			 * 1 == 'normal' netmask
			 * 3 == hex netmask
			 */
			if (y == 1 || y == 3) {
				snprintf(abox_cur->str, 34, "%s %s", expaddr, argv[argcount + 1]);
				argcount++;
			} else
				snprintf(abox_cur->str, 18, "%s", expaddr);
			abox_cur->type = AT_V4;
			abox_cur->resolv = 0;
			abox_cur = new_arg(abox_cur);
			goto complete;
		}

		y = 0;
		if (argcount + 1 < argc)
			y = validate_netmask(argv[argcount + 1]);
		if (y == 1 || y == 3) {
			snprintf(abox_cur->str, sizeof(abox_cur->str), "%s %s", expaddr, argv[argcount + 1]);
			argcount++;
		} else
			strlcpy(abox_cur->str, expaddr, sizeof(abox_cur->str));
		abox_cur->type = AT_UNKWN;
		abox_cur->resolv = 1;
		abox_cur = new_arg(abox_cur);

 complete:
		argcount++;
	}

	return abox_cur;
}