static void release_file_buffer(struct buffer *buf) { if (buf) { int i; for (i = 0; i < sbcount(buf->lines); i++) { sbfree(buf->lines[i].attrs); buf->lines[i].attrs = NULL; if (!buf->file_data) { sbfree(buf->lines[i].line); buf->lines[i].line = NULL; } } /* Free entire file buffer */ sbfree(buf->file_data); buf->file_data = NULL; sbfree(buf->lines); buf->lines = NULL; sbfree(buf->addrs); buf->addrs = NULL; buf->max_width = 0; buf->language = TOKENIZER_LANGUAGE_UNKNOWN; } }
void scr_free(struct scroller *scr) { int i; /* Release the buffer */ for (i = 0; i < sbcount(scr->lines); i++) { free(scr->lines[i].line); sbfree(scr->lines[i].attrs); } sbfree(scr->lines); scr->lines = NULL; hl_regex_free(&scr->last_hlregex); scr->last_hlregex = NULL; hl_regex_free(&scr->hlregex); scr->hlregex = NULL; free(scr->last_inferior_line); scr->last_inferior_line = NULL; swin_delwin(scr->win); scr->win = NULL; /* Release the scroller object */ free(scr); }
int a2_shutdown(struct annotate_two *a2) { int i; cgdb_close(a2->debugger_stdin); a2->debugger_stdin = -1; state_machine_shutdown(a2->sm); commands_shutdown(a2->c); a2_delete_responses(a2); sbfree(a2->responses); a2->responses = NULL; for (i = 0; i < sbcount(a2->client_commands); i++) { struct tgdb_command *tc = a2->client_commands[i]; free(tc->gdb_command); free(tc); } sbfree(a2->client_commands); a2->client_commands = NULL; return 0; }
/* * Cut data from (the front of) a sockbuf. */ static struct mbuf * sbcut_internal(struct sockbuf *sb, int len) { struct mbuf *m, *n, *next, *mfree; next = (m = sb->sb_mb) ? m->m_nextpkt : 0; mfree = NULL; while (len > 0) { if (m == 0) { if (next == 0) panic("sbdrop"); m = next; next = m->m_nextpkt; continue; } if (m->m_len > len) { m->m_len -= len; m->m_data += len; sb->sb_cc -= len; if (sb->sb_sndptroff != 0) sb->sb_sndptroff -= len; if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA) sb->sb_ctl -= len; break; } len -= m->m_len; sbfree(sb, m); n = m->m_next; m->m_next = mfree; mfree = m; m = n; } while (m && m->m_len == 0) { sbfree(sb, m); n = m->m_next; m->m_next = mfree; mfree = m; m = n; } if (m) { sb->sb_mb = m; m->m_nextpkt = next; } else sb->sb_mb = next; /* * First part is an inline SB_EMPTY_FIXUP(). Second part makes sure * sb_lastrecord is up-to-date if we dropped part of the last record. */ m = sb->sb_mb; if (m == NULL) { sb->sb_mbtail = NULL; sb->sb_lastrecord = NULL; } else if (m->m_nextpkt == NULL) { sb->sb_lastrecord = m; } return (mfree); }
static const char * executable_dir(const char *progname) { SB sb; struct stat sbuf; if (! progname) return 0; sbinit(&sb); if (progname[0]=='/') sbaddn(&sb, progname, strlen(progname)); else if (strchr(progname,'/')) sbaddsf(&sb,catpath(NULL,progname)); else { char *p = getenv("PATH"); for (;;) { sb.len = 0; if (! (p && *p)) return sbfree(&sb); while (*p && *p!=':') sbadd1(&sb, *p++); if (*p ==':') p++; sbadd1(&sb, 0); sb.len = 0; sbaddsf(&sb, catpath(sb.buffer, progname)); sbadd1(&sb, 0); if (sb.buffer && stat(sb.buffer,&sbuf)>=0 && S_ISREG(sbuf.st_mode)) if (access(sb.buffer, X_OK) >= 0) break; } } #ifdef S_ISLNK sbadd1(&sb, 0); while(sb.buffer && lstat(sb.buffer,&sbuf)>=0 && S_ISLNK(sbuf.st_mode)) { int h,l; sbaddn(&sb,"../",3); h = sb.len; while ((l=readlink(sb.buffer,sb.buffer+h,sb.maxlen-h))>=sb.maxlen-h) sbgrow(&sb, sb.maxlen - h + SBINCREMENT); if (l < 0) return sbfree(&sb); sb.len = h + l; sbadd1(&sb,0); sb.len = 0; sbaddsf(&sb, catpath(sb.buffer,sb.buffer+h-3)); sbadd1(&sb,0); } #endif while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/') sb.len -= 1; while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]!='/') sb.len -= 1; while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/') sb.len -= 1; sbadd1(&sb, 0); return sb.buffer; }
/* * Drop data from (the front of) a sockbuf. */ void sbdrop(struct sockbuf *sb, int len) { struct mbuf *m, *mn; struct mbuf *next; next = (m = sb->sb_mb) ? m->m_nextpkt : 0; while (len > 0) { if (m == NULL) { if (next == NULL) panic("sbdrop"); m = next; next = m->m_nextpkt; continue; } if (m->m_len > len) { m->m_len -= len; m->m_data += len; sb->sb_cc -= len; if (m->m_type != MT_CONTROL && m->m_type != MT_SONAME) sb->sb_datacc -= len; break; } len -= m->m_len; sbfree(sb, m); mn = m_free(m); m = mn; } while (m && m->m_len == 0) { sbfree(sb, m); mn = m_free(m); m = mn; } if (m) { sb->sb_mb = m; m->m_nextpkt = next; } else sb->sb_mb = next; /* * First part is an inline SB_EMPTY_FIXUP(). Second part * makes sure sb_lastrecord is up-to-date if we dropped * part of the last record. */ m = sb->sb_mb; if (m == NULL) { sb->sb_mbtail = NULL; sb->sb_lastrecord = NULL; } else if (m->m_nextpkt == NULL) sb->sb_lastrecord = m; }
/** * Send a command to gdb. * * @param tgdb * An instance of tgdb * * @param request * The command request to issue the command for */ static void tgdb_run_request(struct tgdb *tgdb, struct tgdb_request *request) { std::string command; if (request->header == TGDB_REQUEST_CONSOLE_COMMAND || request->header == TGDB_REQUEST_COMPLETE || request->header == TGDB_REQUEST_DEBUGGER_COMMAND) { tgdb->make_console_ready_callback = true; } tgdb->is_gdb_ready_for_next_command = 0; tgdb_get_gdb_command(tgdb, request, command); /* Add a newline to the end of the command if it doesn't exist */ if (*command.rbegin() != '\n') { command.push_back('\n'); } /* Send what we're doing to log file */ char *str = sys_quote_nonprintables(command.c_str(), -1); clog_debug(CLOG_GDBIO, "%s", str); sbfree(str); /* A command for the debugger */ commands_set_current_request_type(tgdb->c, request->header); io_writen(tgdb->debugger_stdin, command.c_str(), command.size()); // Alert the GUI a command was sent tgdb->callbacks.request_sent_callback( tgdb->callbacks.context, request, command); tgdb_request_destroy(request); }
/* * Drop the first mbuf off the sockbuf and move the next mbuf to the front. * Currently only the head mbuf of the sockbuf may be dropped this way. * * The next mbuf in the same record as the mbuf being removed is returned * or NULL if the record is exhausted. Note that other records may remain * in the sockbuf when NULL is returned. * * Must be called while holding a critical section. */ struct mbuf * sbunlinkmbuf(struct sockbuf *sb, struct mbuf *m, struct mbuf **free_chain) { struct mbuf *n; KKASSERT(sb->sb_mb == m); sbfree(sb, m); n = m->m_next; if (n) { sb->sb_mb = n; if (sb->sb_lastrecord == m) sb->sb_lastrecord = n; KKASSERT(sb->sb_lastmbuf != m); n->m_nextpkt = m->m_nextpkt; } else { sb->sb_mb = m->m_nextpkt; if (sb->sb_lastrecord == m) { KKASSERT(sb->sb_mb == NULL); sb->sb_lastrecord = NULL; } if (sb->sb_mb == NULL) sb->sb_lastmbuf = NULL; } m->m_nextpkt = NULL; if (free_chain) { m->m_next = *free_chain; *free_chain = m; } else { m->m_next = NULL; } return(n); }
static int sbsetpush(lua_State *L, SB *sb, const char *s) { sbfree(sb); lua_pushstring(L, s); return 1; }
ssize_t io_read(int fd, void *buf, size_t count) { ssize_t amountRead; tgdb_read: if ((amountRead = read(fd, buf, count)) == -1) { /* error */ if (errno == EINTR) goto tgdb_read; else if (errno != EIO) { logger_write_pos(logger, __FILE__, __LINE__, "error reading from fd"); return -1; } else { return 0; /* Happens on EOF for some reason */ } } else if (amountRead == 0) { /* EOF */ return 0; } else { char *str = sys_quote_nonprintables((char *)buf, amountRead); clog_debug(CLOG(TGDB_LOGGER), "%s", str); sbfree(str); } return amountRead; }
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; }
static int sbpush(lua_State *L, SB *sb) { sbslash(sb); lua_pushlstring(L, sb->buffer, sb->len); sbfree(sb); return 1; }
static void sbaddsf(SB *sb, char *s) { if (s) sbaddn(sb, s, strlen(s)); else sbfree(sb); if (s) free((void*)s); }
static void sbaddn(SB *sb, const char *s, int n) { sbgrow(sb, n); if (sb->buffer && s && n) memcpy(sb->buffer + sb->len, s, n); else if (sb->buffer && n) sbfree(sb); sb->len += n; }
static char * catpath(const char *from, const char *fname) { SB sb; sbinit(&sb); if (fname && fname[0]=='/') sbadd1(&sb, '/'); else if (from) sbaddsf(&sb, catpath(NULL,from)); else { char *cwd = 0; while (sb.buffer && !cwd) { cwd = getcwd(sb.buffer + sb.len, sb.maxlen - sb.len); if (cwd || errno != ERANGE) break; sbgrow(&sb, sb.maxlen - sb.len + SBINCREMENT); } if (cwd) sb.len += strlen(cwd); else sbfree(&sb); } for (;;) { while (fname && fname[0]=='/') fname++; if (!fname || !fname[0]) { while (&sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/') sb.len -= 1; sbadd1(&sb, 0); return sb.buffer; } 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.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/') sb.len -= 1; while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]!='/') sb.len -= 1; continue; } } if (sb.len==0 || (sb.buffer && sb.buffer[sb.len-1]!='/')) sbadd1(&sb, '/'); while (*fname!=0 && *fname!='/') sbadd1(&sb, *fname++); } sbadd1(&sb, 0); return sb.buffer; }
/* * Drop a record off the front of a sockbuf and move the next record to the * front. */ void ofp_sbdroprecord_locked(struct sockbuf *sb) { odp_packet_t pkt; SOCKBUF_LOCK_ASSERT(sb); pkt = ofp_sockbuf_remove_first(sb); if (pkt != ODP_PACKET_INVALID) { sbfree(sb, pkt); odp_packet_free(pkt); } }
/* * Drop a record off the front of a sockbuf * and move the next record to the front. */ void sbdroprecord(struct sockbuf *sb) { struct mbuf *m, *mn; m = sb->sb_mb; if (m) { sb->sb_mb = m->m_nextpkt; do { sbfree(sb, m); mn = m_free(m); } while ((m = mn) != NULL); } SB_EMPTY_FIXUP(sb); }
/* * Drop a record off the front of a sockbuf * and move the next record to the front. */ void sbdroprecord(struct sockbuf *sb) { struct mbuf *m, *mn; m = sb->sb_mb; if (m) { sb->sb_mb = m->m_nextpkt; do { sbfree(sb, m); MFREE(m, mn); m = mn; } while (m); } SB_EMPTY_FIXUP(sb); postevent(0, sb, EV_RWBYTES); }
/* * Drop a record off the front of a sockbuf and move the next record to the * front. */ void sbdroprecord_locked(struct sockbuf *sb) { struct mbuf *m; SOCKBUF_LOCK_ASSERT(sb); m = sb->sb_mb; if (m) { sb->sb_mb = m->m_nextpkt; do { sbfree(sb, m); m = m_free(m); } while (m); } SB_EMPTY_FIXUP(sb); }
void filedlg_clear(struct filedlg *fd) { int i; ibuf_clear(fd->G_line_number); for (i = 0; i < sbcount(fd->buf->files); i++) free(fd->buf->files[i]); sbfree(fd->buf->files); fd->buf->files = NULL; fd->buf->max_width = 0; fd->buf->sel_line = 0; fd->buf->sel_col = 0; fd->buf->sel_rline = 0; }
static const char * relocate_path(const char *dir, const char *s) { SB sb; const char *r; const char *execdir = LUA_EXECDIR; int lexecdir = strlen(execdir); int ldir = strlen(dir); sbinit(&sb); while ((r = strstr(s, execdir))) { sbaddn(&sb, s, r-s); sbaddn(&sb, dir, ldir); s = r + lexecdir; while (is_slash(s[0])) { if (is_dot(s[1]) && is_slash(s[2])) { s += 2; continue; } if (is_dot(s[1]) && is_dot(s[2]) && is_slash(s[3]) ) { s += 3; while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1])) sb.len -= 1; while (sb.buffer && sb.len>0 && !is_slash(sb.buffer[sb.len-1])) sb.len -= 1; while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1])) sb.len -= 1; continue; } break; } } sbaddn(&sb, s, strlen(s)); sbadd1(&sb, 0); #ifdef LUA_WIN r = _strdup(sb.buffer); #else r = strdup(sb.buffer); #endif sbfree(&sb); return r; }
int source_del(struct sviewer *sview, const char *path) { int i; struct list_node *cur; struct list_node *prev = NULL; /* Find the target node */ for (cur = sview->list_head; cur != NULL; cur = cur->next) { if (strcmp(path, cur->path) == 0) break; prev = cur; } if (cur == NULL) return 1; /* Node not found */ /* Release file buffers */ release_file_buffer(&cur->file_buf); /* Release file name */ free(cur->path); cur->path = NULL; sbfree(cur->lflags); cur->lflags = NULL; /* Remove link from list */ if (cur == sview->list_head) sview->list_head = sview->list_head->next; else prev->next = cur->next; /* Free the node */ free(cur); /* Free any global marks pointing to this bugger */ for (i = 0; i < sizeof(sview->global_marks) / sizeof(sview->global_marks[0]); i++) { if (sview->global_marks[i].node == cur) sview->global_marks[i].node = NULL; } return 0; }
/* * Drop a record off the front of a sockbuf and move the next record * to the front. * * Must be called while holding a critical section. */ void sbdroprecord(struct sockbuf *sb) { struct mbuf *m; struct mbuf *n; sbcheck(sb); m = sb->sb_mb; if (m) { if ((sb->sb_mb = m->m_nextpkt) == NULL) { sb->sb_lastrecord = NULL; sb->sb_lastmbuf = NULL; } m->m_nextpkt = NULL; for (n = m; n; n = n->m_next) sbfree(sb, n); m_freem(m); sbcheck(sb); } }
int rline_shutdown(struct rline *rline) { if (!rline) return -1; /* Should this be OK? */ rline_free_completions(); sbfree(completions_array); completions_array = NULL; if (rline->input) fclose(rline->input); if (rline->output) fclose(rline->output); free(rline); rline = NULL; return 0; }
/* * Drop data from (the front of) a sockbuf. */ static void sbdrop_internal(struct sockbuf *sb, int len) { odp_packet_t pkt; while (len > 0) { pkt = ofp_sockbuf_get_first(sb); if (pkt == ODP_PACKET_INVALID) return; int buflen = odp_packet_len(pkt); if (buflen > len) { odp_packet_pull_head(pkt, len); sb->sb_cc -= len; if (sb->sb_sndptroff != 0) sb->sb_sndptroff -= len; break; } len -= buflen; pkt = ofp_sockbuf_remove_first(sb); sbfree(sb, pkt); ofp_sockbuf_packet_free(pkt); } }
/** * 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; }
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; }
/** * 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; }
/* 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; }
int sbappendaddrchain(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0, int sbprio) { int space; struct mbuf *m, *n, *n0, *nlast; int error; KASSERT(solocked(sb->sb_so)); /* * XXX sbprio reserved for encoding priority of this* request: * SB_PRIO_NONE --> honour normal sb limits * SB_PRIO_ONESHOT_OVERFLOW --> if socket has any space, * take whole chain. Intended for large requests * that should be delivered atomically (all, or none). * SB_PRIO_OVERDRAFT -- allow a small (2*MLEN) overflow * over normal socket limits, for messages indicating * buffer overflow in earlier normal/lower-priority messages * SB_PRIO_BESTEFFORT --> ignore limits entirely. * Intended for kernel-generated messages only. * Up to generator to avoid total mbuf resource exhaustion. */ (void)sbprio; if (m0 && (m0->m_flags & M_PKTHDR) == 0) panic("sbappendaddrchain"); space = sbspace(sb); #ifdef notyet /* * Enforce SB_PRIO_* limits as described above. */ #endif n0 = NULL; nlast = NULL; for (m = m0; m; m = m->m_nextpkt) { struct mbuf *np; #ifdef MBUFTRACE m_claimm(m, sb->sb_mowner); #endif /* Prepend sockaddr to this record (m) of input chain m0 */ n = m_prepend_sockaddr(sb, m, asa); if (n == NULL) { error = ENOBUFS; goto bad; } /* Append record (asa+m) to end of new chain n0 */ if (n0 == NULL) { n0 = n; } else { nlast->m_nextpkt = n; } /* Keep track of last record on new chain */ nlast = n; for (np = n; np; np = np->m_next) sballoc(sb, np); } SBLASTRECORDCHK(sb, "sbappendaddrchain 1"); /* Drop the entire chain of (asa+m) records onto the socket */ SBLINKRECORDCHAIN(sb, n0, nlast); SBLASTRECORDCHK(sb, "sbappendaddrchain 2"); for (m = nlast; m->m_next; m = m->m_next) ; sb->sb_mbtail = m; SBLASTMBUFCHK(sb, "sbappendaddrchain"); return (1); bad: /* * On error, free the prepended addreseses. For consistency * with sbappendaddr(), leave it to our caller to free * the input record chain passed to us as m0. */ while ((n = n0) != NULL) { struct mbuf *np; /* Undo the sballoc() of this record */ for (np = n; np; np = np->m_next) sbfree(sb, np); n0 = n->m_nextpkt; /* iterate at next prepended address */ MFREE(n, np); /* free prepended address (not data) */ } return 0; }