Beispiel #1
0
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;
  }
}
Beispiel #2
0
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;
}
Beispiel #3
0
/** 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;
}
Beispiel #4
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;
}