View of xos/usr/lib/readline/line.c


XOS | Parent Directory | View | Download

/* Copyright (C) 2008  Emmanuel Varoquaux
 
   This file is part of XOS.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
#include "line.h"
 
#include "xmalloc.h"
 
#include <string.h>
#include <stdlib.h>
 
#define LINEBUF_GROW_SIZE 256
 
#define max(a, b) ((a) > (b) ? (a) : (b))
 
static struct linebuf_struct *current_linebuf;
 
char *line;
int line_end;
int point;
int mark;
 
/* linebuf */
 
static void alloc_linebuf(struct linebuf_struct *linebuf, size_t size)
{
  linebuf->buf = xmalloc(size);
  linebuf->size = size;
}
 
static void resize_linebuf(struct linebuf_struct *linebuf, size_t newsize)
{
  current_linebuf->buf = xrealloc(current_linebuf->buf, newsize);
  current_linebuf->size = newsize;
}
 
static void free_linebuf(struct linebuf_struct *linebuf)
{
  free(linebuf->buf);
}
 
void linebuf_init(struct linebuf_struct *linebuf, const char *s)
{
  alloc_linebuf(linebuf, strlen(s) + 1);
  strcpy(linebuf->buf, s);
}
 
void linebuf_destroy(struct linebuf_struct *linebuf)
{
  free_linebuf(linebuf);
}
 
/* line */
 
static void shift(int from, int to)
{
  int n;
 
  n = to - from;
  if (line_end + n > ((int)current_linebuf->size - 1)) {
    resize_linebuf(current_linebuf, current_linebuf->size + max(LINEBUF_GROW_SIZE, n));
    line = current_linebuf->buf;
  }
  memmove(line + to, line + from, line_end - from + 1);
  line_end += n;
}
 
void line_set(struct linebuf_struct *linebuf)
{
  current_linebuf = linebuf;
  line = linebuf->buf;
  line_end = strlen(line);
  point = line_end;
  mark = 0;
}
 
void line_replace_region_with_char(int start, int end, char c)
{
  if (start + 1 != end)
    shift(end, start + 1);
  line[start] = c;
  point = start + 1;
}
 
void line_replace_region_with_text(int start, int end, const char *text)
{
  int n;
 
  n = strlen(text);
  if (start + n != end)
    shift(end, start + n);
  memcpy(line + start, text, n);
  point = start + n;
}
 
void line_erase_region(int start, int end)
{
  if (start != end)
    memset(line + start, ' ', end - start);
  point = start;
}
 
void line_delete_region(int start, int end)
{
  if (start != end)
    shift(end, start);
  point = start;
}
 
void line_set_point(int newpoint)
{
  point = newpoint;
}
 
void line_set_mark(int newmark)
{
  mark = newmark;
}
 
void line_discard()
{
  current_linebuf = NULL;
  line = NULL;
}
 
void line_release()
{
  if (line)
    line = xstrdup(line);
}