Example #1
0
END_TEST


#define make_str(x) #x

START_TEST(Reading_invalid_piref_fails)
{
    const char* data[] =
    {
        "0, 0]",
        "[0 0]",
        "[0, 0",
        "[0, -1]",
        "[-1, 0]",
        "[0, " make_str(KQT_PAT_INSTANCES_MAX) "]",
        "[" make_str(KQT_PATTERNS_MAX) ", 0]",
    };

    for (size_t i = 0; i < arr_size(data); ++i)
    {
        Streader* sr = init_with_cstr(data[i]);
        Pat_inst_ref* result = PAT_INST_REF_AUTO;

        fail_if(Streader_read_piref(sr, result),
                "Streader accepted `%s` as a valid pattern instance reference",
                data[i]);
    }
}
Example #2
0
/// Initialize the ROOT environment to compile and execute a ROOT AClick
int initAClick(const char* command=0)  {
  std::string rootsys = make_str(gSystem->Getenv("ROOTSYS"));
  std::string geant4  = make_str(gSystem->Getenv("G4INSTALL"));
  std::string dd4hep  = make_str(gSystem->Getenv("DD4hepINSTALL"));
  std::string clhep   = make_str(gSystem->Getenv("CLHEP_DIR"));
  std::string defs    = "";
  std::string libs    = " -L"+rootsys+"/lib";
  std::string inc     = " -I"+dd4hep+"/examples/DDG4/examples -I"+dd4hep + " -I"+dd4hep+"/include";
  libs += " -L"+dd4hep+"/lib -lDDCore -lDDG4 -lDDSegmentation";
  if ( !geant4.empty() )  {
    inc  += " -I"+geant4+"/include/Geant4";
    libs += (" -L"+geant4+"/lib -L"+geant4+"/lib64 -lG4event -lG4tracking -lG4particles");
  }
  if ( !clhep.empty() )  {
    // A bit unclear how to deal with CLHEP libraries here, 
    // if CLHEP is not included in Geant4...
    inc += " -I"+clhep+"/include";
  }
  inc += " -Wno-shadow -g -O0" + defs;
  if ( ROOT_VERSION_CODE < ROOT_VERSION(6,0,0) )
    libs += " -lCint";
  libs += " -lCore -lMathCore -pthread -lm -ldl -rdynamic";
  gSystem->AddIncludePath(inc.c_str());
  gSystem->AddLinkedLibs(libs.c_str());
  std::cout << "+++ Includes:   " << gSystem->GetIncludePath() << std::endl;
  std::cout << "+++ Linked libs:" << gSystem->GetLinkedLibs()  << std::endl;
  int ret = gSystem->Load("libDDG4Plugins");
  if ( 0 == ret )   {
    if ( command )  {
      processCommand(command, true);
    }
  }
  return ret;
}
Example #3
0
// Like make_str, but parses entities.
// Returns an inline sequence consisting of str and entity elements.
static cmark_node *make_str_with_entities(cmark_chunk *content)
{
	cmark_strbuf unescaped = GH_BUF_INIT;

	if (houdini_unescape_html(&unescaped, content->data, (size_t)content->len)) {
		return make_str(cmark_chunk_buf_detach(&unescaped));
	} else {
		return make_str(*content);
	}
}
Example #4
0
// Like make_str, but parses entities.
static cmark_node *make_str_with_entities(cmark_mem *mem,
                                          cmark_chunk *content) {
  cmark_strbuf unescaped = CMARK_BUF_INIT(mem);

  if (houdini_unescape_html(&unescaped, content->data, content->len)) {
    return make_str(mem, cmark_chunk_buf_detach(&unescaped));
  } else {
    return make_str(mem, *content);
  }
}
Example #5
0
/* Parse and evaluate match (regex) expressions */
struct val *
eval5(void)
{
	regex_t		rp;
	regmatch_t	rm[2];
	char		errbuf[256];
	int		eval;
	struct val     *l, *r;
	struct val     *v;

	l = eval6();
	while (token == MATCH) {
		nexttoken(1);
		r = eval6();

		/* coerce to both arguments to strings */
		to_string(l);
		to_string(r);

		/* compile regular expression */
		if ((eval = regcomp(&rp, r->u.s, 0)) != 0) {
			regerror(eval, &rp, errbuf, sizeof(errbuf));
			errx(2, "%s", errbuf);
		}

		/* compare string against pattern --  remember that patterns
		   are anchored to the beginning of the line */
		if (regexec(&rp, l->u.s, 2, rm, 0) == 0 && rm[0].rm_so == 0) {
			if (rm[1].rm_so >= 0) {
				*(l->u.s + rm[1].rm_eo) = '\0';
				v = make_str(l->u.s + rm[1].rm_so);

			} else {
				v = make_int((int)(rm[0].rm_eo - rm[0].rm_so));
			}
		} else {
			if (rp.re_nsub == 0) {
				v = make_int(0);
			} else {
				v = make_str("");
			}
		}

		/* free arguments and pattern buffer */
		free_value(l);
		free_value(r);
		regfree(&rp);

		l = v;
	}

	return l;
}
Example #6
0
// Parse backslash-escape or just a backslash, returning an inline.
static cmark_node *handle_backslash(subject *subj) {
  advance(subj);
  unsigned char nextchar = peek_char(subj);
  if (cmark_ispunct(
          nextchar)) { // only ascii symbols and newline can be escaped
    advance(subj);
    return make_str(subj->mem, cmark_chunk_dup(&subj->input, subj->pos - 1, 1));
  } else if (!is_eof(subj) && skip_line_end(subj)) {
    return make_linebreak(subj->mem);
  } else {
    return make_str(subj->mem, cmark_chunk_literal("\\"));
  }
}
Example #7
0
// Assumes we have a period at the current position.
static cmark_node *handle_period(subject *subj, bool smart) {
  advance(subj);
  if (smart && peek_char(subj) == '.') {
    advance(subj);
    if (peek_char(subj) == '.') {
      advance(subj);
      return make_str(subj->mem, cmark_chunk_literal(ELLIPSES));
    } else {
      return make_str(subj->mem, cmark_chunk_literal(".."));
    }
  } else {
    return make_str(subj->mem, cmark_chunk_literal("."));
  }
}
Example #8
0
// Parse an entity or a regular "&" string.
// Assumes the subject has an '&' character at the current position.
static cmark_node *handle_entity(subject *subj) {
  cmark_strbuf ent = CMARK_BUF_INIT(subj->mem);
  bufsize_t len;

  advance(subj);

  len = houdini_unescape_ent(&ent, subj->input.data + subj->pos,
                             subj->input.len - subj->pos);

  if (len == 0)
    return make_str(subj->mem, cmark_chunk_literal("&"));

  subj->pos += len;
  return make_str(subj->mem, cmark_chunk_buf_detach(&ent));
}
Example #9
0
// Assumes we have a hyphen at the current position.
static cmark_node* handle_hyphen(subject* subj, bool smart)
{
	advance(subj);
	if (smart && peek_char(subj) == '-') {
		advance(subj);
		if (peek_char(subj) == '-') {
			advance(subj);
			return make_str(cmark_chunk_literal(EMDASH));
		} else {
			return make_str(cmark_chunk_literal(ENDASH));
		}
	} else {
		return make_str(cmark_chunk_literal("-"));
	}
}
Example #10
0
extern "C" CDECL rust_str *
upcall_dup_str(rust_task *task, rust_task *target, rust_str *str) {
    LOG_UPCALL_ENTRY(task);
    scoped_lock with(task->kernel->scheduler_lock);

    return make_str(target, (char const *)str->data, str->fill);
}
Example #11
0
extern "C" CDECL rust_str *
upcall_new_str(rust_task *task, char const *s, size_t fill) {
    LOG_UPCALL_ENTRY(task);
    scoped_lock with(task->kernel->scheduler_lock);
    
    return make_str(task, s, fill);
}
Example #12
0
int				ft_readline(int fd, char **line)
{
	int				line_end;
	int				can_read;
	t_fd			*fdatas;
	static t_fd		*flst;

	if (!(fdatas = get_fdatas(&flst, fd)))
		return (-1);
	if (fdatas->start == -1)
	{
		free(fdatas->lst);
		fdatas->lst = NULL;
		fdatas->start = 0;
		return (0);
	}
	line_end = get_line_end(fdatas, &can_read);
	*line = make_str(fdatas, line_end);
	if (line_end < FILE_BUFF_SIZE && can_read == 0)
		fdatas->start = -1;
	if (line_end == FILE_BUFF_SIZE && can_read == 0)
		return (0);
	if (can_read == -1 || line == NULL)
		return (-1);
	return (1);
}
Example #13
0
int				get_next_line(int const fd, char **line)
{
	int				line_end;
	int				can_read;
	t_fd			*fdatas;
	static t_fd		*flst;

	fdatas = get_fdatas(&flst, fd);
	if (fdatas == NULL)
		return (-1);
	if (fdatas->start == -1)
	{
		free(fdatas->lst);
		fdatas->lst = NULL;
		fdatas->start = 0;
		return (0);
	}
	line_end = get_line_end(fdatas, &can_read);
	*line = make_str(fdatas, line_end);
	if (can_read == 0)
		fdatas->start = -1;
	if (can_read == -1)
		return (-1);
	if (line == NULL)
		return (-1);
	return (1);
}
Example #14
0
char	*cpy_from_env(char **tab, char *str)
{
  char	*found;
  int	i;
  int	j;

  j = 0;
  i = 0;
  while (tab[j] != NULL && str[i] != '\0')
    {
      while (tab[j][i] != str[i] && str[i] != '\0' && tab[j][i] != '\0')
        {
          i = 0;
          j++;
          if (tab[j] == NULL)
            return (NULL);
        }
      if (tab[j][i] == str[i])
        i++;
    }
  if (i == 0)
    return (NULL);
  found = make_str(found, tab[j]);
  return (found);
}
Example #15
0
// Parse an autolink or HTML tag.
// Assumes the subject has a '<' character at the current position.
static cmark_node *handle_pointy_brace(subject *subj) {
  bufsize_t matchlen = 0;
  cmark_chunk contents;

  advance(subj); // advance past first <

  // first try to match a URL autolink
  matchlen = scan_autolink_uri(&subj->input, subj->pos);
  if (matchlen > 0) {
    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
    subj->pos += matchlen;

    return make_autolink(subj->mem, contents, 0);
  }

  // next try to match an email autolink
  matchlen = scan_autolink_email(&subj->input, subj->pos);
  if (matchlen > 0) {
    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
    subj->pos += matchlen;

    return make_autolink(subj->mem, contents, 1);
  }

  // finally, try to match an html tag
  matchlen = scan_html_tag(&subj->input, subj->pos);
  if (matchlen > 0) {
    contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
    subj->pos += matchlen;
    return make_raw_html(subj->mem, contents);
  }

  // if nothing matches, just return the opening <:
  return make_str(subj->mem, cmark_chunk_literal("<"));
}
Example #16
0
// Assumes the subject has a c at the current position.
static cmark_node* handle_delim(subject* subj, unsigned char c, bool smart)
{
	int numdelims;
	cmark_node * inl_text;
	bool can_open, can_close;
	cmark_chunk contents;

	numdelims = scan_delims(subj, c, &can_open, &can_close);

	if (c == '\'' && smart) {
		contents = cmark_chunk_literal(RIGHTSINGLEQUOTE);
	} else if (c == '"' && smart) {
		contents = cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);
	} else {
		contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);
	}

	inl_text = make_str(contents);

	if ((can_open || can_close) &&
	    (!(c == '\'' || c == '"') || smart)) {
		push_delimiter(subj, c, can_open, can_close, inl_text);
	}

	return inl_text;
}
Example #17
0
extern "C" CDECL void
upcall_s_str_new_uniq(s_str_new_uniq_args *args) {
    rust_task *task = args->task;
    LOG_UPCALL_ENTRY(task);
    args->retval = make_str(task->kernel, args->cstr, args->len,
                            "str_new_uniq");
}
Example #18
0
// Assumes we have a hyphen at the current position.
static cmark_node *handle_hyphen(subject *subj, bool smart) {
  cmark_strbuf buf = CMARK_BUF_INIT(NULL);
  int startpos = subj->pos;
  int en_count = 0;
  int em_count = 0;
  int numhyphens;
  int i;

  advance(subj);

  if (!smart || peek_char(subj) != '-') {
    return make_str(subj->mem, cmark_chunk_literal("-"));
  }

  while (smart && peek_char(subj) == '-') {
    advance(subj);
  }

  numhyphens = subj->pos - startpos;
  buf.mem = subj->mem;

  if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes
    em_count = numhyphens / 3;
  } else if (numhyphens % 2 == 0) { // if divisible by 2, use all en dashes
    en_count = numhyphens / 2;
  } else if (numhyphens % 3 == 2) { // use one en dash at end
    en_count = 1;
    em_count = (numhyphens - 2) / 3;
  } else { // use two en dashes at the end
    en_count = 2;
    em_count = (numhyphens - 4) / 3;
  }

  for (i = em_count; i > 0; i--) {
    cmark_strbuf_puts(&buf, EMDASH);
  }

  for (i = en_count; i > 0; i--) {
    cmark_strbuf_puts(&buf, ENDASH);
  }

  return make_str(subj->mem, cmark_chunk_buf_detach(&buf));
}
Example #19
0
int main(int argc, char* argv[]) {
  char dest[10];
  char * name;

  name = make_str();
  // assert(strlen(name) < 10);
  __CPROVER_assume(strlen(name) < 10);

  strcpy(dest, name);

  return 0;
}
Example #20
0
extern "C" CDECL rust_vec_box*
rust_list_files(rust_str *path) {
    rust_task *task = rust_get_current_task();
    array_list<rust_str*> strings;
#if defined(__WIN32__)
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile((char*)path->body.data, &FindFileData);
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            rust_str *str = make_str(task->kernel, FindFileData.cFileName,
                                     strlen(FindFileData.cFileName),
                                     "list_files_str");
            strings.push(str);
        } while (FindNextFile(hFind, &FindFileData));
        FindClose(hFind);
    }
#else
    DIR *dirp = opendir((char*)path->body.data);
    if (dirp) {
        struct dirent *dp;
        while ((dp = readdir(dirp))) {
            rust_vec_box *str = make_str(task->kernel, dp->d_name,
                                         strlen(dp->d_name),
                                         "list_files_str");
            strings.push(str);
        }
        closedir(dirp);
    }
#endif

    rust_vec_box *vec = (rust_vec_box *)
                        task->kernel->malloc(vec_size<rust_vec_box*>(strings.size()),
                                "list_files_vec");
    size_t alloc_sz = sizeof(rust_vec*) * strings.size();
    vec->body.fill = vec->body.alloc = alloc_sz;
    memcpy(&vec->body.data[0], strings.data(), alloc_sz);
    return vec;
}
Example #21
0
LLVMValueRef gen_const(struct node *ast)
{
	switch (ast->val[0]) {
	case '\'':
		return make_char(ast->val);
	case '"':
		return make_str(ast->val);
	case '0':
		/* TODO: Support 09 and 08: see section 4.1.4 */
		return LLVMConstIntOfString(TYPE_INT, ast->val, 8);
	default:
		return LLVMConstIntOfString(TYPE_INT, ast->val, 10);
	}
}
Example #22
0
extern "C" rust_str *
shape_log_str(const type_desc *tydesc, uint8_t *data) {
    rust_task *task = rust_get_current_task();

    shape::arena arena;

    std::stringstream ss;
    shape::log log(task, true, tydesc->shape, tydesc->shape_tables,
                   data, ss);

    log.walk();

    int len = ss.str().length();
    return make_str(task->kernel, ss.str().c_str(), len, "log_str");
}
Example #23
0
// Parse strong/emph or a fallback.
// Assumes the subject has '_' or '*' at the current position.
static cmark_node* handle_strong_emph(subject* subj, unsigned char c)
{
	int numdelims;
	cmark_node * inl_text;
	bool can_open, can_close;

	numdelims = scan_delims(subj, c, &can_open, &can_close);

	inl_text = make_str(cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims));

	if (can_open || can_close) {
		push_delimiter(subj, c, can_open, can_close, inl_text);
	}

	return inl_text;
}
Example #24
0
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
static cmark_node* handle_backticks(subject *subj)
{
	cmark_chunk openticks = take_while(subj, isbacktick);
	int startpos = subj->pos;
	int endpos = scan_to_closing_backticks(subj, openticks.len);

	if (endpos == 0) { // not found
		subj->pos = startpos; // rewind
		return make_str(openticks);
	} else {
		cmark_strbuf buf = GH_BUF_INIT;

		cmark_strbuf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);
		cmark_strbuf_trim(&buf);
		cmark_strbuf_normalize_whitespace(&buf);

		return make_code(cmark_chunk_buf_detach(&buf));
	}
}
Example #25
0
extern "C" CDECL rust_str*
last_os_error() {
    rust_task *task = rust_get_current_task();

    LOG(task, task, "last_os_error()");

#if defined(__WIN32__)
    LPTSTR buf;
    DWORD err = GetLastError();
    DWORD res = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                              FORMAT_MESSAGE_FROM_SYSTEM |
                              FORMAT_MESSAGE_IGNORE_INSERTS,
                              NULL, err,
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                              (LPTSTR) &buf, 0, NULL);
    if (!res) {
        task->fail();
        return NULL;
    }
#elif defined(_GNU_SOURCE)
    char cbuf[BUF_BYTES];
    char *buf = strerror_r(errno, cbuf, sizeof(cbuf));
    if (!buf) {
        task->fail();
        return NULL;
    }
#else
    char buf[BUF_BYTES];
    int err = strerror_r(errno, buf, sizeof(buf));
    if (err) {
        task->fail();
        return NULL;
    }
#endif

    rust_str * st = make_str(task->kernel, buf, strlen(buf),
                             "last_os_error");
#ifdef __WIN32__
    LocalFree((HLOCAL)buf);
#endif
    return st;
}
Example #26
0
void
nexttoken(int pat)
{
	char	       *p;

	if ((p = *av) == NULL) {
		token = EOI;
		return;
	}
	av++;

	
	if (pat == 0 && p[0] != '\0') {
		if (p[1] == '\0') {
			const char     *x = "|&=<>+-*/%:()";
			char	       *i;	/* index */

			if ((i = strchr(x, *p)) != NULL) {
				token = i - x;
				return;
			}
		} else if (p[1] == '=' && p[2] == '\0') {
			switch (*p) {
			case '<':
				token = LE;
				return;
			case '>':
				token = GE;
				return;
			case '!':
				token = NE;
				return;
			}
		}
	}
	tokval = make_str(p);
	token = OPERAND;
	return;
}
Example #27
0
    command_line_args(rust_task *task,
                      int sys_argc,
                      char **sys_argv)
        : kernel(task->kernel),
          task(task),
          argc(sys_argc),
          argv(sys_argv)
    {
#if defined(__WIN32__)
        LPCWSTR cmdline = GetCommandLineW();
        LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
        kernel->win32_require("CommandLineToArgvW", wargv != NULL);
        argv = (char **) kernel->malloc(sizeof(char*) * argc,
                                        "win32 command line");
        for (int i = 0; i < argc; ++i) {
            int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
                                              NULL, 0, NULL, NULL);
            kernel->win32_require("WideCharToMultiByte(0)", n_chars != 0);
            argv[i] = (char *) kernel->malloc(n_chars,
                                              "win32 command line arg");
            n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
                                          argv[i], n_chars, NULL, NULL);
            kernel->win32_require("WideCharToMultiByte(1)", n_chars != 0);
        }
        LocalFree(wargv);
#endif

        args = (rust_vec *)
            kernel->malloc(vec_size<rust_vec*>(argc),
                           "command line arg interior");
        args->fill = args->alloc = sizeof(rust_vec*) * argc;
        for (int i = 0; i < argc; ++i) {
            rust_str *str = make_str(kernel, argv[i],
                                     strlen(argv[i]),
                                     "command line arg");
            ((rust_str**)&args->data)[i] = str;
        }
    }
Example #28
0
extern "C" CDECL rust_str *
rust_getcwd() {
    rust_task *task = rust_scheduler::get_task();
    LOG(task, task, "rust_getcwd()");

    char cbuf[BUF_BYTES];

#if defined(__WIN32__)
    if (!_getcwd(cbuf, sizeof(cbuf))) {
#else
    if (!getcwd(cbuf, sizeof(cbuf))) {
#endif
        task->fail();
        return NULL;
    }

    return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd");
}

// TODO: Allow calling native functions that return double results.
extern "C" CDECL
void squareroot(double *input, double *output) {
    *output = sqrt(*input);
}
Example #29
0
extern "C" CDECL rust_str *
rust_getcwd() {
    rust_task *task = rust_get_current_task();
    LOG(task, task, "rust_getcwd()");

    char cbuf[BUF_BYTES];

#if defined(__WIN32__)
    if (!_getcwd(cbuf, sizeof(cbuf))) {
#else
        if (!getcwd(cbuf, sizeof(cbuf))) {
#endif
        task->fail();
        return NULL;
    }

    return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd)");
}

#if defined(__WIN32__)
extern "C" CDECL rust_vec_box *
rust_env_pairs() {
    rust_task *task = rust_get_current_task();
    size_t envc = 0;
    LPTCH ch = GetEnvironmentStringsA();
    LPTCH c;
    for (c = ch; *c; c += strlen(c) + 1) {
        ++envc;
    }
    c = ch;
    rust_vec_box *v = (rust_vec_box *)
        task->kernel->malloc(vec_size<rust_vec_box*>(envc),
                       "str vec interior");
    v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc;
    for (size_t i = 0; i < envc; ++i) {
        size_t n = strlen(c);
        rust_str *str = make_str(task->kernel, c, n, "str");
        ((rust_str**)&v->body.data)[i] = str;
        c += n + 1;
    }
    if (ch) {
        FreeEnvironmentStrings(ch);
    }
    return v;
}
#else
extern "C" CDECL rust_vec_box *
rust_env_pairs() {
    rust_task *task = rust_get_current_task();
#ifdef __APPLE__
    char **environ = *_NSGetEnviron();
#endif
    char **e = environ;
    size_t envc = 0;
    while (*e) {
        ++envc; ++e;
    }
    return make_str_vec(task->kernel, envc, environ);
}
#endif

extern "C" CDECL void
unsupervise() {
    rust_task *task = rust_get_current_task();
    task->unsupervise();
}
Example #30
0
// Parse an inline, advancing subject, and add it as a child of parent.
// Return 0 if no inline can be parsed, 1 otherwise.
static int parse_inline(subject* subj, cmark_node * parent, int options)
{
	cmark_node* new_inl = NULL;
	cmark_chunk contents;
	unsigned char c;
	int endpos;
	c = peek_char(subj);
	if (c == 0) {
		return 0;
	}
	switch(c) {
	case '\n':
		new_inl = handle_newline(subj);
		break;
	case '`':
		new_inl = handle_backticks(subj);
		break;
	case '\\':
		new_inl = handle_backslash(subj);
		break;
	case '&':
		new_inl = handle_entity(subj);
		break;
	case '<':
		new_inl = handle_pointy_brace(subj);
		break;
	case '*':
	case '_':
	case '\'':
	case '"':
		new_inl = handle_delim(subj, c, options & CMARK_OPT_SMART);
		break;
	case '-':
		new_inl = handle_hyphen(subj, options & CMARK_OPT_SMART);
		break;
	case '.':
		new_inl = handle_period(subj, options & CMARK_OPT_SMART);
		break;
	case '[':
		advance(subj);
		new_inl = make_str(cmark_chunk_literal("["));
		push_delimiter(subj, '[', true, false, new_inl);
		break;
	case ']':
		new_inl = handle_close_bracket(subj, parent);
		break;
	case '!':
		advance(subj);
		if (peek_char(subj) == '[') {
			advance(subj);
			new_inl = make_str(cmark_chunk_literal("!["));
			push_delimiter(subj, '!', false, true, new_inl);
		} else {
			new_inl = make_str(cmark_chunk_literal("!"));
		}
		break;
	default:
		endpos = subject_find_special_char(subj, options);
		contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);
		subj->pos = endpos;

		// if we're at a newline, strip trailing spaces.
		if (peek_char(subj) == '\n') {
			cmark_chunk_rtrim(&contents);
		}

		new_inl = make_str(contents);
	}
	if (new_inl != NULL) {
		cmark_node_append_child(parent, new_inl);
	}

	return 1;
}