jv jv_parser_next(struct jv_parser* p) { assert(p->curr_buf && "a buffer must be provided"); if (p->bom_strip_position == 0xff) return jv_invalid_with_msg(jv_string("Malformed BOM")); jv value; presult msg = 0; while (!msg && p->curr_buf_pos < p->curr_buf_length) { char ch = p->curr_buf[p->curr_buf_pos++]; msg = scan(p, ch, &value); } if (msg == OK) { return value; } else if (msg) { return jv_invalid_with_msg(jv_string_fmt("%s at line %d, column %d", msg, p->line, p->column)); } else if (p->curr_buf_is_partial) { assert(p->curr_buf_pos == p->curr_buf_length); // need another buffer return jv_invalid(); } else { assert(p->curr_buf_pos == p->curr_buf_length); // at EOF if (p->st != JV_PARSER_NORMAL) return jv_invalid_with_msg(jv_string("Unfinished string")); if ((msg = check_literal(p))) return jv_invalid_with_msg(jv_string(msg)); if (p->stackpos != 0) return jv_invalid_with_msg(jv_string("Unfinished JSON term")); // p->next is either invalid (nothing here but no syntax error) // or valid (this is the value). either way it's the thing to return value = p->next; p->next = jv_invalid(); return value; } }
static pfunc scan(struct jv_parser* p, char ch, jv* out) { p->column++; if (ch == '\n') { p->line++; p->column = 0; } presult answer = 0; if (p->st == JV_PARSER_NORMAL) { chclass cls = classify(ch); if (cls != LITERAL) { TRY(check_literal(p)); if (check_done(p, out)) answer = OK; } switch (cls) { case LITERAL: tokenadd(p, ch); break; case WHITESPACE: break; case QUOTE: p->st = JV_PARSER_STRING; break; case STRUCTURE: TRY(token(p, ch)); break; case INVALID: return "Invalid character"; } if (check_done(p, out)) answer = OK; } else { if (ch == '"' && p->st == JV_PARSER_STRING) { TRY(found_string(p)); p->st = JV_PARSER_NORMAL; if (check_done(p, out)) answer = OK; } else { tokenadd(p, ch); if (ch == '\\' && p->st == JV_PARSER_STRING) { p->st = JV_PARSER_STRING_ESCAPE; } else { p->st = JV_PARSER_STRING; } } } return answer; }
/** Search for packages to upgrade and add them to the transaction. */ int SYMEXPORT alpm_sync_sysupgrade(alpm_handle_t *handle, int enable_downgrade) { alpm_list_t *i, *j; alpm_trans_t *trans; CHECK_HANDLE(handle, return -1); trans = handle->trans; ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1)); _alpm_log(handle, ALPM_LOG_DEBUG, "checking for package upgrades\n"); for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) { alpm_pkg_t *lpkg = i->data; if(alpm_pkg_find(trans->add, lpkg->name)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name); continue; } /* Search for literal then replacers in each sync database. */ for(j = handle->dbs_sync; j; j = j->next) { alpm_db_t *sdb = j->data; /* Check sdb */ alpm_pkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name); int literal_upgrade = 0; if(spkg) { literal_upgrade = check_literal(handle, lpkg, spkg, enable_downgrade); if(literal_upgrade) { trans->add = alpm_list_add(trans->add, spkg); } /* jump to next local package */ break; } else { alpm_list_t *replacers; replacers = check_replacers(handle, lpkg, sdb); if(replacers) { trans->add = alpm_list_join(trans->add, replacers); } } } } return 0; }
static alpm_list_t *check_replacers(alpm_handle_t *handle, alpm_pkg_t *lpkg, alpm_db_t *sdb) { /* 2. search for replacers in sdb */ alpm_list_t *replacers = NULL; alpm_list_t *k; _alpm_log(handle, ALPM_LOG_DEBUG, "searching for replacements for %s in %s\n", lpkg->name, sdb->treename); for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) { int found = 0; alpm_pkg_t *spkg = k->data; alpm_list_t *l; for(l = alpm_pkg_get_replaces(spkg); l; l = l->next) { alpm_depend_t *replace = l->data; /* we only want to consider literal matches at this point. */ if(_alpm_depcmp_literal(lpkg, replace)) { found = 1; break; } } if(found) { alpm_question_replace_t question = { .type = ALPM_QUESTION_REPLACE_PKG, .replace = 0, .oldpkg = lpkg, .newpkg = spkg, .newdb = sdb }; alpm_pkg_t *tpkg; /* check IgnorePkg/IgnoreGroup */ if(alpm_pkg_should_ignore(handle, spkg) || alpm_pkg_should_ignore(handle, lpkg)) { _alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package replacement (%s-%s => %s-%s)\n"), lpkg->name, lpkg->version, spkg->name, spkg->version); continue; } QUESTION(handle, &question); if(!question.replace) { continue; } /* If spkg is already in the target list, we append lpkg to spkg's * removes list */ tpkg = alpm_pkg_find(handle->trans->add, spkg->name); if(tpkg) { /* sanity check, multiple repos can contain spkg->name */ if(tpkg->origin_data.db != sdb) { _alpm_log(handle, ALPM_LOG_WARNING, _("cannot replace %s by %s\n"), lpkg->name, spkg->name); continue; } _alpm_log(handle, ALPM_LOG_DEBUG, "appending %s to the removes list of %s\n", lpkg->name, tpkg->name); tpkg->removes = alpm_list_add(tpkg->removes, lpkg); /* check the to-be-replaced package's reason field */ if(alpm_pkg_get_reason(lpkg) == ALPM_PKG_REASON_EXPLICIT) { tpkg->reason = ALPM_PKG_REASON_EXPLICIT; } } else { /* add spkg to the target list */ /* copy over reason */ spkg->reason = alpm_pkg_get_reason(lpkg); spkg->removes = alpm_list_add(NULL, lpkg); _alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n", spkg->name, spkg->version); replacers = alpm_list_add(replacers, spkg); } } } return replacers; } /** Search for packages to upgrade and add them to the transaction. */ int SYMEXPORT alpm_sync_sysupgrade(alpm_handle_t *handle, int enable_downgrade) { alpm_list_t *i, *j; alpm_trans_t *trans; CHECK_HANDLE(handle, return -1); trans = handle->trans; ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1)); _alpm_log(handle, ALPM_LOG_DEBUG, "checking for package upgrades\n"); for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) { alpm_pkg_t *lpkg = i->data; if(alpm_pkg_find(trans->remove, lpkg->name)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s is marked for removal -- skipping\n", lpkg->name); continue; } if(alpm_pkg_find(trans->add, lpkg->name)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name); continue; } /* Search for replacers then literal (if no replacer) in each sync database. */ for(j = handle->dbs_sync; j; j = j->next) { alpm_db_t *sdb = j->data; alpm_list_t *replacers; if(!(sdb->usage & ALPM_DB_USAGE_UPGRADE)) { continue; } /* Check sdb */ replacers = check_replacers(handle, lpkg, sdb); if(replacers) { trans->add = alpm_list_join(trans->add, replacers); /* jump to next local package */ break; } else { alpm_pkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name); if(spkg) { if(check_literal(handle, lpkg, spkg, enable_downgrade)) { trans->add = alpm_list_add(trans->add, spkg); } /* jump to next local package */ break; } } } } return 0; }