Esempio n. 1
0
astr variableDump(le *varlist)
{
  astr as = astr_new();

  for (; varlist; varlist = varlist->list_next) {
    if (varlist->branch) {
      astr_afmt(as, "%s \t", varlist->data);
      astr_cat_delete(as, leDumpReformat(varlist->branch));
      astr_cat_char(as, '\n');
    }
  }

  return as;
}
Esempio n. 2
0
/*
 * Convert a key code sequence into a key code sequence string.
 */
astr keyvectostr(size_t *keys, size_t numkeys)
{
    size_t i;
    astr as = astr_new();

    for (i = 0; i < numkeys; i++) {
        astr key = chordtostr(keys[i]);
        astr_cat(as, key);
        astr_delete(key);
        if (i < numkeys - 1)
            astr_cat_char(as, ' ');
    }

    return as;
}
Esempio n. 3
0
static void draw_status_line(size_t line, Window *wp)
{
  size_t i;
  char *buf, *eol_type;
  Point pt = window_pt(wp);
  astr as, bs;

  term_attrset(1, FONT_REVERSE);

  term_move(line, 0);
  for (i = 0; i < wp->ewidth; ++i)
    term_addch('-');

  if (cur_bp->eol == coding_eol_cr)
    eol_type = "(Mac)";
  else if (cur_bp->eol == coding_eol_crlf)
    eol_type = "(DOS)";
  else
    eol_type = ":";
    
  term_move(line, 0);
  bs = astr_afmt(astr_new(), "(%d,%d)", pt.n+1, get_goalc_wp(wp));
  as = astr_afmt(astr_new(), "--%s%2s  %-15s   %s %-9s (Text",
                 eol_type, make_mode_line_flags(wp), wp->bp->name,
                 make_screen_pos(wp, &buf), astr_cstr(bs));
  free(buf);
  astr_delete(bs);

  if (wp->bp->flags & BFLAG_AUTOFILL)
    astr_cat_cstr(as, " Fill");
  if (wp->bp->flags & BFLAG_OVERWRITE)
    astr_cat_cstr(as, " Ovwrt");
  if (thisflag & FLAG_DEFINING_MACRO)
    astr_cat_cstr(as, " Def");
  if (wp->bp->flags & BFLAG_ISEARCH)
    astr_cat_cstr(as, " Isearch");

  astr_cat_char(as, ')');
  term_addnstr(astr_cstr(as), min(term_width(), astr_len(as)));
  astr_delete(as);

  term_attrset(1, FONT_NORMAL);
}
Esempio n. 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;
}
Esempio n. 5
0
/*
 * Convert a key like "\\C-xrs" to "C-x r s"
 */
astr simplify_key(char *key)
{
    int i, j;
    size_t *keys;
    astr dest = astr_new();

    if (key == NULL)
        return dest;
    i = keystrtovec(key, &keys);
    for (j = 0; j < i; j++) {
        astr as;
        if (j > 0)
            astr_cat_char(dest, ' ');
        as = chordtostr(keys[j]);
        astr_cat(dest, as);
        astr_delete(as);
    }
    if (i > 0)
        free(keys);

    return dest;
}
Esempio n. 6
0
static void
draw_status_line (size_t line, Window wp)
{
  term_attrset (FONT_REVERSE);

  term_move (line, 0);
  for (size_t i = 0; i < get_window_ewidth (wp); ++i)
    term_addstr ("-");

  const char *eol_type;
  if (get_buffer_eol (cur_bp) == coding_eol_cr)
    eol_type = "(Mac)";
  else if (get_buffer_eol (cur_bp) == coding_eol_crlf)
    eol_type = "(DOS)";
  else
    eol_type = ":";

  term_move (line, 0);
  size_t n = offset_to_line (get_window_bp (wp), window_o (wp));
  astr as = astr_fmt ("--%s%2s  %-15s   %s %-9s (Fundamental",
                      eol_type, make_mode_line_flags (wp), get_buffer_name (get_window_bp (wp)),
                      make_screen_pos (wp), astr_cstr (astr_fmt ("(%zu,%zu)", n + 1,
                                                                 get_goalc_bp (get_window_bp (wp), window_o (wp)))));

  if (get_buffer_autofill (get_window_bp (wp)))
    astr_cat_cstr (as, " Fill");
  if (thisflag & FLAG_DEFINING_MACRO)
    astr_cat_cstr (as, " Def");
  if (get_buffer_isearch (get_window_bp (wp)))
    astr_cat_cstr (as, " Isearch");

  astr_cat_char (as, ')');
  term_addstr (astr_cstr (as));

  term_attrset (FONT_NORMAL);
}
Esempio n. 7
0
File: file.c Progetto: M1lan/zile
/*
 * 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.
 *
 * The return value indicates success or failure.
 */
bool
expand_path (astr path)
{
  int ok = true;
  const char *sp = astr_cstr (path);
  astr epath = astr_new ();

  if (*sp != '/' && *sp != '~')
    {
      astr_cat (epath, agetcwd ());
      if (astr_len (epath) == 0 ||
          astr_get (epath, astr_len (epath) - 1) != '/')
        astr_cat_char (epath, '/');
    }

  for (const char *p = sp; *p != '\0';)
    {
      if (*p == '/')
        {
          if (*++p == '/')
            { /* Got `//'.  Restart from this point. */
              while (*p == '/')
                p++;
              astr_truncate (epath, 0);
            }
          if (astr_len (epath) == 0 ||
              astr_get (epath, astr_len (epath) - 1) != '/')
            astr_cat_char (epath, '/');
        }
      else if (*p == '~' && (p == sp || p[-1] == '/'))
        { /* Got `/~' or leading `~'.  Restart from this point. */
          struct passwd *pw;

          astr_truncate (epath, 0);
          ++p;

          if (*p == '/')
            { /* Got `~/'.  Insert the user's home directory. */
              pw = getpwuid (getuid ());
              if (pw == NULL)
                {
                  ok = false;
                  break;
                }
              if (!STREQ (pw->pw_dir, "/"))
                astr_cat_cstr (epath, pw->pw_dir);
            }
          else
            { /* Got `~something'.  Insert that user's home directory. */
              astr as = astr_new ();
              while (*p != '\0' && *p != '/')
                astr_cat_char (as, *p++);
              pw = getpwnam (astr_cstr (as));
              if (pw == NULL)
                {
                  ok = false;
                  break;
                }
              astr_cat_cstr (epath, pw->pw_dir);
            }
        }
      else if (*p == '.' && (p[1] == '/' || p[1] == '\0'))
        { /* Got `.'. */
          ++p;
        }
      else if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0'))
        { /* Got `..'. */
          if (astr_len (epath) >= 1 && astr_get (epath, astr_len (epath) - 1) == '/')
            astr_truncate (epath, astr_len (epath) - 1);
          while (astr_get (epath, astr_len (epath) - 1) != '/' && astr_len (epath) >= 1)
            astr_truncate (epath, astr_len (epath) - 1);
          p += 2;
        }

      if (*p != '~')
        while (*p != '\0' && *p != '/')
          astr_cat_char (epath, *p++);
    }

  astr_cpy (path, epath);

  return ok;
}
Esempio n. 8
0
/*
 * Convert a key chord into its ASCII representation
 */
astr chordtostr(size_t key)
{
    astr as = astr_new();

    if (key & KBD_CTRL)
        astr_cat_cstr(as, "C-");
    if (key & KBD_META)
        astr_cat_cstr(as, "M-");
    key &= ~(KBD_CTRL | KBD_META);

    switch (key) {
    case KBD_PGUP:
        astr_cat_cstr(as, "<prior>");
        break;
    case KBD_PGDN:
        astr_cat_cstr(as, "<next>");
        break;
    case KBD_HOME:
        astr_cat_cstr(as, "<home>");
        break;
    case KBD_END:
        astr_cat_cstr(as, "<end>");
        break;
    case KBD_DEL:
        astr_cat_cstr(as, "<delete>");
        break;
    case KBD_BS:
        astr_cat_cstr(as, "<backspace>");
        break;
    case KBD_INS:
        astr_cat_cstr(as, "<insert>");
        break;
    case KBD_LEFT:
        astr_cat_cstr(as, "<left>");
        break;
    case KBD_RIGHT:
        astr_cat_cstr(as, "<right>");
        break;
    case KBD_UP:
        astr_cat_cstr(as, "<up>");
        break;
    case KBD_DOWN:
        astr_cat_cstr(as, "<down>");
        break;
    case KBD_RET:
        astr_cat_cstr(as, "<RET>");
        break;
    case KBD_TAB:
        astr_cat_cstr(as, "<TAB>");
        break;
    case KBD_F1:
        astr_cat_cstr(as, "<f1>");
        break;
    case KBD_F2:
        astr_cat_cstr(as, "<f2>");
        break;
    case KBD_F3:
        astr_cat_cstr(as, "<f3>");
        break;
    case KBD_F4:
        astr_cat_cstr(as, "<f4>");
        break;
    case KBD_F5:
        astr_cat_cstr(as, "<f5>");
        break;
    case KBD_F6:
        astr_cat_cstr(as, "<f6>");
        break;
    case KBD_F7:
        astr_cat_cstr(as, "<f7>");
        break;
    case KBD_F8:
        astr_cat_cstr(as, "<f8>");
        break;
    case KBD_F9:
        astr_cat_cstr(as, "<f9>");
        break;
    case KBD_F10:
        astr_cat_cstr(as, "<f10>");
        break;
    case KBD_F11:
        astr_cat_cstr(as, "<f11>");
        break;
    case KBD_F12:
        astr_cat_cstr(as, "<f12>");
        break;
    case ' ':
        astr_cat_cstr(as, "SPC");
        break;
    default:
        if (isgraph(key))
            astr_cat_char(as, (int)(key & 0xff));
        else
            astr_afmt(as, "<%x>", key);
    }

    return as;
}
Esempio n. 9
0
/*
 * Read the file contents into a buffer.
 * Return quietly if the file doesn't exist, or other error.
 */
void read_from_disk(const char *filename)
{
  Line *lp;
  FILE *fp;
  int i, size, first_eol = TRUE;
  char *this_eol_type;
  size_t eol_len = 0, total_eols = 0;
  char buf[BUFSIZ];

  if ((fp = fopen(filename, "r")) == NULL) {
    if (errno != ENOENT) {
      minibuf_write("%s: %s", filename, strerror(errno));
      cur_bp->flags |= BFLAG_READONLY;
    }
    return;
  }

#if HAVE_UNISTD_H
  if (!check_writable(filename))
    cur_bp->flags |= BFLAG_READONLY;
#endif
  
  lp = cur_bp->pt.p;

  /* Read first chunk and determine EOL type. */
  if ((size = fread(buf, 1, BUFSIZ, fp)) > 0) {
    for (i = 0; i < size && total_eols < MAX_EOL_CHECK_COUNT; i++) {
      if (buf[i] == '\n' || buf[i] == '\r') {
        total_eols++;
        if (buf[i] == '\n')
          this_eol_type = coding_eol_lf;
        else if (i >= size || buf[i + 1] != '\n')
          this_eol_type = coding_eol_cr;
        else {
          this_eol_type = coding_eol_crlf;
          i++;
        }
        
        if (first_eol) {
          /* This is the first end-of-line. */
          cur_bp->eol = this_eol_type;
          first_eol = FALSE;
        } else if (cur_bp->eol != this_eol_type) {
          /* This EOL is different from the last; arbitrarily choose
             LF. */
          cur_bp->eol = coding_eol_lf;
          break;
        }
      }
    }
    
    /* Process this and subsequent chunks into lines. */
    eol_len = strlen(cur_bp->eol);
    do {
      for (i = 0; i < size; i++) {
        if (strncmp(cur_bp->eol, buf + i, eol_len) != 0)
          astr_cat_char(lp->item, buf[i]);
        else {
          lp = list_prepend(lp, astr_new());
          ++cur_bp->num_lines;
          i += eol_len - 1;
        }
      }
    } while ((size = fread(buf, 1, BUFSIZ, fp)) > 0);
  }

  list_next(lp) = cur_bp->lines;
  list_prev(cur_bp->lines) = lp;
  cur_bp->pt.p = list_next(cur_bp->lines);

  fclose(fp);
}
Esempio n. 10
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;
}
Esempio n. 11
0
static astr snagAToken(getcCallback getachar, ungetcCallback ungetachar, enum tokenname *tokenid)
{
  int c;
  int doublequotes = 0;
  astr tok = astr_new();

  *tokenid = T_EOF;

  /* Chew space to next token */
  do {
    c = getachar();

    /* Munch comments */
    if (c == ';')
      do {
        c = getachar();
      } while (c != EOF && c != '\n');
  } while (c != EOF && (c == ' ' || c == '\t'));

  /* Snag token */
  if (c == '(') {
    *tokenid = T_OPENPAREN;
    return tok;
  } else if (c == ')') {
    *tokenid = T_CLOSEPAREN;
    return tok;
  } else if (c == '\'') {
    *tokenid = T_QUOTE;
    return tok;
  } else if (c == '\n') {
    *tokenid = T_NEWLINE;
    return tok;
  } else if (c == EOF) {
    *tokenid = T_EOF;
    return tok;
  }

  /* It looks like a string. Snag to the next whitespace. */
  if (c == '\"') {
    doublequotes = 1;
    c = getachar();
  }

  while (1) {
    astr_cat_char(tok, (char)c);

    if (!doublequotes) {
      if (c == ')' || c == '(' || c == ';' || c == ' ' || c == '\n' || c == '\r' || c == EOF) {
        ungetachar(c);
        astr_truncate(tok, (ptrdiff_t)-1);

        if (!astr_cmp_cstr(tok, "quote")) {
          *tokenid = T_QUOTE;
          return tok;
        }
        *tokenid = T_WORD;
        return tok;
      }
    } else {
      switch (c) {
      case '\n':
      case '\r':
      case EOF:
        ungetachar(c);
        /* Fall through */

      case '\"':
        astr_truncate(tok, (ptrdiff_t)-1);
        *tokenid = T_WORD;
        return tok;

      }
    }

    c = getachar();
  }

  return tok;
}