Ejemplo n.º 1
0
void search()
{
	int cpos = 0;
	int c;
	point_t o_point = curbp->b_point;
	point_t found;

	searchtext[0] = '\0';
	display_prompt_and_response(m_sprompt, searchtext);
	cpos = strlen(searchtext);

	for (;;) {
		c = getch();
		/* ignore control keys other than C-g, backspace, CR,  C-s, C-R, ESC */
		if (c < 32 && c != 07 && c != 0x08 && c != 0x13 && c != 0x12 && c != 0x1b)
			continue;

		switch(c) {
		case 0x1b: /* esc */
			searchtext[cpos] = '\0';
			flushinp(); /* discard any escape sequence without writing in buffer */
			return;

		case 0x07: /* ctrl-g */
			curbp->b_point = o_point;
			return;

		case 0x13: /* ctrl-s, do the search */
			found = search_forward(searchtext);
			display_search_result(found, FWD_SEARCH, m_sprompt, searchtext);
			break;

		case 0x12: /* ctrl-r, do the search */
			found = search_backwards(searchtext);
			display_search_result(found, REV_SEARCH, m_sprompt, searchtext);
			break;

		case 0x7f: /* del, erase */
		case 0x08: /* backspace */
			if (cpos == 0)
				continue;
			searchtext[--cpos] = '\0';
			display_prompt_and_response(m_sprompt, searchtext);
			break;

		default:
			if (cpos < STRBUF_M - 1) {
				searchtext[cpos++] = c;
				searchtext[cpos] = '\0';
				display_prompt_and_response(m_sprompt, searchtext);
			}
			break;
		}
	}
}
Ejemplo n.º 2
0
/* Search forwards or backwards for the text delimited by BINDING.
   The search is forwards if BINDING->start is greater than BINDING->end. */
long
search (char *string, SEARCH_BINDING *binding)
{
  long result;

  /* If the search is backwards, then search backwards, otherwise forwards. */
  if (binding->start > binding->end)
    result = search_backward (string, binding);
  else
    result = search_forward (string, binding);

  return result;
}
Ejemplo n.º 3
0
/* Find STRING in LINE, returning the offset of the end of the string.
   Return an offset of -1 if STRING does not appear in LINE.  The search
   is bound by the end of the line (i.e., either NEWLINE or 0). */
int
string_in_line (char *string, char *line)
{
  register int end;
  SEARCH_BINDING binding;

  /* Find the end of the line. */
  for (end = 0; line[end] && line[end] != '\n'; end++);

  /* Search for STRING within these confines. */
  binding.buffer = line;
  binding.start = 0;
  binding.end = end;
  binding.flags = S_FoldCase | S_SkipDest;

  return search_forward (string, &binding);
}
Ejemplo n.º 4
0
/*search for a string and replace it with another string */
void query_replace(void)
{
	point_t o_point = curbp->b_point;
	point_t l_point = -1;
	point_t found;
	char question[STRBUF_L];
	int slen, rlen;   /* length of search and replace strings */
	int numsub = 0;   /* number of substitutions */
	int ask = TRUE;
	int c;

	searchtext[0] = '\0';
	replace[0] = '\0';
	
	if (!getinput("Query replace: ", (char*)searchtext, STRBUF_M))
		return;

	if (!getinput("With: ", (char*)replace, STRBUF_M))
		return;

	slen = strlen(searchtext);
	rlen = strlen(replace);
	
	/* build query replace question string */
	sprintf(question, "Replace '%s' with '%s' ? ", searchtext, replace);

	/* scan through the file, from point */
	numsub = 0;
	while(TRUE) {
		found = search_forward(searchtext);

		/* if not found set the point to the last point of replacement, or where we started */
		if (found == -1) {
			curbp->b_point = (l_point == -1 ? o_point : l_point);
			break;
		}

		curbp->b_point = found;
		/* search_forward places point at end of search, move to start of search */
		curbp->b_point -= slen;

		if (ask == TRUE) {
			msg(question);
			clrtoeol();
			
		qprompt:
			display(curwp, TRUE);
			c = getch();

			switch (c) {
			case 'y': /* yes, substitute */
				break;
			
			case 'n': /* no, find next */
				curbp->b_point = found; /* set to end of search string */
				continue;
			
			case '!': /* yes/stop asking, do the lot */
				ask = FALSE;
				break;
			
			case 0x1B: /* esc */
				flushinp(); /* discard any escape sequence without writing in buffer */
			case 'q': /* controlled exit */
				return;

			default: /* help me */
				msg("(y)es, (n)o, (!)do the rest, (q)uit");
				goto qprompt;
			}
		}
		
		if (rlen > slen) {
			movegap(curbp, found);
			/*check enough space in gap left */
			if (rlen - slen < curbp->b_egap - curbp->b_gap)
				growgap(curbp, rlen - slen);
			/* shrink gap right by r - s */
			curbp->b_gap = curbp->b_gap + (rlen - slen);
		} else if (slen > rlen) {
			movegap(curbp, found);
			/* stretch gap left by s - r, no need to worry about space */
			curbp->b_gap = curbp->b_gap - (slen - rlen);
		} else {
			/* if rlen = slen, we just overwrite the chars, no need to move gap */		
		}

		/* now just overwrite the chars at point in the buffer */
		l_point = curbp->b_point;
		memcpy(ptr(curbp, curbp->b_point), replace, rlen * sizeof (char_t));
		curbp->b_flags |= B_MODIFIED;
		curbp->b_point = found - (slen - rlen); /* end of replcement */
		numsub++;
	}

	msg("%d substitutions", numsub);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
static int
pdf_insert_bookmark(
    PDF *p,
    const char *hypertext,
    pdf_outline *outline,
    int jndex)
{
    static const char fn[] = "pdf_insert_bookmark";
    pdf_outline *root, *self;
    int parent;
    int self_idx;
    int pageno = pdf_current_page(p);

    /* allocation */
    if (p->outline_count == 0)
    {
        p->outline_capacity = OUTLINE_CHUNKSIZE;
        p->outlines = (pdf_outline *) pdc_calloc(p->pdc,
                          sizeof(pdf_outline) * p->outline_capacity, fn);

        /* populate the root outline object */
        root = &p->outlines[0];
        pdf_init_outline(p, root);
        root->obj_id = pdc_alloc_id(p->out);
        root->open = pdc_true;

        /* set the open mode show bookmarks if we have at least one,
         * and the client didn't already set his own open mode.
         */
        pdf_fix_openmode(p);
    }
    else if (p->outline_count + 1 >= p->outline_capacity)
    {
        p->outline_capacity *= 2;
        p->outlines = (pdf_outline *) pdc_realloc(p->pdc, p->outlines,
                          sizeof(pdf_outline) * p->outline_capacity, fn);
    }

    /* copy */
    self_idx = ++p->outline_count;
    self = &p->outlines[self_idx];
    memcpy(self, outline, sizeof(pdf_outline));

    self->obj_id = pdc_alloc_id(p->out);
    self->text = (char *) hypertext;
    self->page_id = pdf_get_page_id(p, 0);
    parent = self->parent;

    /* default destination */
    if (self->action == NULL && self->dest == NULL)
        self->dest = pdf_init_destination(p);

    /* no destination */
    if (self->dest != NULL &&
        self->dest->name != NULL && !strlen(self->dest->name))
    {
        pdf_cleanup_destination(p, self->dest);
        self->dest = NULL;
    }

    /* current page */
    if (self->dest)
    {
	/* this ugly code is for compatibility with the
	** obsolete "bookmarkdest" parameter.
	*/
        if (self->dest->pgnum == 0)
            self->dest->pgnum = pdf_current_page(p);

        if (self->dest->pgnum == 0)
	{
            self->dest->pgnum = 1;
	}
	else if (self->dest->page == PDC_BAD_ID)
	{
            self->dest->page = pdf_get_page_id(p, self->dest->pgnum);
	}
    }

    /* special case: empty list.
    */
    if (FIRST(parent) == 0)
    {
        if (jndex > 0)
	    pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index",
                pdc_errprintf(p->pdc, "%d", jndex), 0, 0);

        FIRST(parent) = LAST(parent) = self_idx;
	self->in_order = pdc_true;
    }
    else switch (jndex)
    {
	case -2:	/* insert "in order" */
	{
	    /* the "natural" case: append to the end if appropriate.
	    */
	    if (pageno >= search_backward(p, -1, LAST(parent)))
	    {
		self->prev = LAST(parent);
		NEXT(LAST(parent)) = self_idx;
		LAST(parent) = self_idx;
	    }
	    else
	    {
		int idx;
		int curr_pg = 1;
		int next_pg;

		for (idx = FIRST(parent); idx != 0; idx = NEXT(idx))
		{
		    if (!IN_ORDER(idx))
			continue;

		    next_pg = pdf_search_page_fwd(p, curr_pg, PAGE_ID(idx));

		    /* TODO: understand why this can happen.
		    */
		    if (next_pg < 1)
		    {
			idx = 0;
			break;
		    }

		    if (next_pg > pageno)
		    {
			self->next = idx;
			self->prev = PREV(idx);
			PREV(idx) = self_idx;

			if (self->prev == 0)
			    FIRST(parent) = self_idx;
			else
			    NEXT(self->prev) = self_idx;

			break;
		    }

		    curr_pg = next_pg;
		}

		/* if there are no "in order" bookmarks yet,
		** we simply append this one to the end.
		*/
		if (idx == 0)
		{
		    self->prev = LAST(parent);
		    NEXT(LAST(parent)) = self_idx;
		    LAST(parent) = self_idx;
		}
	    }

	    self->in_order = pdc_true;
	    break;
	}

	case -1:	/* append to the end */
	{
	    self->prev = LAST(parent);
	    NEXT(LAST(parent)) = self_idx;
	    LAST(parent) = self_idx;

	    self->in_order =
		(pageno >= search_backward(p, pageno, self->prev));
	    break;
	}

	case 0:		/* insert at the beginning */
	{
	    self->next = FIRST(parent);
	    PREV(FIRST(parent)) = self_idx;
	    FIRST(parent) = self_idx;

	    self->in_order =
		(pageno <= search_forward(p, pageno, self->next));
	    break;
	}

	default:	/* insert before [1..LAST] */
	{
	    int i;
	    int target = FIRST(parent);

            for (i = 0; i < jndex; ++i)
	    {
		if (target == LAST(parent))
		    pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index",
                        pdc_errprintf(p->pdc, "%d", jndex), 0, 0);

		target = NEXT(target);
	    }

	    self->next = target;
	    self->prev = PREV(target);
	    NEXT(self->prev) = PREV(self->next) = self_idx;

	    self->in_order =
		((pageno >= search_backward(p, pageno, self->prev)) &&
		(pageno <= search_forward(p, pageno, self->next)));
	    break;
	}
    } /* else switch */

    /* increase the number of open sub-entries for all relevant ancestors */
    do {
        COUNT(parent)++;
    } while (OPEN(parent) && (parent = PARENT(parent)) != 0);

    return (self_idx);          /* caller may use this as handle */
}
Ejemplo n.º 7
0
/* Treat this just like @unnumbered.  The only difference is
   in node defaulting. */
void
cm_top (void)
{
  /* It is an error to have more than one @top. */
  if (top_node_seen && strcmp (current_node, "Top") != 0)
    {
      TAG_ENTRY *tag = tag_table;

      line_error (_("Node with %ctop as a section already exists"),
                  COMMAND_PREFIX);

      while (tag)
        {
          if (tag->flags & TAG_FLAG_IS_TOP)
            {
              file_line_error (tag->filename, tag->line_no,
                               _("Here is the %ctop node"), COMMAND_PREFIX);
              return;
            }
          tag = tag->next_ent;
        }
    }
  else
    {
      top_node_seen = 1;

      /* It is an error to use @top before using @node. */
      if (!tag_table)
        {
          char *top_name;

          get_rest_of_line (0, &top_name);
          line_error (_("%ctop used before %cnode, defaulting to %s"),
                      COMMAND_PREFIX, COMMAND_PREFIX, top_name);
          execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name);
          free (top_name);
          return;
        }

      cm_unnumbered ();

      /* The most recently defined node is the top node. */
      tag_table->flags |= TAG_FLAG_IS_TOP;

      /* Now set the logical hierarchical level of the Top node. */
      {
        int orig_offset = input_text_offset;

        input_text_offset = search_forward (node_search_string, orig_offset);

        if (input_text_offset > 0)
          {
            int this_section;

            /* We have encountered a non-top node, so mark that one exists. */
            non_top_node_seen = 1;

            /* Move to the end of this line, and find out what the
               sectioning command is here. */
            while (input_text[input_text_offset] != '\n')
              input_text_offset++;

            if (input_text_offset < input_text_length)
              input_text_offset++;

            this_section = what_section (input_text + input_text_offset,
                                         NULL);

            /* If we found a sectioning command, then give the top section
               a level of this section - 1. */
            if (this_section != -1)
              set_top_section_level (this_section - 1);
          }
        input_text_offset = orig_offset;
      }
    }
}