static int collect_children(struct pstree_item *item) { pid_t *ch; int ret, i, nr_children, nr_inprogress; ret = parse_children(item->pid.real, &ch, &nr_children); if (ret < 0) return ret; nr_inprogress = 0; for (i = 0; i < nr_children; i++) { struct pstree_item *c; pid_t pid = ch[i]; /* Is it already frozen? */ if (child_collected(item, pid)) continue; nr_inprogress++; pr_info("Seized task %d, state %d\n", pid, ret); c = alloc_pstree_item(); if (c == NULL) { ret = -1; goto free; } if (!opts.freeze_cgroup) /* fails when meets a zombie */ seize_catch_task(pid); ret = seize_wait_task(pid, item->pid.real, &dmpi(c)->pi_creds); if (ret < 0) { /* * Here is a race window between parse_children() and seize(), * so the task could die for these time. * Don't worry, will try again on the next attempt. The number * of attempts is restricted, so it will exit if something * really wrong. */ ret = 0; xfree(c); continue; } c->pid.real = pid; c->parent = item; c->state = ret; list_add_tail(&c->sibling, &item->children); /* Here is a recursive call (Depth-first search) */ ret = collect_task(c); if (ret < 0) goto free; } free: xfree(ch); return ret < 0 ? ret : nr_inprogress; }
struct cParseNode* parse_rule(unsigned int rule, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) { struct cParseNode* node = _new_parsenode(rule); struct cParseNode* tmp; int i; LOG("parsing rule #%d %s (token at %d)\n", rule, grammar->rules.rules[rule].name, tokens->at); int at = tokens->at; INDENT(); for (i=0; i < grammar->rules.rules[rule].num; i++) { tokens->at = at; tmp = parse_children(rule, &(grammar->rules.rules[rule].options[i]), grammar, tokens, error); if (tmp != NULL) { LOG("CHild success! %d\n", i); if (tmp != UNINITIALIZED) { node->child = tmp; } DEDENT(); return node; } } LOG("failed rule %d\n", rule); DEDENT(); tokens->at = at; return NULL; }
struct cParseNode* check_special(unsigned int rule, struct RuleSpecial special, struct cParseNode* current, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) { struct cParseNode* tmp; int at, i; LOG("special\n"); INDENT(); if (special.type == STAR) { LOG("star!\n"); while (tokens->at < tokens->num) { at = tokens->at; tmp = parse_children(rule, special.option, grammar, tokens, error); if (tmp == NULL) { tokens->at = at; break; } current = append_nodes(current, tmp); if (at == tokens->at) { break; } } LOG("awesome star\n"); DEDENT(); return current; } else if (special.type == PLUS) { LOG("plus!\n"); at = tokens->at; tmp = parse_children(rule, special.option, grammar, tokens, error); if (tmp == NULL) { tokens->at = at; LOG("failed plus\n"); DEDENT(); return NULL; } current = append_nodes(current, tmp); if (at == tokens->at) { return current; } while (tokens->at < tokens->num) { at = tokens->at; tmp = parse_children(rule, special.option, grammar, tokens, error); if (tmp == NULL) { tokens->at = at; break; } current = append_nodes(current, tmp); if (at == tokens->at) { break; } } LOG("good plus\n"); DEDENT(); return current; } else if (special.type == OR) { LOG("or!\n"); at = tokens->at; for (i=0;i<special.option->num;i++) { // each of the child items with be of the special STRAIGHT option // type -> allowing the OR special to have a list of lists tmp = parse_children(rule, special.option->items[i].value.special.option, grammar, tokens, error); if (tmp != NULL) { LOG("got or...\n"); current = append_nodes(current, tmp); DEDENT(); return current; } } LOG("fail or\n"); DEDENT(); return NULL; } else if (special.type == QUESTION) { LOG("?maybe\n"); at = tokens->at; tmp = parse_children(rule, special.option, grammar, tokens, error); LOG("done maybe children\n"); if (tmp == NULL) { LOG("not taking it\n"); tokens->at = at; DEDENT(); return current; } current = append_nodes(current, tmp); LOG("got maybe\n"); DEDENT(); return current; } else if (special.type == NOIGNORE) { LOG("no ignore (initial %d)\n", grammar->rules.rules[rule].dont_ignore); int before_ignore = grammar->rules.rules[rule].dont_ignore; at = tokens->at; grammar->rules.rules[rule].dont_ignore = 1; tmp = parse_children(rule, special.option, grammar, tokens, error); grammar->rules.rules[rule].dont_ignore = before_ignore; if (tmp == NULL) { tokens->at = at; LOG("failed ignore\n"); DEDENT(); return NULL; } current = append_nodes(current, tmp); LOG("ignore success! back to %d %d", grammar->rules.rules[rule].dont_ignore, before_ignore); DEDENT(); return current; } else if (special.type == NOT) { LOG("NOT\n"); at = tokens->at; tmp = parse_children(rule, special.option, grammar, tokens, error); if (tmp == NULL) { if (tokens->at < tokens->num) { tmp = _new_parsenode(rule); tmp->token = &tokens->tokens[tokens->at]; tmp->type = NTOKEN; tokens->at += 1; current = append_nodes(current, tmp); LOG("awesome. eating token\n"); } else { LOG("not enough tokens to eat\n"); at = tokens->at; return NULL; } DEDENT(); return current; } LOG("nope, it passed\n"); tokens->at = at; DEDENT(); return NULL; } else { LOG("unknown special type: %s\n", special.type); DEDENT(); return NULL; } LOG("umm shouldnt happen"); DEDENT(); return NULL; }
static pj_json_elem* parse_elem_throw(struct parse_state *st, pj_json_elem *elem) { pj_str_t name = {NULL, 0}, value = {NULL, 0}; pj_str_t token; if (!elem) elem = pj_pool_alloc(st->pool, sizeof(*elem)); /* Parse name */ if (*st->scanner.curptr == '"') { pj_scan_get_char(&st->scanner); pj_scan_get_until_ch(&st->scanner, '"', &token); pj_scan_get_char(&st->scanner); if (*st->scanner.curptr == ':') { pj_scan_get_char(&st->scanner); name = token; } else { value = token; } } if (value.slen) { /* Element with string value and no name */ pj_json_elem_string(elem, &name, &value); return elem; } /* Parse value */ if (pj_cis_match(&st->float_spec, *st->scanner.curptr) || *st->scanner.curptr == '-') { float val; pj_bool_t neg = PJ_FALSE; if (*st->scanner.curptr == '-') { pj_scan_get_char(&st->scanner); neg = PJ_TRUE; } pj_scan_get(&st->scanner, &st->float_spec, &token); val = pj_strtof(&token); if (neg) val = -val; pj_json_elem_number(elem, &name, val); } else if (*st->scanner.curptr == '"') { unsigned err; char *start = st->scanner.curptr; err = parse_quoted_string(st, &token); if (err) { st->scanner.curptr = start + err; return NULL; } pj_json_elem_string(elem, &name, &token); } else if (pj_isalpha(*st->scanner.curptr)) { if (pj_scan_strcmp(&st->scanner, "false", 5)==0) { pj_json_elem_bool(elem, &name, PJ_FALSE); pj_scan_advance_n(&st->scanner, 5, PJ_TRUE); } else if (pj_scan_strcmp(&st->scanner, "true", 4)==0) { pj_json_elem_bool(elem, &name, PJ_TRUE); pj_scan_advance_n(&st->scanner, 4, PJ_TRUE); } else if (pj_scan_strcmp(&st->scanner, "null", 4)==0) { pj_json_elem_null(elem, &name); pj_scan_advance_n(&st->scanner, 4, PJ_TRUE); } else { return NULL; } } else if (*st->scanner.curptr == '[') { pj_json_elem_array(elem, &name); if (parse_children(st, elem) != PJ_SUCCESS) return NULL; } else if (*st->scanner.curptr == '{') { pj_json_elem_obj(elem, &name); if (parse_children(st, elem) != PJ_SUCCESS) return NULL; } else { return NULL; } return elem; }