antirez / kilo

A text editor in less than 1000 LOC with syntax highlight and search.
BSD 2-Clause "Simplified" License
7.41k stars 813 forks source link

compiler warnings #58

Open dodona2 opened 5 years ago

dodona2 commented 5 years ago

just for the records:

Fedora release 29

gcc (GCC) 8.2.1 20181215 (Red Hat 8.2.1-6)

In file included from /usr/include/termios.h:25, from kilo.c:40: /usr/include/features.h:184:3: warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp]

warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"

^~~ kilo.c: In function ‘editorRefreshScreen’: kilo.c:953:19: warning: implicit declaration of function ‘time’; did you mean ‘tee’? [-Wimplicit-function-declaration] if (msglen && time(NULL)-E.statusmsg_time < 5) ^~~~ tee

p3x-robot commented 5 years ago

that is a warning, it still compiles.

texrg commented 5 years ago
> make
> cc -o kilo kilo.c -Wall -W -pedantic -std=c99
> In file included from /usr/include/termios.h:25,
>                  from kilo.c:40:
> /usr/include/features.h:184:3: warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp]
>  # warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
>    ^~~~~~~
> kilo.c: In function ‘editorRefreshScreen’:
> kilo.c:953:19: warning: implicit declaration of function ‘time’; did you mean ‘tee’? [-Wimplicit-function-declaration]
>      if (msglen && time(NULL)-E.statusmsg_time < 5)
> 
dodona2 commented 4 years ago

with linux.gcc 9.2.1: _/usr/include/features.h:185:3: warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp] 185 | # warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" | ^~~ kilo.c: In function ‘editorRefreshScreen’: kilo.c:953:19: warning: implicit declaration of function ‘time’ [-Wimplicit-function-declaration] 953 | if (msglen && time(NULL)-E.statusmsgtime < 5) | ^~~~

it's very easy to avoid the warnings. I just paste the corrected code:

/* Kilo -- A very simple editor in less than 1-kilo lines of code (as counted

define KILO_VERSION "0.0.1"

/ #define _BSD_SOURCE -dod /

define _DEFAULT_SOURCE / -dod /

define _GNU_SOURCE

include

include

include

include

include

include

include

include / -dod /

include <sys/types.h>

include <sys/ioctl.h>

/ #include <sys/time.h> -dod /

include

include

include

/ Syntax highlight types /

define HL_NORMAL 0

define HL_NONPRINT 1

define HL_COMMENT 2 / Single line comment. /

define HL_MLCOMMENT 3 / Multi-line comment. /

define HL_KEYWORD1 4

define HL_KEYWORD2 5

define HL_STRING 6

define HL_NUMBER 7

define HL_MATCH 8 / Search match. /

define HL_HIGHLIGHT_STRINGS (1<<0)

define HL_HIGHLIGHT_NUMBERS (1<<1)

struct editorSyntax { char filematch; char keywords; char singleline_comment_start[2]; char multiline_comment_start[3]; char multiline_comment_end[3]; int flags; };

/ This structure represents a single line of the file we are editing. / typedef struct erow { int idx; / Row index in the file, zero-based. / int size; / Size of the row, excluding the null term. / int rsize; / Size of the rendered row. / char chars; / Row content. / char render; / Row content "rendered" for screen (for TABs). / unsigned char hl; / Syntax highlight type for each character in render./ int hl_oc; / Row had open comment at end in last syntax highlight check. */ } erow;

typedef struct hlcolor { int r,g,b; } hlcolor;

struct editorConfig { int cx,cy; / Cursor x and y position in characters / int rowoff; / Offset of row displayed. / int coloff; / Offset of column displayed. / int screenrows; / Number of rows that we can show / int screencols; / Number of cols that we can show / int numrows; / Number of rows / int rawmode; / Is terminal raw mode enabled? / erow row; / Rows / int dirty; / File modified but not saved. / char filename; / Currently open filename / char statusmsg[80]; time_t statusmsg_time; struct editorSyntax syntax; / Current syntax highlight, or NULL. */ };

static struct editorConfig E;

enum KEY_ACTION{ KEY_NULL = 0, / NULL / CTRL_C = 3, / Ctrl-c / CTRL_D = 4, / Ctrl-d / CTRL_F = 6, / Ctrl-f / CTRL_H = 8, / Ctrl-h / TAB = 9, / Tab / CTRL_L = 12, / Ctrl+l / ENTER = 13, / Enter / CTRL_Q = 17, / Ctrl-q / CTRL_S = 19, / Ctrl-s / CTRL_U = 21, / Ctrl-u / ESC = 27, / Escape / BACKSPACE = 127, / Backspace / /* The following are just soft codes, not really reported by the

void editorSetStatusMessage(const char *fmt, ...);

/ =========================== Syntax highlights DB =========================

/ C / C++ / char C_HL_extensions[] = {".c",".cpp",NULL}; char C_HL_keywords[] = { / A few C / C++ keywords / "switch","if","while","for","break","continue","return","else", "struct","union","typedef","static","enum","class", / C types / "int|","long|","double|","float|","char|","unsigned|","signed|", "void|",NULL };

/* Here we define an array of syntax highlights by extensions, keywords,

define HLDB_ENTRIES (sizeof(HLDB)/sizeof(HLDB[0]))

/ ======================= Low level terminal handling ====================== /

static struct termios orig_termios; / In order to restore at exit./

void disableRawMode(int fd) { / Don't even check the return value as it's too late. / if (E.rawmode) { tcsetattr(fd,TCSAFLUSH,&orig_termios); E.rawmode = 0; } }

/ Called at exit to avoid remaining in raw mode. / void editorAtExit(void) { disableRawMode(STDIN_FILENO); }

/ Raw mode: 1960 magic shit. / int enableRawMode(int fd) { struct termios raw;

if (E.rawmode) return 0; /* Already enabled. */
if (!isatty(STDIN_FILENO)) goto fatal;
atexit(editorAtExit);
if (tcgetattr(fd,&orig_termios) == -1) goto fatal;

raw = orig_termios;  /* modify the original mode */
/* input modes: no break, no CR to NL, no parity check, no strip char,
 * no start/stop output control. */
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* output modes - disable post processing */
raw.c_oflag &= ~(OPOST);
/* control modes - set 8 bit chars */
raw.c_cflag |= (CS8);
/* local modes - choing off, canonical off, no extended functions,
 * no signal chars (^Z,^C) */
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
/* control chars - set return condition: min number of bytes and timer. */
raw.c_cc[VMIN] = 0; /* Return each byte, or zero for timeout. */
raw.c_cc[VTIME] = 1; /* 100 ms timeout (unit is tens of second). */

/* put terminal in raw mode after flushing */
if (tcsetattr(fd,TCSAFLUSH,&raw) < 0) goto fatal;
E.rawmode = 1;
return 0;

fatal: errno = ENOTTY; return -1; }

/* Read a key from the terminal put in raw mode, trying to handle

/* Use the ESC [6n escape sequence to query the horizontal cursor position

/* Try to get the number of columns in the current terminal. If the ioctl()

failed: return -1; }

/ ====================== Syntax highlight color scheme ==================== /

int is_separator(int c) { return c == '\0' || isspace(c) || strchr(",.()+-/*=~%[];",c) != NULL; }

/* Return true if the specified row last char is part of a multi line comment

/* Set every byte of row->hl (that corresponds to every character in the line)

/ Maps syntax highlight token types to terminal colors. / int editorSyntaxToColor(int hl) { switch(hl) { case HL_COMMENT: case HL_MLCOMMENT: return 36; / cyan / case HL_KEYWORD1: return 33; / yellow / case HL_KEYWORD2: return 32; / green / case HL_STRING: return 35; / magenta / case HL_NUMBER: return 31; / red / case HL_MATCH: return 34; / blu / default: return 37; / white / } }

/* Select the syntax highlight scheme depending on the filename,

/ ======================= Editor rows implementation ======================= /

/ Update the rendered version and the syntax highlight of a row. / void editorUpdateRow(erow *row) { int tabs = 0, nonprint = 0, j, idx;

/* Create a version of the row we can directly print on the screen,

/* Insert a row at the specified position, shifting the other rows on the bottom

/ Free row's heap allocated stuff. / void editorFreeRow(erow *row) { free(row->render); free(row->chars); free(row->hl); }

/* Remove the row at the specified position, shifting the remainign on the

/* Turn the editor rows into a single heap-allocated string.

/* Insert a character at the specified position in a row, moving the remaining

/ Append the string 's' at the end of a row / void editorRowAppendString(erow row, char s, size_t len) { row->chars = realloc(row->chars,row->size+len+1); memcpy(row->chars+row->size,s,len); row->size += len; row->chars[row->size] = '\0'; editorUpdateRow(row); E.dirty++; }

/ Delete the character at offset 'at' from the specified row. / void editorRowDelChar(erow *row, int at) { if (row->size <= at) return; memmove(row->chars+at,row->chars+at+1,row->size-at); editorUpdateRow(row); row->size--; E.dirty++; }

/ Insert the specified char at the current prompt position. / void editorInsertChar(int c) { int filerow = E.rowoff+E.cy; int filecol = E.coloff+E.cx; erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow];

/* If the row where the cursor is currently located does not exist in our
 * logical representaion of the file, add enough empty rows as needed. */
if (!row) {
    while(E.numrows <= filerow)
        editorInsertRow(E.numrows,"",0);
}
row = &E.row[filerow];
editorRowInsertChar(row,filecol,c);
if (E.cx == E.screencols-1)
    E.coloff++;
else
    E.cx++;
E.dirty++;

}

/* Inserting a newline is slightly complex as we have to handle inserting a

/ Delete the char at the current prompt position. / void editorDelChar() { int filerow = E.rowoff+E.cy; int filecol = E.coloff+E.cx; erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow];

if (!row || (filecol == 0 && filerow == 0)) return;
if (filecol == 0) {
    /* Handle the case of column 0, we need to move the current line
     * on the right of the previous one. */
    filecol = E.row[filerow-1].size;
    editorRowAppendString(&E.row[filerow-1],row->chars,row->size);
    editorDelRow(filerow);
    row = NULL;
    if (E.cy == 0)
        E.rowoff--;
    else
        E.cy--;
    E.cx = filecol;
    if (E.cx >= E.screencols) {
        int shift = (E.screencols-E.cx)+1;
        E.cx -= shift;
        E.coloff += shift;
    }
} else {
    editorRowDelChar(row,filecol-1);
    if (E.cx == 0 && E.coloff)
        E.coloff--;
    else
        E.cx--;
}
if (row) editorUpdateRow(row);
E.dirty++;

}

/* Load the specified program in the editor memory and returns 0 on success

/ Save the current file on disk. Return 0 on success, 1 on error. / int editorSave(void) { int len; char *buf = editorRowsToString(&len); int fd = open(E.filename,O_RDWR|O_CREAT,0644); if (fd == -1) goto writeerr;

/* Use truncate + a single write(2) call in order to make saving
 * a bit safer, under the limits of what we can do in a small editor. */
if (ftruncate(fd,len) == -1) goto writeerr;
if (write(fd,buf,len) != len) goto writeerr;

close(fd);
free(buf);
E.dirty = 0;
editorSetStatusMessage("%d bytes written on disk", len);
return 0;

writeerr: free(buf); if (fd != -1) close(fd); editorSetStatusMessage("Can't save! I/O error: %s",strerror(errno)); return 1; }

/ ============================= Terminal update ============================ /

/* We define a very simple "append buffer" structure, that is an heap

define ABUF_INIT {NULL,0}

void abAppend(struct abuf ab, const char s, int len) { char *new = realloc(ab->b,ab->len+len);

if (new == NULL) return;
memcpy(new+ab->len,s,len);
ab->b = new;
ab->len += len;

}

void abFree(struct abuf *ab) { free(ab->b); }

/* This function writes the whole screen using VT100 escape characters

/* Set an editor status message for the second line of the status, at the

/ =============================== Find mode ================================ /

define KILO_QUERY_LEN 256

void editorFind(int fd) { char query[KILO_QUERY_LEN+1] = {0}; int qlen = 0; int last_match = -1; / Last line where a match was found. -1 for none. / int find_next = 0; / if 1 search next, if -1 search prev. / int saved_hl_line = -1; / No saved HL / char *saved_hl = NULL;

define FIND_RESTORE_HL do { \

if (saved_hl) { \
    memcpy(E.row[saved_hl_line].hl,saved_hl, E.row[saved_hl_line].rsize); \
    saved_hl = NULL; \
} \

} while (0)

/* Save the cursor position in order to restore it later. */
int saved_cx = E.cx, saved_cy = E.cy;
int saved_coloff = E.coloff, saved_rowoff = E.rowoff;

while(1) {
    editorSetStatusMessage(
        "Search: %s (Use ESC/Arrows/Enter)", query);
    editorRefreshScreen();

    int c = editorReadKey(fd);
    if (c == DEL_KEY || c == CTRL_H || c == BACKSPACE) {
        if (qlen != 0) query[--qlen] = '\0';
        last_match = -1;
    } else if (c == ESC || c == ENTER) {
        if (c == ESC) {
            E.cx = saved_cx; E.cy = saved_cy;
            E.coloff = saved_coloff; E.rowoff = saved_rowoff;
        }
        FIND_RESTORE_HL;
        editorSetStatusMessage("");
        return;
    } else if (c == ARROW_RIGHT || c == ARROW_DOWN) {
        find_next = 1;
    } else if (c == ARROW_LEFT || c == ARROW_UP) {
        find_next = -1;
    } else if (isprint(c)) {
        if (qlen < KILO_QUERY_LEN) {
            query[qlen++] = c;
            query[qlen] = '\0';
            last_match = -1;
        }
    }

    /* Search occurrence. */
    if (last_match == -1) find_next = 1;
    if (find_next) {
        char *match = NULL;
        int match_offset = 0;
        int i, current = last_match;

        for (i = 0; i < E.numrows; i++) {
            current += find_next;
            if (current == -1) current = E.numrows-1;
            else if (current == E.numrows) current = 0;
            match = strstr(E.row[current].render,query);
            if (match) {
                match_offset = match-E.row[current].render;
                break;
            }
        }
        find_next = 0;

        /* Highlight */
        FIND_RESTORE_HL;

        if (match) {
            erow *row = &E.row[current];
            last_match = current;
            if (row->hl) {
                saved_hl_line = current;
                saved_hl = malloc(row->rsize);
                memcpy(saved_hl,row->hl,row->rsize);
                memset(row->hl+match_offset,HL_MATCH,qlen);
            }
            E.cy = 0;
            E.cx = match_offset;
            E.rowoff = current;
            E.coloff = 0;
            /* Scroll horizontally as needed. */
            if (E.cx > E.screencols) {
                int diff = E.cx - E.screencols;
                E.cx -= diff;
                E.coloff += diff;
            }
        }
    }
}

}

/ ========================= Editor events handling ======================== /

/ Handle cursor position change because arrow keys were pressed. / void editorMoveCursor(int key) { int filerow = E.rowoff+E.cy; int filecol = E.coloff+E.cx; int rowlen; erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow];

switch(key) {
case ARROW_LEFT:
    if (E.cx == 0) {
        if (E.coloff) {
            E.coloff--;
        } else {
            if (filerow > 0) {
                E.cy--;
                E.cx = E.row[filerow-1].size;
                if (E.cx > E.screencols-1) {
                    E.coloff = E.cx-E.screencols+1;
                    E.cx = E.screencols-1;
                }
            }
        }
    } else {
        E.cx -= 1;
    }
    break;
case ARROW_RIGHT:
    if (row && filecol < row->size) {
        if (E.cx == E.screencols-1) {
            E.coloff++;
        } else {
            E.cx += 1;
        }
    } else if (row && filecol == row->size) {
        E.cx = 0;
        E.coloff = 0;
        if (E.cy == E.screenrows-1) {
            E.rowoff++;
        } else {
            E.cy += 1;
        }
    }
    break;
case ARROW_UP:
    if (E.cy == 0) {
        if (E.rowoff) E.rowoff--;
    } else {
        E.cy -= 1;
    }
    break;
case ARROW_DOWN:
    if (filerow < E.numrows) {
        if (E.cy == E.screenrows-1) {
            E.rowoff++;
        } else {
            E.cy += 1;
        }
    }
    break;
}
/* Fix cx if the current line has not enough chars. */
filerow = E.rowoff+E.cy;
filecol = E.coloff+E.cx;
row = (filerow >= E.numrows) ? NULL : &E.row[filerow];
rowlen = row ? row->size : 0;
if (filecol > rowlen) {
    E.cx -= filecol-rowlen;
    if (E.cx < 0) {
        E.coloff += E.cx;
        E.cx = 0;
    }
}

}

/* Process events arriving from the standard input, which is, the user

int editorFileWasModified(void) { return E.dirty; }

void initEditor(void) { E.cx = 0; E.cy = 0; E.rowoff = 0; E.coloff = 0; E.numrows = 0; E.row = NULL; E.dirty = 0; E.filename = NULL; E.syntax = NULL; if (getWindowSize(STDIN_FILENO,STDOUT_FILENO, &E.screenrows,&E.screencols) == -1) { perror("Unable to query the screen for size (columns / rows)"); exit(1); } E.screenrows -= 2; / Get room for status bar. / }

int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr,"Usage: kilo \n"); exit(1); }

initEditor();
editorSelectSyntaxHighlight(argv[1]);
editorOpen(argv[1]);
enableRawMode(STDIN_FILENO);
editorSetStatusMessage(
    "HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find");
while(1) {
    editorRefreshScreen();
    editorProcessKeypress(STDIN_FILENO);
}
return 0;

}