_c_public_ int c_shquote_unquote(char **outp,
                                 size_t *n_outp,
                                 const char *in,
                                 size_t n_in) {
        size_t n_out = *n_outp;
        char *out = *outp;
        int r;

        while (n_in > 0) {
                size_t len;

                switch (*in) {
                case '\'':
                        r = c_shquote_unquote_single(&out, &n_out, &in, &n_in);
                        if (r)
                                return r;

                        break;
                case '\"':
                        r = c_shquote_unquote_double(&out, &n_out, &in, &n_in);
                        if (r)
                                return r;

                        break;
                case '\\':
                        r = c_shquote_unescape_char_unquoted(&out, &n_out, &in, &n_in);
                        if (r)
                                return r;

                        break;
                default:
                        /*
                         * Consume until the next escape character. If none
                         * exists, consume the rest of the string.
                         */
                        len = c_shquote_strncspn(in, n_in, "\'\"\\");
                        r = c_shquote_consume_str(&out, &n_out, &in, &n_in, len);
                        if (r)
                                return r;
                }
        }

        *outp = out;
        *n_outp = n_out;
        return 0;
}
_c_public_ int c_shquote_unquote(char **outp,
                                 size_t *n_outp,
                                 const char *in,
                                 size_t n_in) {
        size_t n_out = *n_outp;
        char *out = *outp;
        int r;

        while (n_in > 0) {
                size_t len;

                switch (*in) {
                case '\'':
                        r = c_shquote_unquote_single(&out, &n_out, &in, &n_in);
                        if (r)
                                return r;

                        break;
                case '\"':
                        r = c_shquote_unquote_double(&out, &n_out, &in, &n_in);
                        if (r)
                                return r;

                        break;
                case '\\':
                        r = c_shquote_unescape_char_unquoted(&out, &n_out, &in, &n_in);
                        if (r)
                                return r;

                        break;
                default:
                         
                        len = c_shquote_strncspn(in, n_in, "\'\"\\");
                        r = c_shquote_consume_str(&out, &n_out, &in, &n_in, len);
                        if (r)
                                return r;
                }
        }

        *outp = out;
        *n_outp = n_out;
        return 0;
}