Exemple #1
0
/*
 * Return a `~/foo' like path if the user is under his home directory,
 * and restart from / if // found,
 * else the unmodified path.
 */
astr compact_path(const astr path)
{
  astr buf = astr_new();
  struct passwd *pw;
  size_t i;

  if ((pw = getpwuid(getuid())) == NULL) {
    /* User not found in password file. */
    astr_cpy(buf, path);
    return buf;
  }

  /* Replace `/userhome/' (if existent) with `~/'. */
  i = strlen(pw->pw_dir);
  if (!strncmp(pw->pw_dir, astr_cstr(path), i)) {
    astr_cpy_cstr(buf, "~/");
    if (!strcmp(pw->pw_dir, "/"))
      astr_cat_cstr(buf, astr_char(path, 1));
    else
      astr_cat_cstr(buf, astr_char(path, i + 1));
  } else
    astr_cpy(buf, path);

  return buf;
}
Exemple #2
0
static void draw_line(size_t line, size_t startcol, Window *wp, Line *lp,
		      size_t lineno, Region *r, int highlight)
{
  size_t x, i;

  term_move(line, 0);
  for (x = 0, i = startcol; i < astr_len(lp->item) && x < wp->ewidth; i++) {
    if (highlight && in_region(lineno, i, r))
      outch(*astr_char(lp->item, (ptrdiff_t)i), FONT_REVERSE, &x);
    else
      outch(*astr_char(lp->item, (ptrdiff_t)i), FONT_NORMAL, &x);
  }

  draw_end_of_line(line, wp, lineno, r, highlight, x, i);
}
Exemple #3
0
/*
 * Copy a region of text into an allocated buffer.
 */
char *
copy_text_block (size_t startn, size_t starto, size_t size)
{
  char *buf, *dp;
  size_t max_size, n, i;
  Line *lp;

  max_size = 10;
  dp = buf = (char *) xzalloc (max_size);

  lp = cur_bp->pt.p;
  n = cur_bp->pt.n;
  if (n > startn)
    do
      lp = lp->prev;
    while (--n > startn);
  else if (n < startn)
    do
      lp = lp->next;
    while (++n < startn);

  for (i = starto; dp - buf < (int) size;)
    {
      if (dp >= buf + max_size)
	{
	  int save_off = dp - buf;
	  max_size += 10;
	  buf = (char *) xrealloc (buf, max_size);
	  dp = buf + save_off;
	}
      if (i < astr_len (lp->text))
	*dp++ = *astr_char (lp->text, (ptrdiff_t) (i++));
      else
	{
	  *dp++ = '\n';
	  lp = lp->next;
	  i = 0;
	}
    }

  return buf;
}
Exemple #4
0
/*
 * Return the current directory.
 */
static astr get_current_dir(void)
{
  astr buf;
  int p;

  if (cur_bp->filename != NULL)
    /* If the current buffer has a filename, get the current directory
       name from it. */
    buf = astr_new_cstr(cur_bp->filename);
  else { /* Get the current directory name from the system. */
    buf = agetcwd();
    if (astr_len(buf) != 0 && *astr_char(buf, -1) != '/')
      astr_cat_char(buf, '/');
  }

  p = astr_rfind_cstr(buf, "/");
  astr_truncate(buf, p + 1);

  return buf;
}
Exemple #5
0
/*
 * This function calculates the best start column to draw if the line
 * needs to get truncated.
 * Called only for the line where is the point.
 */
static void calculate_start_column(Window *wp)
{
  size_t col = 0, lastcol = 0, t = tab_width(wp->bp);
  int rpfact, lpfact;
  char *buf, *rp, *lp, *p;
  Point pt = window_pt(wp);

  rp = astr_char(pt.p->item, (ptrdiff_t)pt.o);
  rpfact = pt.o / (wp->ewidth / 3);

  for (lp = rp; lp >= astr_cstr(pt.p->item); --lp) {
    for (col = 0, p = lp; p < rp; ++p)
      if (*p == '\t') {
        col |= t - 1;
        ++col;
      } else if (isprint(*p))
        ++col;
      else {
        col += make_char_printable(&buf, (size_t)*p);
        free(buf);
      }

    lpfact = (lp - astr_cstr(pt.p->item)) / (wp->ewidth / 3);

    if (col >= wp->ewidth - 1 || lpfact < (rpfact - 2)) {
      wp->start_column = lp + 1 - astr_cstr(pt.p->item);
      point_screen_column = lastcol;
      return;
    }

    lastcol = col;
  }

  wp->start_column = 0;
  point_screen_column = col;
}
Exemple #6
0
/*
 * This functions does some corrections and expansions to
 * the passed path:
 * - expands `~/' and `~name/' expressions;
 * - replaces `//' with `/' (restarting from the root directory);
 * - removes `..' and `.' entries.
 *
 * If something goes wrong, the string is deleted and NULL returned
 */
astr expand_path(astr path)
{
  int ret = TRUE;
  struct passwd *pw;
  const char *sp = astr_cstr(path);
  astr epath = astr_new();

  if (*sp != '/') {
    astr_cat_delete(epath, agetcwd());
    if (astr_len(epath) == 0 || *astr_char(epath, -1) != '/')
      astr_cat_char(epath, '/');
  }

  while (*sp != '\0') {
    if (*sp == '/') {
      if (*++sp == '/') {
        /* Got `//'.  Restart from this point. */
        while (*sp == '/')
          sp++;
        astr_truncate(epath, 0);
      }
      astr_cat_char(epath, '/');
    } else if (*sp == '~') {
      if (*(sp + 1) == '/') {
        /* Got `~/'. Restart from this point and insert the user's
           home directory. */
        astr_truncate(epath, 0);
        if ((pw = getpwuid(getuid())) == NULL) {
          ret = FALSE;
          break;
        }
        if (strcmp(pw->pw_dir, "/") != 0)
          astr_cat_cstr(epath, pw->pw_dir);
        ++sp;
      } else {
        /* Got `~something'.  Restart from this point and insert that
           user's home directory. */
        astr as = astr_new();
        astr_truncate(epath, 0);
        ++sp;
        while (*sp != '\0' && *sp != '/')
          astr_cat_char(as, *sp++);
        pw = getpwnam(astr_cstr(as));
        astr_delete(as);
        if (pw == NULL) {
          ret = FALSE;
          break;
        }
        astr_cat_cstr(epath, pw->pw_dir);
      }
    } else if (*sp == '.') {
      if (*(sp + 1) == '/' || *(sp + 1) == '\0') {
        ++sp;
        if (*sp == '/' && *(sp + 1) != '/')
          ++sp;
      } else if (*(sp + 1) == '.' &&
                 (*(sp + 2) == '/' || *(sp + 2) == '\0')) {
        if (astr_len(epath) >= 1 && *astr_char(epath, -1) == '/')
          astr_truncate(epath, -1);
        while (*astr_char(epath, -1) != '/' &&
               astr_len(epath) >= 1)
          astr_truncate(epath, -1);
        sp += 2;
        if (*sp == '/' && *(sp + 1) != '/')
          ++sp;
      } else
        goto got_component;
    } else {
      const char *p;
    got_component:
      p = sp;
      while (*p != '\0' && *p != '/')
        p++;
      if (*p == '\0') { /* Final filename */
        astr_cat_cstr(epath, sp);
        break;
      } else { /* Non-final directory */
        while (*sp != '/')
          astr_cat_char(epath, *sp++);
      }
    }
  }

  astr_cpy(path, epath);
  astr_delete(epath);

  if (!ret) {
    astr_delete(path);
    return NULL;
  }
  return path;
}