Пример #1
0
struct hl_line_attr *hl_regex_highlight(struct hl_regex_info **info,
        char *line, enum hl_group_kind group_kind)
{
    hl_line_attr *attrs = NULL;

    if (*info && (*info)->regex && (*info)->regex[0]) {
        int pos = 0;

        for (;;) {
            int ret;
            int len;
            int start, end;

            ret = hl_regex_search(info, line + pos, (*info)->regex, (*info)->icase, &start, &end);
            if (ret <= 0)
                break;

            len = end - start;
            pos += start;

            /* Push search attribute */
            sbpush(attrs, hl_line_attr(pos, group_kind));

            /* And the back to regular text attribute */
            sbpush(attrs, hl_line_attr(pos + len, 0));

            pos += len;
        }
    }

    return attrs;
}
Пример #2
0
static char *detab_buffer(char *buffer, int tabstop)
{
    int i;
    int dst = 0;
    char *newbuf = NULL;
    int size = sbcount(buffer);

    char *tab = strchr(buffer, '\t');
    if (!tab)
        return buffer;

    for (i = 0; i < size; i++) {
        if (buffer[i] == '\t') {
            int spaces = tabstop - dst % tabstop;

            while(spaces--) {
                sbpush(newbuf, ' ');
                dst++;
            }
        } else {
            sbpush(newbuf, buffer[i]);
            dst++;
        }

        if (buffer[i] == '\n' || buffer[i] == '\r')
            dst = 0;
    }

    sbfree(buffer);
    return newbuf;
}
Пример #3
0
void source_add_disasm_line(struct list_node *node, const char *line)
{
    uint64_t addr = 0;
    struct source_line sline;
    char *colon = 0, colon_char = 0;

    sline.line = NULL;
    sbsetcount(sline.line, strlen(line) + 1);
    strcpy(sline.line, line);
    sline.line = detab_buffer(sline.line, node->file_buf.tabstop);

    sline.attrs = NULL;
    sline.len = sbcount(sline.line);

    colon = strchr((char*)line, ':');
    if (colon) {
        colon_char = *colon;
        *colon = 0;
    }

    cgdb_hexstr_to_u64(line, &addr);

    if (colon) {
        *colon = colon_char;
    }

    sbpush(node->file_buf.addrs, addr);

    struct line_flags lf = { 0, 0 };
    sbpush(node->file_buf.lines, sline);
    sbpush(node->lflags, lf);
}
Пример #4
0
static int
lua_cwd(lua_State *L)
{
#ifdef _WIN32

  char drv[2];
  int l;
  SB sb;
  sbinit(&sb);
  drv[0] = '.'; drv[1] = 0;
  l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
  if (l > sb.maxlen) {
    sbgrow(&sb, l+1);
    l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
  }
  if (l <= 0)
    return sbsetpush(L, &sb, ".");
  sb.len += l;
  return sbpush(L, &sb);

#elif HAVE_GETCWD
  
  const char *s;
  SB sb;
  sbinit(&sb);
  s = getcwd(sb.buffer, sb.maxlen);
  while (!s && errno==ERANGE)
    {
      sbgrow(&sb, sb.maxlen + SBINCREMENT);
      s = getcwd(sb.buffer, sb.maxlen);
    }
  if (! s)
    return sbsetpush(L, &sb, ".");
  sb.len += strlen(s);
  return sbpush(L, &sb);

#else
  
  const char *s;
  SB sb;
  sbinit(&sb);
  sbgrow(&sb, PATH_MAX); 
  s = getwd(sb.buffer);
  if (! s)
    return sbsetpush(L, &sb, ".");
  sb.len += strlen(s);
  return sbpush(L, &sb);

#endif
}
Пример #5
0
static void scroller_addline(struct scroller *scr, char *line,
    struct hl_line_attr *attrs, enum ScrInputKind kind)
{
    struct scroller_line sl;

    /* Add attribute from last inferior line to start of this one */
    if (kind == SCR_INPUT_INFERIOR && (scr->last_inferior_attr != -1)) {
        /* If there isn't already a color attribute for the first column */
        if (!attrs || (attrs[0].col() != 0)) {
            int count = sbcount(attrs);

            /* Bump the count up and scoot the attributes over one */
            sbsetcount(attrs, count + 1);
            memmove(attrs+1, attrs, count * sizeof(struct hl_line_attr));

            attrs[0] = hl_line_attr(0, scr->last_inferior_attr);
        }

        scr->last_inferior_attr = -1;
    }

    sl.line = line;
    sl.line_len = strlen(line);
    sl.kind = kind;
    sl.attrs = attrs;
    sbpush(scr->lines, sl);

    scr->lines_to_display++;

    scroller_set_last_inferior_attr(scr);
}
Пример #6
0
int highlight_node(const char *filename, struct buffer *buf)
{
    int ret;
    int length = 0;
    int lasttype = -1;
    struct ibuf *ibuf = ibuf_init();
    struct tokenizer *t = tokenizer_init();

    if (tokenizer_set_file(t, filename, buf->language) == -1) {
        if_print_message("%s:%d tokenizer_set_file error", __FILE__, __LINE__);
        return -1;
    }

    while ((ret = tokenizer_get_token(t)) > 0) {
        enum tokenizer_type e = tokenizer_get_packet_type(t);

        /*if_print_message  ( "TOKEN(%d:%s)\n", e, tokenizer_get_printable_enum ( e ) ); */

        if (e == TOKENIZER_NEWLINE) {
            sbpush(buf->tlines, strdup(ibuf_get(ibuf)));

            if (length > buf->max_width)
                buf->max_width = length;

            length = 0;
            lasttype = -1;
            ibuf_clear(ibuf);
        } else {
            const char *tok_data = tokenizer_get_data(t);
            enum hl_group_kind hlg = hlg_from_tokenizer_type(e, tok_data);

            if (hlg == HLG_LAST) {
                logger_write_pos(logger, __FILE__, __LINE__, "Bad hlg_type for '%s', e==%d\n", tok_data, e);
                hlg = HLG_TEXT;
            }

            /* Set the highlight group type */
            add_type(ibuf, &lasttype, hlg);
            /* Add the text and bump our length */
            length += ibuf_add(ibuf, tok_data);
        }
    }

    ibuf_free(ibuf);
    tokenizer_destroy(t);
    return 0;
}
Пример #7
0
char *sys_quote_nonprintables(const char *str, int len)
{
    int i;
    char *ret = NULL;

    if (len == -1)
        len = strlen(str);

    /* Nil terminate our return string */
    sbpush(ret, 0);

    for (i = 0; i < len; ++i)
    {
        const char *ch = NULL;

        if (str[i] == '\r')
            ch = "\\r";
        else if (str[i] == '\n')
            ch = "\\n";
        else if (str[i] == '\032')
            ch = "\\032";
        else if (str[i] == '\033')
            ch = "\\033";
        else if (str[i] == '\b')
            ch = "\\b";
        else if (str[i] == '\t')
            ch = "\\t";

        if (ch)
            sbpushstrf(&ret, "(%s)", ch);
        else
            sbpushstr(&ret, &str[i], 1);
    }

    return ret;
}
Пример #8
0
static int highlight_node(struct list_node *node)
{
    int i;
    int ret;
    int line = 0;
    int length = 0;
    int lasttype = -1;
    struct token_data tok_data;
    struct tokenizer *t = tokenizer_init();
    struct buffer *buf = &node->file_buf;

    for (i = 0; i < sbcount(buf->lines); i++) {
        sbfree(buf->lines[i].attrs);
        buf->lines[i].attrs = NULL;
    }

    if (!buf->file_data) {
        for (line = 0; line < sbcount(buf->lines); line++) {
            struct source_line *sline = &buf->lines[line];

            tokenizer_set_buffer(t, sline->line, buf->language);

            length = 0;
            lasttype = -1;
            while ((ret = tokenizer_get_token(t, &tok_data)) > 0) {
                if (tok_data.e == TOKENIZER_NEWLINE)
                    break;

                enum hl_group_kind hlg = hlg_from_tokenizer_type(tok_data.e, tok_data.data);

                /* Add attribute if highlight group has changed */
                if (lasttype != hlg) {
                    sbpush(buf->lines[line].attrs, hl_line_attr(length, hlg));

                    lasttype = hlg;
                }

                /* Add the text and bump our length */
                length += strlen(tok_data.data);
            }
        }

    } else {
        if (tokenizer_set_buffer(t, buf->file_data, buf->language) == -1) {
            if_print_message("%s:%d tokenizer_set_buffer error", __FILE__, __LINE__);
            return -1;
        }

        while ((ret = tokenizer_get_token(t, &tok_data)) > 0) {
            if (tok_data.e == TOKENIZER_NEWLINE) {
                if (length > buf->max_width)
                    buf->max_width = length;

                length = 0;
                lasttype = -1;
                line++;
            } else {
                enum hl_group_kind hlg = hlg_from_tokenizer_type(tok_data.e, tok_data.data);

                if (hlg == HLG_LAST) {
                    clog_error(CLOG_CGDB, "Bad hlg_type for '%s', e==%d\n", tok_data.data, tok_data.e);
                    hlg = HLG_TEXT;
                }

                /* Add attribute if highlight group has changed */
                if (lasttype != hlg) {
                    sbpush(buf->lines[line].attrs, hl_line_attr(length, hlg));

                    lasttype = hlg;
                }

                /* Add the text and bump our length */
                length += strlen(tok_data.data);
            }
        }
    }

    tokenizer_destroy(t);
    return 0;
}
Пример #9
0
/**
 * Load file and fill tlines line pointers.
 *
 * \param buf
 * struct buffer pointer
 *
 * \param filename
 * name of file to load
 *
 * \return
 * 0 on sucess, -1 on error
 */
static int load_file_buf(struct buffer *buf, const char *filename)
{
    FILE *file;
    long file_size;
    int ret = -1;

    /* Special buffer not backed by file */
    if (filename[0] == '*')
        return 0;

    file = fopen(filename, "rb");
    if (!file)
        return -1;

    file_size = get_file_size(file);
    if (file_size > 0) {
        size_t bytes_read;

        /* Set the stretchy buffer size to our file size plus one for nil */
        sbsetcount(buf->file_data, file_size + 1);

        /* Read in the entire file */
        bytes_read = fread(buf->file_data, 1, file_size, file);

        /* If we had a partial read, bail */
        if (bytes_read != file_size) {
            sbfree(buf->file_data);
            buf->file_data = NULL;

            fclose(file);
            return -1;
        }

        /* Zero terminate buffer */
        buf->file_data[bytes_read] = 0;

        /* Convert tabs to spaces */
        buf->tabstop = cgdbrc_get_int(CGDBRC_TABSTOP);
        buf->file_data = detab_buffer(buf->file_data, buf->tabstop);

        {
            char *line_start = buf->file_data;
            char *line_feed = strchr(line_start, '\n');

            while (line_feed)
            {
                size_t line_len;
                char *line_end = line_feed;

                /* Trim trailing cr-lfs */
                while (line_end >= line_start && (*line_end == '\n' || *line_end == '\r'))
                    line_end--;

                /* Update max length string found */
                line_len = line_end - line_start + 1;
                if (line_len > buf->max_width)
                    buf->max_width = line_len;

                struct source_line sline;
                sline.line = line_start;
                sline.len = line_len;
                sline.attrs = NULL;

                /* Add this line to lines array */
                sbpush(buf->lines, sline);

                line_start = line_feed + 1;
                line_feed = strchr(line_start, '\n');
            }

            if (*line_start) {
                struct source_line sline;
                sline.line = line_start;
                sline.len = strlen(line_start);
                sline.attrs = NULL;

                sbpush(buf->lines, sline);
            }

            ret = 0;
        }
    }

    fclose(file);
    return ret;
}
Пример #10
0
/* parse: Translates special characters in a string.  (i.e. backspace, tab...)
 * ------
 *
 *   buf:  The string to parse
 *
 * Return Value:  A newly allocated copy of buf, with modifications made.
 */
static char *parse(struct scroller *scr, struct hl_line_attr **attrs,
    const char *orig, const char *buf, int buflen, enum ScrInputKind kind)
{
    // Read in tabstop settings, but don't change them on the fly as we'd have to
    //  store each previous line and recalculate every one of them.
    static const int tab_size = cgdbrc_get_int(CGDBRC_TABSTOP);
    int tabcount = count(buf, buflen, '\t');
    int orig_len = strlen(orig);
    int length = MAX(orig_len, scr->current.pos) + buflen +
        (tab_size - 1) * tabcount + 1;
    char *rv = (char *) cgdb_calloc(length, 1);
    int i, j;
    int debugwincolor = cgdbrc_get_int(CGDBRC_DEBUGWINCOLOR);
    int width, height;

    height = swin_getmaxy(scr->win);
    width = swin_getmaxx(scr->win);

    /* Copy over original buffer */
    strcpy(rv, orig);

    i = scr->current.pos;

    /* Expand special characters */
    for (j = 0; j < buflen; j++) {
        switch (buf[j]) {
                /* Backspace/Delete -> Erase last character */
            case 8:
            case 127:
                if (i > 0)
                    i--;
                break;
                /* Tab -> Translating to spaces */
            case '\t':
                do {
                    rv[i++] = ' ';
                } while (i % tab_size != 0);
                break;
                /* Carriage return -> Move back to the beginning of the line */
            case '\r':
                i = 0;
                if (buf[j + 1] != '\n') {
                    sbfree(*attrs);
                    *attrs = NULL;
                }
                break;
            case '\033':
                /* Handle ansi escape characters */
                if (hl_ansi_color_support(hl_groups_instance) &&
                    debugwincolor) {
                    int attr;
                    int ansi_count = hl_ansi_get_color_attrs(
                            hl_groups_instance, buf + j, &attr);
                    if (ansi_count) {
                        j += ansi_count - 1;
                        sbpush(*attrs, hl_line_attr(i, attr));
                    }
                } else {
                    rv[i++] = buf[j];
                }
                break;
            default:
                rv[i++] = buf[j];
                break;
        }
    }

    scr->current.pos = i;

    /**
     * The prompt should never be longer than the width of the terminal.
     *
     * The below should only be done for the readline prompt interaction,
     * not for text coming from gdb/inferior. Otherwise you'll truncate
     * their text in the scroller!
     *
     * When readline is working with the prompt (at least in "dumb" mode)
     * it assumes that the terminal will only display as many characters as
     * the terminal is wide. If the terminal is reduced in size (resized to a
     * smaller width) readline will only clear the number of characters
     * that will fit into the new terminal width. Our prompt may still
     * have a lot more characters than that (the characters that existed
     * in the prompt before the resize). This truncation of the prompt
     * is solving that problem.
     */
    size_t rvlength = strlen(rv);
    if (kind == SCR_INPUT_READLINE && rvlength >= width) {
        rv[width - 1] = 0;
    }

    return rv;
}
Пример #11
0
static void scr_add_buf(struct scroller *scr, const char *buf,
    enum ScrInputKind kind)
{
    char *x;
    int distance;

    /* Find next newline in the string */
    x = strchr((char *)buf, '\n');
    distance = x ? x - buf : strlen(buf);

    /* Append to the last line in the buffer */
    if (distance > 0) {
        int is_crlf = (distance == 1) && (buf[0] == '\r');
        if (!is_crlf) {
            int index = sbcount(scr->lines) - 1;
            char *orig = scr->lines[index].line;
            int orig_len = scr->lines[index].line_len;

            if ((scr->last_inferior_attr != -1) &&
                    (kind != scr->lines[index].kind)) {
                /* Default to 0: Add that color attribute in */
                int attr = 0;

                if (kind == SCR_INPUT_INFERIOR) {
                    attr = scr->last_inferior_attr;
                    scr->last_inferior_attr = -1;
                }

                sbpush(scr->lines[index].attrs, hl_line_attr(orig_len, attr));
            }

            scr->lines[index].kind = kind;
            scr->lines[index].line = parse(
                scr, &scr->lines[index].attrs, orig, buf, distance, kind);
            scr->lines[index].line_len = strlen(scr->lines[index].line);

            scroller_set_last_inferior_attr(scr);

            free(orig);
        }
    }

    /* Create additional lines if buf contains newlines */
    while (x != NULL) {
        char *line;
        struct hl_line_attr *attrs = NULL;

        buf = x + 1;
        x = strchr((char *)buf, '\n');
        distance = x ? x - buf : strlen(buf);

        /* inferior input with no lf. */
        if (!x && (kind == SCR_INPUT_INFERIOR) && distance && (distance < 4096)) {
            /* Store away and parse when the rest of the line shows up */
            scr->last_inferior_line = strdup(buf);
            /* Add line since we did have a lf */
            scr->current.pos = 0;
            scroller_addline(scr, strdup(""), NULL, kind);
            break;
        }

        /* Expand the buffer */
        scr->current.pos = 0;

        /* Add the new line */
        line = parse(scr, &attrs, "", buf, distance, kind);
        scroller_addline(scr, line, attrs, kind);
    }

    /* Don't want to exit scroll mode simply because new data received */
    if (!scr->in_scroll_mode) {
        scr_end(scr);
    }
}
Пример #12
0
static int 
lua_basename(lua_State *L)
{
  const char *fname = luaL_checkstring(L, 1);
  const char *suffix = luaL_optstring(L, 2, 0);

#ifdef _WIN32

  int sl;
  const char *p, *s;
  SB sb;
  sbinit(&sb);
  /* Special cases */
  if (fname[0] && fname[1]==':') {
    sbaddn(&sb, fname, 2);
    fname += 2;
    if (fname[0]=='/' || fname[0]=='\\')
      sbadd1(&sb, '/');
    while (fname[0]=='/' || fname[0]=='\\')
      fname += 1;
    if (fname[0]==0)
      return sbpush(L, &sb);
    sb.len = 0;
  }
  /* Position p after last nontrivial slash */
  s = p = fname;
  while (*s) {
    if ((s[0]=='\\' || s[0]=='/') &&
        (s[1] && s[1]!='/' && s[1]!='\\' ) )
      p = s + 1;
    s++;
  }
  /* Copy into buffer */
  while (*p && *p!='/' && *p!='\\')
    sbadd1(&sb, *p++);
  /* Process suffix */
  if (suffix==0 || suffix[0]==0)
    return sbpush(L, &sb);
  if (suffix[0]=='.')
    suffix += 1;
  if (suffix[0]==0)
    return sbpush(L, &sb);
  sl = strlen(suffix);
  if (sb.len > sl) {
    s =  sb.buffer + sb.len - (sl + 1);
    if (s[0]=='.' && _strnicmp(s+1,suffix, sl)==0)
      sb.len = s - sb.buffer;
  }
  return sbpush(L, &sb);
  
#else

  int sl;
  const char *s, *p;
  SB sb;
  sbinit(&sb);
  /* Position p after last nontrivial slash */
  s = p = fname;
  while (*s) {
    if (s[0]=='/' && s[1] && s[1]!='/')
      p = s + 1;
    s++;
  }
  /* Copy into buffer */
  while (*p && *p!='/')
    sbadd1(&sb, *p++);
  /* Process suffix */
  if (suffix==0 || suffix[0]==0)
    return sbpush(L, &sb);
  if (suffix[0]=='.')
    suffix += 1;
  if (suffix[0]==0)
    return sbpush(L, &sb);
  sl = strlen(suffix);
  if (sb.len > sl) {
    s =  sb.buffer + sb.len - (sl + 1);
    if (s[0]=='.' && strncmp(s+1,suffix, sl)==0)
      sb.len = s - sb.buffer;
  }
  return sbpush(L, &sb);

#endif
}
Пример #13
0
static int 
concat_fname(lua_State *L, const char *fname)
{
  const char *from = lua_tostring(L, -1);

#ifdef _WIN32

  const char *s;
  SB sb;
  sbinit(&sb);
  sbaddn(&sb, from, strlen(from));
  if (fname==0)
    return sbpush(L, &sb);
  /* Handle absolute part of fname */
  if (fname[0]=='/' || fname[0]=='\\') {
    if (fname[1]=='/' || fname[1]=='\\') {
      sb.len = 0;                            /* Case //abcd */
      sbaddn(&sb, "//", 2);
    } else {
      char drive;
      if (sb.len >= 2 && sb.buffer[1]==':'   /* Case "/abcd" */
          && isalpha((unsigned char)(sb.buffer[0])) )
        drive = sb.buffer[0];
      else
        drive = _getdrive() + 'A' - 1;
      sb.len = 0;
      sbadd1(&sb, drive);
      sbaddn(&sb, ":/", 2);
    }
  } else if (fname[0] && 	              /* Case "x:abcd"   */
             isalpha((unsigned char)(fname[0])) && fname[1]==':') {
    if (fname[2]!='/' && fname[2]!='\\') {
      if (sb.len < 2 || sb.buffer[1]!=':' 
          || !isalpha((unsigned char)(sb.buffer[0]))
          || (toupper((unsigned char)sb.buffer[0]) !=
              toupper((unsigned char)fname[0]) ) ) 
        {
          int l;
          char drv[4];
          sb.len = 0;
          drv[0]=fname[0]; drv[1]=':'; drv[2]='.'; drv[3]=0;
          l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
          if (l > sb.maxlen) {
            sbgrow(&sb, l+1);
            l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
          }
          if (l <= 0)
            sbaddn(&sb, drv, 3);
          else
            sb.len += l;
        }
      fname += 2;
    } else {
      sb.len = 0;                              /* Case "x:/abcd"  */
      sbadd1(&sb, toupper((unsigned char)fname[0])); 
      sbaddn(&sb, ":/", 2);
      fname += 2;
      while (*fname == '/' || *fname == '\\')
        fname += 1;
    }
  }
  /* Process path components */
  for (;;)
  {
    while (*fname=='/' || *fname=='\\')
      fname ++;
    if (*fname == 0)
      return sbpush(L, &sb);
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]=='\\' || fname[1]==0) {
	fname += 1;
	continue;
      }
      if (fname[1]=='.')
        if (fname[2]=='/' || fname[2]=='\\' || fname[2]==0) {
          size_t l;
	  fname += 2;
          lua_pushcfunction(L, lua_dirname);
          sbpush(L, &sb);
          lua_call(L, 1, 1);
          s = lua_tolstring(L, -1, &l);
          sbinit(&sb);
          sbaddn(&sb, s, l);
          lua_pop(L, 1);
	  continue;
      }
    }
    if (sb.len==0 || 
        (sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\') )
      sbadd1(&sb, '/');
    while (*fname && *fname!='/' && *fname!='\\')
      sbadd1(&sb, *fname++);
  }
             
#else
  SB sb;
  sbinit(&sb);

  if (fname && fname[0]=='/') 
    sbadd1(&sb, '/');
  else
    sbaddn(&sb, from, strlen(from));
  for (;;) {
    while (fname && fname[0]=='/')
      fname++;
    if (!fname || !fname[0]) {
      sbadd1(&sb, '/');
      while (sb.len > 1 && sb.buffer[sb.len-1]=='/')
        sb.len --;
      return sbpush(L, &sb);
    }
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]==0) {
	fname +=1;
	continue;
      }
      if (fname[1]=='.')
	if (fname[2]=='/' || fname[2]==0) {
	  fname +=2;
          while (sb.len > 0 && sb.buffer[sb.len-1]=='/')
            sb.len --;
          while (sb.len > 0 && sb.buffer[sb.len-1]!='/')
            sb.len --;
	  continue;
	}
    }
    if (sb.len == 0 || sb.buffer[sb.len-1] != '/')
      sbadd1(&sb, '/');
    while (*fname!=0 && *fname!='/')
      sbadd1(&sb, *fname++);
  }
  
  
#endif

}
Пример #14
0
static int 
lua_dirname(lua_State *L)
{
  const char *fname = luaL_checkstring(L, 1);

#ifdef _WIN32

  const char *s;
  const char *p;
  SB sb;
  sbinit(&sb);
  /* Handle leading drive specifier */
  if (isalpha((unsigned char)fname[0]) && fname[1]==':') {
    sbadd1(&sb, *fname++);
    sbadd1(&sb, *fname++);
  }
  /* Search last non terminal / or \ */
  p = 0;
  s = fname;
  while (*s) {
    if ((s[0]=='\\' || s[0]=='/') &&
        (s[1] && s[1]!='/' && s[1]!='\\') )
      p = s;
    s++;
  }
  /* Cannot find non terminal / or \ */
  if (p == 0) {
    if (sb.len > 0) {
      if (fname[0]==0 || fname[0]=='/' || fname[0]=='\\')
	sbadd1(&sb, '/');
      return sbpush(L, &sb);
    } else {
      if (fname[0]=='/' || fname[0]=='\\')
	return sbsetpush(L, &sb, "//");
      else
	return sbsetpush(L, &sb, ".");
    }
  }
  /* Single leading slash */
  if (p == fname) {
    sbadd1(&sb, '/');
    return sbpush(L, &sb);
  }
  /* Backtrack all slashes */
  while (p>fname && (p[-1]=='/' || p[-1]=='\\'))
    p--;
  /* Multiple leading slashes */
  if (p == fname)
    return sbsetpush(L, &sb, "//");
  /* Regular case */
  s = fname;
  do {
    sbadd1(&sb, *s++);
  } while (s<p);
  return sbpush(L, &sb);

#else

  const char *s = fname;
  const char *p = 0;
  SB sb; 
  sbinit(&sb);
  while (*s) {
    if (s[0]=='/' && s[1] && s[1]!='/')
      p = s;
    s++;
  }
  if (!p) {
    if (fname[0]=='/')
      return sbsetpush(L, &sb, fname);
    else
      return sbsetpush(L, &sb, ".");
  }
  s = fname;
  do {
    sbadd1(&sb, *s++);
  } while (s<p);
  return sbpush(L, &sb);

#endif
}
Пример #15
0
int filedlg_add_file_choice(struct filedlg *fd, const char *file_choice)
{
    int length;
    int index, i;
    int equal = 1;              /* Not set to 0, because 0 *is* equal */

    if (file_choice == NULL || *file_choice == '\0')
        return -1;

    /* Make sure file exists. If temp files are used to create an
     * executable, and the temp files are deleted, they pollute the
     * file open dialog with files you can't actually open.
     *
     * The downside to not showing them all is that a user might
     * not understand why certain files aren't showing up. O well.
     */
    if (file_choice[0] != '*') {
        if (fs_verify_file_exists(file_choice) == 0)
            return -4;
    }

    /* find index to insert by comparing:
     * Absolute paths go to the end
     * Relative paths go before the absolute paths 
     */
    for (i = 0; i < sbcount(fd->buf->files); i++) {
        /* Don't add duplicate entry's ... gdb outputs duplicates */
        if ((equal = strcmp(fd->buf->files[i], file_choice)) == 0)
            return -3;
        else if (equal < 0) {
            /* Inserting filename, stop before relative path */
            if ((file_choice[0] != '.' && file_choice[0] != '/')
                    && fd->buf->files[i][0] == '.')
                break;

            /* Inserting filename, stop before absolute path */
            if (file_choice[0] != '/' && fd->buf->files[i][0] == '/')
                break;

        } else if (equal > 0) { /* Found ( file_choice is greater ) */
            /* Inserting Absolute path, it goes to the end */
            if (file_choice[0] == '/' && fd->buf->files[i][0] != '/')
                continue;

            /* Inserting relative path, continue until before absolute or relative path */
            if (file_choice[0] == '.' && (fd->buf->files[i][0] != '.'
                            && fd->buf->files[i][0] != '/'))
                continue;

            break;
        }
    }

    index = i;

    sbpush(fd->buf->files, NULL);

    /* shift everything down and then insert into index */
    for (i = sbcount(fd->buf->files) - 1; i > index; i--)
        fd->buf->files[i] = fd->buf->files[i - 1];

    fd->buf->files[index] = cgdb_strdup(file_choice);

    if ((length = strlen(file_choice)) > fd->buf->max_width)
        fd->buf->max_width = length;

    return 0;
}
Пример #16
0
/** 
 * Display the source.
 *
 * A line in the source viewer looks like,
 *   # │ marker text
 * where,
 *   # is the line number to display or ~ if no line number
 *   │ is the divider between the line number or it is a mark
 *   marker is shortarrow, longarrow, highlight, block, etc
 *   text is the source code to display
 *
 * The syntax highlighting works as follows,
 *
 * The #
 * - If breakpoint is set, use Breakpoint
 * - If breakpoint is disabled, use DisabledBreakpoint
 * - If selected line, use SelectedLineNr
 * - If executing line, use ExecutingLineNr
 * - Otherwise, no highlighting group
 *
 * The │ 
 * - When source window is in focus, the character is bolded, otherwise normal
 * - If the user has a mark set, the mark will be displayed instead of any
 *   other character.
 * - Edge case: When the marker is long or short arrow, CGDB prints ├
 *   instead of │ the ├ is colored based on highlighting group for 
 *   the selected or executing arrow.
 *
 * The marker
 * - The marker is the shortarrow, longarrow, highlight or block
 * - The color is based off the corresponding highlighting group
 *
 * The text
 * - The syntax highlighting source code to display
 * - Will be colored with SelectedLineHighlight or ExecutingLineHighlight
 *   if the line is the selected or executing line and the display is set
 *   to highlight.
 */
int source_display(struct sviewer *sview, int focus, enum win_refresh dorefresh)
{
    int i;
    int lwidth;
    int line;
    int count;

    enum LineDisplayStyle exe_display_style, sel_display_style;
    int sellineno, exelineno;
    int enabled_bp, disabled_bp;
    int exe_line_display_is_arrow, sel_line_display_is_arrow;
    int exe_arrow_attr, sel_arrow_attr;
    int exe_block_attr, sel_block_attr;
    char fmt[16];
    int width, height;
    int focus_attr = focus ? SWIN_A_BOLD : 0;
    int showmarks = cgdbrc_get_int(CGDBRC_SHOWMARKS);
    int hlsearch = cgdbrc_get_int(CGDBRC_HLSEARCH);
    int mark_attr;

    struct hl_line_attr *sel_highlight_attrs = 0;
    struct hl_line_attr *exe_highlight_attrs = 0;

    /* Check that a file is loaded */
    if (!sview->cur || !sview->cur->file_buf.lines) {
        logo_display(sview->win);

        if (dorefresh == WIN_REFRESH)
            swin_wrefresh(sview->win);
        else
            swin_wnoutrefresh(sview->win);

        return 0;
    }

    sellineno = hl_groups_get_attr(
        hl_groups_instance, HLG_SELECTED_LINE_NUMBER);
    exelineno = hl_groups_get_attr(
        hl_groups_instance, HLG_EXECUTING_LINE_NUMBER);
    enabled_bp = hl_groups_get_attr(
        hl_groups_instance, HLG_ENABLED_BREAKPOINT);
    disabled_bp = hl_groups_get_attr(
        hl_groups_instance, HLG_DISABLED_BREAKPOINT);

    exe_display_style = cgdbrc_get_displaystyle(CGDBRC_EXECUTING_LINE_DISPLAY);
    exe_arrow_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_EXECUTING_LINE_ARROW);
    exe_block_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_EXECUTING_LINE_BLOCK);

    sel_display_style = cgdbrc_get_displaystyle(CGDBRC_SELECTED_LINE_DISPLAY);
    sel_arrow_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_SELECTED_LINE_ARROW);
    sel_block_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_SELECTED_LINE_BLOCK);

    exe_line_display_is_arrow =
        exe_display_style == LINE_DISPLAY_SHORT_ARROW ||
        exe_display_style == LINE_DISPLAY_LONG_ARROW;
    sel_line_display_is_arrow = 
        sel_display_style == LINE_DISPLAY_SHORT_ARROW ||
        sel_display_style == LINE_DISPLAY_LONG_ARROW;

    mark_attr = hl_groups_get_attr(hl_groups_instance, HLG_MARK);

    sbpush(sel_highlight_attrs, hl_line_attr(0, HLG_SELECTED_LINE_HIGHLIGHT));
    sbpush(exe_highlight_attrs, hl_line_attr(0, HLG_EXECUTING_LINE_HIGHLIGHT));
    
    /* Make sure cursor is visible */
    swin_curs_set(!!focus);

    /* Initialize variables */
    height = swin_getmaxy(sview->win);
    width = swin_getmaxx(sview->win);

    /* Set starting line number (center source file if it's small enough) */
    count = sbcount(sview->cur->file_buf.lines);
    if (count < height) {
        line = (count - height) / 2;
    } else {
        line = sview->cur->sel_line - height / 2;
        if (line > count - height)
            line = count - height;
        else if (line < 0)
            line = 0;
    }

    /* Print 'height' lines of the file, starting at 'line' */
    lwidth = log10_uint(count) + 1;
    snprintf(fmt, sizeof(fmt), "%%%dd", lwidth);

    for (i = 0; i < height; i++, line++) {

        int column_offset = 0;
        /* Is this the current selected line? */
        int is_sel_line = (line >= 0 && sview->cur->sel_line == line);
        /* Is this the current executing line */
        int is_exe_line = (line >= 0 && sview->cur->exe_line == line);
        struct source_line *sline = (line < 0 || line >= count)?
            NULL:&sview->cur->file_buf.lines[line];
        struct hl_line_attr *printline_attrs = (sline)?sline->attrs:0;

        swin_wmove(sview->win, i, 0);

        /* Print the line number */
        if (line < 0 || line >= count) {
            for (int j = 1; j < lwidth; j++)
                swin_waddch(sview->win, ' ');
            swin_waddch(sview->win, '~');
        } else {
            int line_attr = 0;
            int bp_val = sview->cur->lflags[line].breakpt;
            if (bp_val == 1) {
                line_attr = enabled_bp;
            } else if (bp_val == 2) {
                line_attr = disabled_bp;
            } else if (bp_val == 0 && is_exe_line) {
                line_attr = exelineno;
            } else if (bp_val == 0 && is_sel_line) {
                line_attr = sellineno;
            }

            swin_wattron(sview->win, line_attr);
            swin_wprintw(sview->win, fmt, line + 1);
            swin_wattroff(sview->win, line_attr);
        }

        if (!swin_has_colors()) {
            /* TODO:
            swin_wprintw(sview->win, "%.*s\n",
                    sview->cur->file_buf.lines[line].line,
                    sview->cur->file_buf.lines[line].len);
            */
            continue;
        }

        /* Print the vertical bar or mark */
        {
            SWIN_CHTYPE vert_bar_char;
            int vert_bar_attr;
            int mc;

            if (showmarks &&
                ((mc = source_get_mark_char(sview, sview->cur, line)) > 0)) {
                vert_bar_char = mc;
                vert_bar_attr = mark_attr;
            } else if (is_exe_line && exe_line_display_is_arrow) {
                vert_bar_attr = exe_arrow_attr;
                vert_bar_char = SWIN_SYM_LTEE;
            } else if (is_sel_line && sel_line_display_is_arrow) {
                vert_bar_attr = sel_arrow_attr;
                vert_bar_char = SWIN_SYM_LTEE;
            } else {
                vert_bar_attr = focus_attr;
                vert_bar_char = SWIN_SYM_VLINE;
            }

            swin_wattron(sview->win, vert_bar_attr);
            swin_waddch(sview->win, vert_bar_char);
            swin_wattroff(sview->win, vert_bar_attr);
        }

        /* Print the marker */
        if (is_exe_line || is_sel_line) {
            enum LineDisplayStyle display_style;
            int arrow_attr, block_attr;
            struct hl_line_attr *highlight_attr;

            if (is_exe_line) {
                display_style = exe_display_style;
                arrow_attr = exe_arrow_attr;
                block_attr = exe_block_attr;
                highlight_attr = exe_highlight_attrs;
            } else {
                display_style = sel_display_style;
                arrow_attr = sel_arrow_attr;
                block_attr = sel_block_attr;
                highlight_attr = sel_highlight_attrs;
            }

            switch (display_style) {
                case LINE_DISPLAY_SHORT_ARROW:
                    swin_wattron(sview->win, arrow_attr);
                    swin_waddch(sview->win, '>');
                    swin_wattroff(sview->win, arrow_attr);
                    break;
                case LINE_DISPLAY_LONG_ARROW:
                    swin_wattron(sview->win, arrow_attr);
                    column_offset = get_line_leading_ws_count(
                        sline->line, sline->len);
                    column_offset -= (sview->cur->sel_col + 1);
                    if (column_offset < 0)
                        column_offset = 0;

                    /* Now actually draw the arrow */
                    for (int j = 0; j < column_offset; j++)
                        swin_waddch(sview->win, SWIN_SYM_HLINE);

                    swin_waddch(sview->win, '>');
                    swin_wattroff(sview->win, arrow_attr);

                    break;
                case LINE_DISPLAY_HIGHLIGHT:
                    swin_waddch(sview->win, ' ');
                    printline_attrs = highlight_attr;
                    break;
                case LINE_DISPLAY_BLOCK:
                    column_offset = get_line_leading_ws_count(
                        sline->line, sline->len);
                    column_offset -= (sview->cur->sel_col + 1);
                    if (column_offset < 0)
                        column_offset = 0;

                    /* Now actually draw the space to the block */
                    for (int j = 0; j < column_offset; j++)
                        swin_waddch(sview->win, ' ');

                    /* Draw the block */
                    swin_wattron(sview->win, block_attr);
                    swin_waddch(sview->win, ' ');
                    swin_wattroff(sview->win, block_attr);
                    break;
            }
        } else {
            swin_waddch(sview->win, ' ');
        }


        /* Print the text */
        if (line < 0 || line >= count) {
            for (int j = 2 + lwidth; j < width; j++)
                swin_waddch(sview->win, ' ');
        } else {
            int x, y;
            y = swin_getcury(sview->win);
            x = swin_getcurx(sview->win);

            hl_printline(sview->win, sline->line, sline->len,
                printline_attrs, -1, -1, sview->cur->sel_col + column_offset,
                width - lwidth - 2);

            if (hlsearch && sview->last_hlregex) {
                struct hl_line_attr *attrs = hl_regex_highlight(
                        &sview->last_hlregex, sline->line, HLG_SEARCH);
                if (sbcount(attrs)) {
                    hl_printline_highlight(sview->win, sline->line, sline->len,
                        attrs, x, y, sview->cur->sel_col + column_offset,
                        width - lwidth - 2);
                    sbfree(attrs);
                }
            }

            if (is_sel_line && sview->hlregex) {
                struct hl_line_attr *attrs = hl_regex_highlight(
                        &sview->hlregex, sline->line, HLG_INCSEARCH);
                if (sbcount(attrs)) {
                    hl_printline_highlight(sview->win, sline->line, sline->len,
                        attrs, x, y, sview->cur->sel_col + column_offset,
                        width - lwidth - 2);
                    sbfree(attrs);
                }
            }
        }
    }

    switch(dorefresh) {
        case WIN_NO_REFRESH:
            swin_wnoutrefresh(sview->win);
            break;
        case WIN_REFRESH:
            swin_wrefresh(sview->win);
            break;
    }

    sbfree(sel_highlight_attrs);
    sbfree(exe_highlight_attrs);

    return 0;
}
Пример #17
0
int rline_rl_complete(struct rline *rline, char **completions,
        display_callback display_cb)
{
    int size;
    int key;
    rl_command_func_t *compare_func = NULL;

    if (!rline)
        return -1;

    /* Currently, if readline output's the tab completion to rl_outstream, it will fill
     * the pty between it and CGDB and will cause CGDB to hang. */
    if (!display_cb)
        return -1;

    size = sbcount(completions);
    if (size == 0) {
        rl_completion_word_break_hook = NULL;
        rl_completion_entry_function = NULL;
    } else {
        int i;

        for (i = 0; i < size; i++)
            sbpush(completions_array, completions[i]);

        rl_completion_word_break_hook = rline_rl_cpvfunc_t;
        rl_completion_entry_function = rline_rl_completion_entry_function;
    }

    rl_completion_display_matches_hook = display_cb;

    /* This is probably a hack, however it works for now.
     *
     * Basically, rl_complete is working fine. After the call to rl_complete,
     * rl_line_buffer contains the proper data. However, the CGDB main loop
     * always call rline_rl_forced_update_display, which in the case of tab 
     * completion does this, (gdb) b ma(gdb) b main
     *
     * Normally, this works fine because the user hits '\n', which puts the prompt
     * on the next line. In this case, the user hit's \t.
     *
     * In order work around this problem, simply putting the \r should work 
     * for now.
     *
     * This obviously shouldn't be done when readline is doing 
     *    `?' means list the possible completions.
     * style completion. Because that actuall does list all of the values on
     * a different line. In this situation the \r goes after the completion
     * is done, since only the current prompt is on that line.
     */

    /* Another confusing comparison. This checks to see if the last
     * readline function and the current readline function and the 
     * tab completion callback are all the same. This ensures that this
     * is the second time the user hit \t in a row. Instead of simply
     * calling rl_complete_internal, it's better to call, rl_completion_mode
     * because this checks to see what kind of completion should be done.
     */
    if (rline->rline_rl_last_func == rline->tab_completion &&
            rline->rline_rl_last_func == rl_last_func)
        compare_func = rline->tab_completion;

    key = rl_completion_mode(compare_func);

    if (key == TAB)
        fprintf(rline->output, "\r");

    rl_complete_internal(key);

    if (key != TAB)
        fprintf(rline->output, "\r");

    /* Free the current completion array entries */
    rline_free_completions();

    return 0;
}