Ejemplo n.º 1
0
termline* newline(const char* chars) {
  static termline* line = 0;
  if (line)
    freeline(line);
  line = alloc_newline(chars);
  return line;
}
Ejemplo n.º 2
0
const char* syntax(const char *chars) {
  size_t sz = strlen(chars);
  termline* line = alloc_newline(chars);
  int jed_prefix_length = t24_is_jed_line(line->chars, sz);
  t24_basic_highlight(line->chars, sz, jed_prefix_length);
  const char* result = decode_colors(line->chars, sz);
  freeline(line);
  return result;
}
Ejemplo n.º 3
0
/*
 * Set up the terminal for a given size.
 */
void
term_resize(int newrows, int newcols)
{
  bool on_alt_screen = term.on_alt_screen;
  term_switch_screen(0, false);

  term.selected = false;

  term.marg_top = 0;
  term.marg_bot = newrows - 1;

 /*
  * Resize the screen and scrollback. We only need to shift
  * lines around within our data structures, because lineptr()
  * will take care of resizing each individual line if
  * necessary. So:
  * 
  *  - If the new screen is longer, we shunt lines in from temporary
  *    scrollback if possible, otherwise we add new blank lines at
  *    the bottom.
  *
  *  - If the new screen is shorter, we remove any blank lines at
  *    the bottom if possible, otherwise shunt lines above the cursor
  *    to scrollback if possible, otherwise delete lines below the
  *    cursor.
  * 
  *  - Then, if the new scrollback length is less than the
  *    amount of scrollback we actually have, we must throw some
  *    away.
  */

  termlines *lines = term.lines;
  term_cursor *curs = &term.curs;
  term_cursor *saved_curs = &term.saved_cursors[term.on_alt_screen];

  // Shrink the screen if newrows < rows
  if (newrows < term.rows) {
    int removed = term.rows - newrows;
    int destroy = min(removed, term.rows - (curs->y + 1));
    int store = removed - destroy;
    
    // Push removed lines into scrollback
    for (int i = 0; i < store; i++) {
      termline *line = lines[i];
      scrollback_push(compressline(line));
      freeline(line);
    }

    // Move up remaining lines
    memmove(lines, lines + store, newrows * sizeof(termline *));
    
    // Destroy removed lines below the cursor
    for (int i = term.rows - destroy; i < term.rows; i++)
      freeline(lines[i]);
    
    // Adjust cursor position
    curs->y = max(0, curs->y - store);
    saved_curs->y = max(0, saved_curs->y - store);
  }

  term.lines = lines = renewn(lines, newrows);
  
  // Expand the screen if newrows > rows
  if (newrows > term.rows) {
    int added = newrows - term.rows;
    int restore = min(added, term.tempsblines);
    int create = added - restore;
    
    // Fill bottom of screen with blank lines
    for (int i = newrows - create; i < newrows; i++)
      lines[i] = newline(newcols, false);
    
    // Move existing lines down
    memmove(lines + restore, lines, term.rows * sizeof(termline *));
    
    // Restore lines from scrollback
    for (int i = restore; i--;) {
      uchar *cline = scrollback_pop();
      termline *line = decompressline(cline, null);
      free(cline);
      line->temporary = false;  /* reconstituted line is now real */
      lines[i] = line;
    }
    
    // Adjust cursor position
    curs->y += restore;
    saved_curs->y += restore;
  }
  
  // Resize lines
  for (int i = 0; i < newrows; i++)
    resizeline(lines[i], newcols);
  
  // Make a new displayed text buffer.
  if (term.displines) {
    for (int i = 0; i < term.rows; i++)
      freeline(term.displines[i]);
  }
  term.displines = renewn(term.displines, newrows);
  for (int i = 0; i < newrows; i++) {
    termline *line = newline(newcols, false);
    term.displines[i] = line;
    for (int j = 0; j < newcols; j++)
      line->chars[j].attr = ATTR_INVALID;
  }

  // Make a new alternate screen.
  lines = term.other_lines;
  if (lines) {
    for (int i = 0; i < term.rows; i++)
      freeline(lines[i]);
  }
  term.other_lines = lines = renewn(lines, newrows);
  for (int i = 0; i < newrows; i++)
    lines[i] = newline(newcols, true);

  // Reset tab stops
  term.tabs = renewn(term.tabs, newcols);
  for (int i = (term.cols > 0 ? term.cols : 0); i < newcols; i++)
    term.tabs[i] = (i % 8 == 0);

  // Check that the cursor positions are still valid.
  assert(0 <= curs->y && curs->y < newrows);
  assert(0 <= saved_curs->y && saved_curs->y < newrows);
  curs->x = min(curs->x, newcols - 1);

  curs->wrapnext = false;

  term.disptop = 0;

  term.rows = newrows;
  term.cols = newcols;

  term_switch_screen(on_alt_screen, false);
}
Ejemplo n.º 4
0
static void
join (
     FILE *fp1,
     FILE *fp2 )
{
  struct seq seq1, seq2;
  struct line line;
  int diff, i, j, eof1, eof2;

  /* Read the first line of each file. */
  initseq (&seq1);
  getseq (fp1, &seq1);
  initseq (&seq2);
  getseq (fp2, &seq2);

  while (seq1.count && seq2.count)
    {
      diff = keycmp (&seq1.lines[0], &seq2.lines[0]);
      if (diff < 0)
	{
	  if (print_unpairables_1)
	    prline (&seq1.lines[0]);
	  freeline (&seq1.lines[0]);
	  seq1.count = 0;
	  getseq (fp1, &seq1);
	  continue;
	}
      if (diff > 0)
	{
	  if (print_unpairables_2)
	    prline (&seq2.lines[0]);
	  freeline (&seq2.lines[0]);
	  seq2.count = 0;
	  getseq (fp2, &seq2);
	  continue;
	}

      /* Keep reading lines from file1 as long as they continue to
	 match the current line from file2. */
      eof1 = 0;
      do
	if (!getseq (fp1, &seq1))
	  {
	    eof1 = 1;
	    ++seq1.count;
	    break;
	  }
      while (!keycmp (&seq1.lines[seq1.count - 1], &seq2.lines[0]));

      /* Keep reading lines from file2 as long as they continue to
	 match the current line from file1. */
      eof2 = 0;
      do
	if (!getseq (fp2, &seq2))
	  {
	    eof2 = 1;
	    ++seq2.count;
	    break;
	  }
      while (!keycmp (&seq1.lines[0], &seq2.lines[seq2.count - 1]));

      if (print_pairables)
	{
	  for (i = 0; i < seq1.count - 1; ++i)
	    for (j = 0; j < seq2.count - 1; ++j)
	      prjoin (&seq1.lines[i], &seq2.lines[j]);
	}

      for (i = 0; i < seq1.count - 1; ++i)
	freeline (&seq1.lines[i]);
      if (!eof1)
	{
	  seq1.lines[0] = seq1.lines[seq1.count - 1];
	  seq1.count = 1;
	}
      else
	seq1.count = 0;

      for (i = 0; i < seq2.count - 1; ++i)
	freeline (&seq2.lines[i]);
      if (!eof2)
	{
	  seq2.lines[0] = seq2.lines[seq2.count - 1];
	  seq2.count = 1;
	}
      else
	seq2.count = 0;
    }

  if (print_unpairables_1 && seq1.count)
    {
      prline (&seq1.lines[0]);
      freeline (&seq1.lines[0]);
      while (getline (fp1, &line))
	{
	  prline (&line);
	  freeline (&line);
	}
    }

  if (print_unpairables_2 && seq2.count)
    {
      prline (&seq2.lines[0]);
      freeline (&seq2.lines[0]);
      while (getline (fp2, &line))
	{
	  prline (&line);
	  freeline (&line);
	}
    }

  delseq (&seq1);
  delseq (&seq2);
}
Ejemplo n.º 5
0
/*
 * Process the library command.
 * This command (sadly) requires a rather
 * detailed knowledge of the file system of
 * the operating system.
 */
void library(void)
{
	char	*p;
	int	c;
	int	d;
	char	*sctp;
	struct line	*lp1;
	struct line	*lp2;
	FILE	*fp;

	c = getnb();
	if (c!='c' && c!='s' && c!='l' && c!='d')
		diag("Bad library command");
	while (isalpha(*ctp))
		++ctp;
	while ((d = *ctp)==' ' || d=='\t')
		++ctp;
	if (c!='l' && d==0)
		diag("Missing file name");
	p = ctp;
	while (*ctp != 0)
		++ctp;
	switch (c) {

	case 'c':
		if ((fp=fopen(p, "r")) == NULL)
			diag("Cannot open");
		lp1 = line;
		while (lp1 != NULL) {
			lp2 = lp1->l_fp;
			freeline(lp1);
			lp1 = lp2;
		}
		line = NULL;
		sctp = ctp;
		while (focal_getline(abuf, fp) != 0) {
			ctp = abuf;
			if ((c=getnb()) != 0) {
				if (isdigit(c) == 0)
					diag("Direct line in call");
				inject(c);
			}
		}
		fclose(fp);
		ctp = sctp;
		break;

	case 'd':
		if (remove(p) < 0)
			diag("Cannot delete");
		break;

	case 'l':
#ifndef	DIR_SUPPORT
		diag("Library list not implemented");
#else
	{
#ifdef	DOS
		int	attr = _A_RDONLY | _A_ARCH;
		int	rc;
		static struct find_t	de;
		static char	fname[FILENAME_MAX];
		char	*s;
		
		if (d == 0)
			strcpy(fname, "*.*");
		else {
			strcpy(fname, p);
			s = fname + strlen(fname) - 1;
			if (*s == '\\')
				strcat(fname, "*.*");
			else if (*s == '.')
				strcat(fname, "\\*.*");
		}
		rc = _dos_findfirst(fname, attr, &de);
		while (!rc) {
			if ((de.attrib & _A_SUBDIR) == 0
			    && strcmp(de.name, ".") != 0
			    && strcmp(de.name, "..") != 0)
				printf("%-13s\n", de.name);
			rc = _dos_findnext(&de);
		}
#else
#ifdef DIRENT
		struct dirent *de;
		DIR *dp;

		if (d == 0)
			p = ".";
		if ((dp = opendir(p)) == NULL) {
			perror("focal");
			diag("Bad directory");
		}
		while ((de = readdir(dp)) != NULL) {
			if (de->d_ino == 0
			    ||  strcmp(de->d_name, ".") == 0
			    ||  strcmp(de->d_name, "..") == 0)
				continue;
			printf("%s\n", de->d_name);
		}
		closedir(dp);
#else
		int	fd = 0;
		
		if (d == 0)
			p = ".";
		if (stat(p, &sb) < 0
		|| (sb.st_mode&S_IFMT) != S_IFDIR
		|| (fd = open(p, 0)) < 0)
			diag("Bad directory");
		while (read(fd, &db, sizeof(db)) == sizeof(db)) {
			if (db.d_ino == 0
			||  strncmp(db.d_name, ".",  DIRSIZ) == 0
			||  strncmp(db.d_name, "..", DIRSIZ) == 0)
				continue;
			printf("%.*s\n", DIRSIZ, db.d_name);
		}
		close(fd);
#endif
#endif
	}
#endif
		break;

	case 's':
		if ((fp=fopen(p, "w")) == NULL)
			diag("Cannot create");
		save(NULL, fp);
		fclose(fp);
		break;
	}
}