Example #1
0
char *find_prefix_line(struct buffer *buff, const char *prefix, int prefix_size)
{
	int count;
	char *p = buff->space;
	char *end_p = p + buff->size;

	while (is_empty_character(*prefix) && prefix_size)
	{
		prefix++;
		prefix_size--;
	}

	if (prefix_size == 0)
	{
		return NULL;
	}

	end_p -= prefix_size;

	while (1)
	{
		for (count = 0; p < end_p && is_empty_character(*p); p++, count++);

		if (p >= end_p)
		{
			return NULL;
		}

		if (memcmp(p, prefix, prefix_size) == 0)
		{
			return p - count;
		}

		p = find_next_line(buff, p);
		if (p == NULL)
		{
			return NULL;
		}
	}

	return NULL;
}
void
grub_envblk_delete (grub_envblk_t envblk, const char *name)
{
  char *p, *pend;
  int nl;

  nl = strlen (name);
  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
  pend = envblk->buf + envblk->size;

  while (p + nl + 1 < pend)
    {
      if (strncmp (p, name, nl) == 0 && p[nl] == '=')
        {
          /* Found.  */
          int len = nl + 1;

          while (p + len < pend)
            {
              if (p[len] == '\n')
                break;
              else if (p[len] == '\\')
                len += 2;
              else
                len++;
            }

          if (p + len >= pend)
            /* Broken.  */
            return;

          len++;
          g_memmove (p, p + len, pend - (p + len));
          grub_memset (pend - len, '#', len);
          break;
        }

      p = find_next_line (p, pend);
    }
}
Example #3
0
struct buffer *replace_prefix_line(struct buffer *buff, const char *prefix, int prefix_size, const char *new_line, int new_line_size)
{
	char *p, *end_p, *q;
	struct buffer *new_buff;

	p = find_prefix_line(buff, prefix, prefix_size);
	if (p == NULL)
	{
		return NULL;
	}

	end_p = find_next_line(buff, p);
	if (end_p == NULL)
	{
		new_buff = malloc_buffer(buff->size + new_line_size + 1);
	}
	else
	{
		new_buff = malloc_buffer(buff->size - (end_p - p) + new_line_size + 1);
	}

	if (new_buff == NULL)
	{
		return NULL;
	}

	q = mem_area_copy(mem_area_copy(new_buff->space, buff->space, p - 1), new_line, new_line + new_line_size - 1);

	if (end_p == NULL)
	{
		return new_buff;
	}

	*q++ = '\n';
	mem_area_copy(q, end_p, buff->space + buff->size - 1);

	return new_buff;
}
Example #4
0
/* Start from some arbitrary line on a polyline and walk back to find
   the first node (i.e. for which the number of connected lines <> 2)
   This line must not be a dead line (note that the arbitrary line
   cannot be a dead line because this has already been checked in
   main.c. */
int walk_back(struct Map_info *map, int start_line, int type)
{
    int start_node, n1, n2;
    int line;
    int next_line;

    G_debug(2, "walk_back() start = %d", start_line);
    line = start_line;

    /* Otherwise find the start (i.e. travel in the negative direction) */
    Vect_get_line_nodes(map, line, &start_node, NULL);

    while (1) {
	/* Find next line at start node */
	next_line = find_next_line(map, line, start_node, type);
	G_debug(2, "  next = %d", next_line);

	/* Keep going so long as not returned to start_line, i.e. if not a closed set of lines */
	if (next_line == 0 || next_line == start_line)
	    break;

	line = next_line;
	/* In a heavily edited binary vector map the relationship
	   between the direction of a line (in terms of whether it is
	   positive or negative in a node's line array) and the order of
	   the line's nodes N1 and N2 is not constant.  So here we flip
	   the direction of travel if the initial direction of travel
	   points back to the same line. */
	Vect_get_line_nodes(map, next_line, &n1, &n2);
	if (n2 == start_node)
	    start_node = n1;
	else
	    start_node = n2;
    }

    return (line);
}
Example #5
0
/* Start from the first node on a polyline and walk to the other end,
   collecting the coordinates of each node en route.  */
int walk_forward_and_pick_up_coords(struct Map_info *map,
				    int start_line, int ltype,
				    struct line_pnts *points,
				    int *lines_visited,
				    struct line_cats *Cats, int write_cats)
{
    int cat_idx;
    int line, next_line, n1, n2;
    int type, node, next_node;
    struct line_pnts *pnts;
    struct line_cats *cats_tmp;

    G_debug(2, "  walk_forward() start = %d", start_line);
    line = start_line;
    pnts = Vect_new_line_struct();
    if (write_cats != NO_CATS) {
	cats_tmp = Vect_new_cats_struct();
    }
    else {
	cats_tmp = NULL;
    }

    Vect_reset_line(points);

    /* Pick up first set of coordinates */
    lines_visited[line] = 1;
    if (cats_tmp)
	type = Vect_read_line(map, pnts, Cats, line);
    else
	type = Vect_read_line(map, pnts, NULL, line);

    Vect_get_line_nodes(map, line, &n1, &n2);
    next_line = find_next_line(map, line, n1, ltype);
    if (next_line > 0) {	/* continue at start node */
	Vect_append_points(points, pnts, GV_BACKWARD);
	next_node = n1;
    }
    else {
	Vect_append_points(points, pnts, GV_FORWARD);
	next_line = find_next_line(map, line, n2, ltype);	/* check end node */
	if (next_line > 0) {
	    next_node = n2;	/* continue at end node */
	}
	else {
	    return 1;		/* no other line */
	}
    }

    /* While next line exist append coordinates */
    line = next_line;
    node = next_node;
    while (line != 0 && line != start_line) {
	G_debug(2, "  line = %d", line);
	type = Vect_read_line(map, pnts, cats_tmp, line);
	if (cats_tmp && write_cats == MULTI_CATS) {
	    for (cat_idx = 0; cat_idx < cats_tmp->n_cats; cat_idx++) {
		Vect_cat_set(Cats, cats_tmp->field[cat_idx],
			     cats_tmp->cat[cat_idx]);
	    }
	}
	Vect_get_line_nodes(map, line, &n1, &n2);

	if (node == n1) {
	    Vect_line_delete_point(pnts, 0);	/* delete duplicate nodes */
	    Vect_append_points(points, pnts, GV_FORWARD);
	    next_node = n2;
	}
	else {
	    Vect_line_delete_point(pnts, pnts->n_points - 1);
	    Vect_append_points(points, pnts, GV_BACKWARD);
	    next_node = n1;
	}

	lines_visited[line] = 1;

	/* Find next one */
	next_line = find_next_line(map, line, next_node, ltype);

	line = next_line;
	node = next_node;
    }

    if (cats_tmp)
	Vect_destroy_cats_struct(cats_tmp);

    return 1;
}
int
grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value)
{
  char *p, *pend;
  char *space;
  int found = 0;
  int nl;
  int vl;
  int i;

  nl = strlen (name);
  vl = escaped_value_len (value);
  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
  pend = envblk->buf + envblk->size;

  /* First, look at free space.  */
  for (space = pend - 1; *space == '#'; space--)
    ;

  if (*space != '\n')
    /* Broken.  */
    return 0;

  space++;

  while (p + nl + 1 < space)
    {
      if (strncmp (p, name, nl) == 0 && p[nl] == '=')
        {
          int len;

          /* Found the same name.  */
          p += nl + 1;

          /* Check the length of the current value.  */
          len = 0;
          while (p + len < pend && p[len] != '\n')
            {
              if (p[len] == '\\')
                len += 2;
              else
                len++;
            }

          if (p + len >= pend)
            /* Broken.  */
            return 0;

          if (pend - space < vl - len)
            /* No space.  */
            return 0;

          if (vl < len)
            {
              /* Move the following characters backward, and fill the new
                 space with harmless characters.  */
              g_memmove (p + vl, p + len, pend - (p + len));
              grub_memset (space + len - vl, '#', len - vl);
            }
          else
            /* Move the following characters forward.  */
            g_memmove (p + vl, p + len, pend - (p + vl));

          found = 1;
          break;
        }

      p = find_next_line (p, pend);
    }

  if (! found)
    {
      /* Append a new variable.  */

      if (pend - space < nl + 1 + vl + 1)
        /* No space.  */
        return 0;

      memcpy (space, name, nl);
      p = space + nl;
      *p++ = '=';
    }

  /* Write the value.  */
  for (i = 0; value[i]; i++)
    {
      if (value[i] == '\\' || value[i] == '\n')
        *p++ = '\\';

      *p++ = value[i];
    }

  *p = '\n';
  return 1;
}
void
grub_envblk_iterate (grub_envblk_t envblk,
                     int hook (const char *name, const char *value))
{
  char *p, *pend;

  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
  pend = envblk->buf + envblk->size;

  while (p < pend)
    {
      if (*p != '#')
        {
          char *name;
          char *value;
          char *name_start, *name_end, *value_start;
          char *q;
          int ret;

          name_start = p;
          while (p < pend && *p != '=')
            p++;
          if (p == pend)
            /* Broken.  */
            return;
          name_end = p;

          p++;
          value_start = p;
          while (p < pend)
            {
              if (*p == '\n')
                break;
              else if (*p == '\\')
                p += 2;
              else
                p++;
            }

          if (p >= pend)
            /* Broken.  */
            return;

          name = g_malloc (p - name_start + 1);
          if (! name)
            /* out of memory.  */
            return;

          value = name + (value_start - name_start);

          memcpy (name, name_start, name_end - name_start);
          name[name_end - name_start] = '\0';

          for (p = value_start, q = value; *p != '\n'; ++p)
            {
              if (*p == '\\')
                *q++ = *++p;
              else
                *q++ = *p;
            }
          *q = '\0';

          ret = hook (name, value);
          g_free (name);
          if (ret)
            return;
        }

      p = find_next_line (p, pend);
    }
}