Ejemplo n.º 1
0
/* Return the index of the first non-whitespace or newline character in
   STRING. */
int
skip_whitespace_and_newlines (char *string)
{
  register int i;

  for (i = 0; string && whitespace_or_newline (string[i]); i++);
  return i;
}
Ejemplo n.º 2
0
/* Return the index of the first non-node character in STRING.  Note that
   this function contains quite a bit of hair to ignore periods in some
   special cases.  This is because we here at GNU ship some info files which
   contain nodenames that contain periods.  No such nodename can start with
   a period, or continue with whitespace, newline, or ')' immediately following
   the period.  If second argument NEWLINES_OKAY is non-zero, newlines should
   be skipped while parsing out the nodename specification. */
int
skip_node_characters (char *string, int newlines_okay)
{
  register int c, i = 0;
  int paren_seen = 0;
  int paren = 0;

  /* Handle special case.  This is when another function has parsed out the
     filename component of the node name, and we just want to parse out the
     nodename proper.  In that case, a period at the start of the nodename
     indicates an empty nodename. */
  if (string && *string == '.')
    return 0;

  if (string && *string == '(')
    {
      paren++;
      paren_seen++;
      i++;
    }

  for (; string && (c = string[i]); i++)
    {
      if (paren)
        {
          if (c == '(')
            paren++;
          else if (c == ')')
            paren--;

          continue;
        }
      
      /* If the character following the close paren is a space or period,
         then this node name has no more characters associated with it. */
      if (c == '\t' ||
          c == ','  ||
          c == INFO_TAGSEP ||
          ((!newlines_okay) && (c == '\n')) ||
          ((paren_seen && string[i - 1] == ')') &&
           (c == ' ' || c == '.')) ||
          (c == '.' &&
           (
#if 0
/* This test causes a node name ending in a period, like `This.', not to
   be found.  The trailing . is stripped.  This occurs in the jargon
   file (`I see no X here.' is a node name).  */
           (!string[i + 1]) ||
#endif
            (whitespace_or_newline (string[i + 1])) ||
            (string[i + 1] == ')'))))
        break;
    }
  return i;
}
Ejemplo n.º 3
0
/* Search for sequences of whitespace or newlines in STRING, replacing
   all such sequences with just a single space.  Remove whitespace from
   start and end of string. */
void
canonicalize_whitespace (char *string)
{
  register int i, j;
  int len, whitespace_found, whitespace_loc = 0;
  char *temp;

  if (!string)
    return;

  len = strlen (string);
  temp = xmalloc (1 + len);

  /* Search for sequences of whitespace or newlines.  Replace all such
     sequences in the string with just a single space. */

  whitespace_found = 0;
  for (i = 0, j = 0; string[i]; i++)
    {
      if (whitespace_or_newline (string[i]))
        {
          whitespace_found++;
          whitespace_loc = i;
          continue;
        }
      else
        {
          if (whitespace_found && whitespace_loc)
            {
              whitespace_found = 0;

              /* Suppress whitespace at start of string. */
              if (j)
                temp[j++] = ' ';
            }

          temp[j++] = string[i];
        }
    }

  /* Kill trailing whitespace. */
  if (j && whitespace (temp[j - 1]))
    j--;

  temp[j] = '\0';
  strcpy (string, temp);
  free (temp);
}
Ejemplo n.º 4
0
/* Given CONTENTS and FB (a file buffer), add the menu found in CONTENTS
   to the menu found in FB->contents.  Second argument SIZE is the total
   size of CONTENTS. */
static void
add_menu_to_file_buffer (char *contents, size_t size, FILE_BUFFER *fb)
{
  SEARCH_BINDING contents_binding, fb_binding;
  long contents_offset, fb_offset;

  contents_binding.buffer = contents;
  contents_binding.start = 0;
  contents_binding.end = size;
  contents_binding.flags = S_FoldCase | S_SkipDest;

  fb_binding.buffer = fb->contents;
  fb_binding.start = 0;
  fb_binding.end = fb->filesize;
  fb_binding.flags = S_FoldCase | S_SkipDest;

  /* Move to the start of the menus in CONTENTS and FB. */
  if (search_forward (INFO_MENU_LABEL, &contents_binding, &contents_offset)
      != search_success)
    /* If there is no menu in CONTENTS, quit now. */
    return;

  /* There is a menu in CONTENTS, and contents_offset points to the first
     character following the menu starter string.  Skip all whitespace
     and newline characters. */
  contents_offset += skip_whitespace_and_newlines (contents + contents_offset);

  /* If there is no menu in FB, make one. */
  if (search_forward (INFO_MENU_LABEL, &fb_binding, &fb_offset)
      != search_success)
    {
      /* Find the start of the second node in this file buffer.  If there
         is only one node, we will be adding the contents to the end of
         this node. */
      fb_offset = find_node_separator (&fb_binding);

      /* If not even a single node separator, give up. */
      if (fb_offset == -1)
        return;

      fb_binding.start = fb_offset;
      fb_binding.start +=
        skip_node_separator (fb_binding.buffer + fb_binding.start);

      /* Try to find the next node separator. */
      fb_offset = find_node_separator (&fb_binding);

      /* If found one, consider that the start of the menu.  Otherwise, the
         start of this menu is the end of the file buffer (i.e., fb->size). */
      if (fb_offset != -1)
        fb_binding.start = fb_offset;
      else
        fb_binding.start = fb_binding.end;

      insert_text_into_fb_at_binding
        (fb, &fb_binding, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL));

      fb_binding.buffer = fb->contents;
      fb_binding.start = 0;
      fb_binding.end = fb->filesize;
      if (search_forward (INFO_MENU_LABEL, &fb_binding, &fb_offset)
	  != search_success)
        abort ();
    }

  /* CONTENTS_OFFSET and FB_OFFSET point to the starts of the menus that
     appear in their respective buffers.  Add the remainder of CONTENTS
     to the end of FB's menu. */
  fb_binding.start = fb_offset;
  fb_offset = find_node_separator (&fb_binding);
  if (fb_offset != -1)
    fb_binding.start = fb_offset;
  else
    fb_binding.start = fb_binding.end;

  /* Leave exactly one blank line between directory entries. */
  {
    int num_found = 0;

    while ((fb_binding.start > 0) &&
           (whitespace_or_newline (fb_binding.buffer[fb_binding.start - 1])))
      {
        num_found++;
        fb_binding.start--;
      }

    /* Optimize if possible. */
    if (num_found >= 2)
      {
        fb_binding.buffer[fb_binding.start++] = '\n';
        fb_binding.buffer[fb_binding.start++] = '\n';
      }
    else
      {
        /* Do it the hard way. */
        insert_text_into_fb_at_binding (fb, &fb_binding, "\n\n", 2);
        fb_binding.start += 2;
      }
  }

  /* Insert the new menu. */
  insert_text_into_fb_at_binding
    (fb, &fb_binding, contents + contents_offset, size - contents_offset);
}