Fixed implicit method; some refactoring
parent
66093b4858
commit
584bcb94d1
20
Makefile
20
Makefile
|
@ -1,14 +1,16 @@
|
||||||
SRC_DIR = src
|
SRC_DIR := src
|
||||||
RELEASE_DIR = build/release
|
BUILD_DIR := build
|
||||||
DEBUG_DIR = build/debug
|
RELEASE_DIR := $(BUILD_DIR)/release
|
||||||
BINARY = stj
|
DEBUG_DIR := $(BUILD_DIR)/debug
|
||||||
|
BINARY := stj
|
||||||
|
CORES := $(shell nproc --all)
|
||||||
|
|
||||||
all: debug
|
all: debug
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@ rm -rf build
|
@ rm -rf $(BUILD_DIR)
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,14 +20,14 @@ run-release: release
|
||||||
.PHONY: run-release
|
.PHONY: run-release
|
||||||
|
|
||||||
release: $(RELEASE_DIR)/Makefile
|
release: $(RELEASE_DIR)/Makefile
|
||||||
@ make -C $(RELEASE_DIR)
|
@ make -C $(RELEASE_DIR) -j$(CORES)
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
|
|
||||||
$(RELEASE_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
|
$(RELEASE_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
|
||||||
@ cmake -H$(SRC_DIR) -B$(RELEASE_DIR) -DCMAKE_BUILD_TYPE=Release
|
@ cmake -H$(SRC_DIR) -B$(RELEASE_DIR) -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
clean-release:
|
clean-release:
|
||||||
@ rm -rf build/release
|
@ rm -rf $(RELEASE_DIR)
|
||||||
.PHONY: clean-release
|
.PHONY: clean-release
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,12 +37,12 @@ run-debug: debug
|
||||||
.PHONY: run-debug
|
.PHONY: run-debug
|
||||||
|
|
||||||
debug: $(DEBUG_DIR)/Makefile
|
debug: $(DEBUG_DIR)/Makefile
|
||||||
@ make -C $(DEBUG_DIR)
|
@ make -C $(DEBUG_DIR) -j$(CORES)
|
||||||
.PHONY: debug
|
.PHONY: debug
|
||||||
|
|
||||||
$(DEBUG_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
|
$(DEBUG_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
|
||||||
@ cmake -H$(SRC_DIR) -B$(DEBUG_DIR) -DCMAKE_BUILD_TYPE=Debug
|
@ cmake -H$(SRC_DIR) -B$(DEBUG_DIR) -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
|
||||||
clean-debug:
|
clean-debug:
|
||||||
@ rm -rf build/debug
|
@ rm -rf $(DEBUG_DIR)
|
||||||
.PHONY: clean-debug
|
.PHONY: clean-debug
|
||||||
|
|
|
@ -18,16 +18,17 @@ project(stj VERSION 0.1)
|
||||||
|
|
||||||
|
|
||||||
# =====COMPILE FLAGS=====
|
# =====COMPILE FLAGS=====
|
||||||
# General flags
|
add_definitions(-DVERSION="${CMAKE_PROJECT_VERSION}" -D_XOPEN_SOURCE=600)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVERSION=\"${CMAKE_PROJECT_VERSION}\"")
|
|
||||||
|
|
||||||
# Debug flags
|
# Debug flags
|
||||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -Wall -O0 -march=native")
|
# -g flag gets auto-added by CMake for the debug build
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -O0 -march=native")
|
||||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||||
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -pedantic")
|
||||||
|
|
||||||
# Release flags
|
# Release flags
|
||||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Werror -march=native")
|
# -O3 gets added automatically by CMake
|
||||||
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Werror -march=native -pedantic-errors")
|
||||||
|
|
||||||
|
|
||||||
# =====EXECUTABLE=====
|
# =====EXECUTABLE=====
|
||||||
|
|
104
src/st/st.c
104
src/st/st.c
|
@ -31,8 +31,8 @@
|
||||||
|
|
||||||
/* Arbitrary sizes */
|
/* Arbitrary sizes */
|
||||||
#define UTF_INVALID 0xFFFD
|
#define UTF_INVALID 0xFFFD
|
||||||
#define UTF_SIZ 4
|
#define UTF_SIZE 4
|
||||||
#define ESC_BUF_SIZ (128*UTF_SIZ)
|
#define ESC_BUF_SIZ (128*UTF_SIZE)
|
||||||
#define ESC_ARG_SIZ 16
|
#define ESC_ARG_SIZ 16
|
||||||
#define STR_BUF_SIZ ESC_BUF_SIZ
|
#define STR_BUF_SIZ ESC_BUF_SIZ
|
||||||
#define STR_ARG_SIZ ESC_ARG_SIZ
|
#define STR_ARG_SIZ ESC_ARG_SIZ
|
||||||
|
@ -227,50 +227,51 @@ static int iofd = 1;
|
||||||
static int cmdfd;
|
static int cmdfd;
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
|
|
||||||
static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
static uchar utfbyte[UTF_SIZE + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||||
static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
static uchar utfmask[UTF_SIZE + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||||
static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
static Rune utfmin[UTF_SIZE + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||||
static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
static Rune utfmax[UTF_SIZE + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||||
|
|
||||||
ssize_t
|
ssize_t xwrite(int fd, const char* s, size_t len)
|
||||||
xwrite(int fd, const char *s, size_t len)
|
|
||||||
{
|
{
|
||||||
size_t aux = len;
|
size_t aux = len;
|
||||||
ssize_t r;
|
ssize_t result;
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
r = write(fd, s, len);
|
result = write(fd, s, len);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
// This means an error occured in write, so it passes the error along
|
||||||
len -= r;
|
if (result < 0)
|
||||||
s += r;
|
return result;
|
||||||
|
|
||||||
|
len -= result;
|
||||||
|
s += result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return aux;
|
return aux;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
// Same as malloc, but stops entire program if malloc fails
|
||||||
xmalloc(size_t len)
|
void* safe_malloc(size_t len)
|
||||||
{
|
{
|
||||||
void *p;
|
void *ptr;
|
||||||
|
|
||||||
if (!(p = malloc(len)))
|
if (!(ptr = malloc(len)))
|
||||||
die("malloc: %s\n", strerror(errno));
|
die("malloc: %s\n", strerror(errno));
|
||||||
|
|
||||||
return p;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
// Same as realloc, but stops entire program if malloc fails
|
||||||
xrealloc(void *p, size_t len)
|
void* safe_realloc(void* ptr, size_t len)
|
||||||
{
|
{
|
||||||
if ((p = realloc(p, len)) == NULL)
|
if ((ptr = realloc(ptr, len)) == NULL)
|
||||||
die("realloc: %s\n", strerror(errno));
|
die("realloc: %s\n", strerror(errno));
|
||||||
|
|
||||||
return p;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char * safe_strdup(char* s)
|
||||||
xstrdup(char *s)
|
|
||||||
{
|
{
|
||||||
if ((s = strdup(s)) == NULL)
|
if ((s = strdup(s)) == NULL)
|
||||||
die("strdup: %s\n", strerror(errno));
|
die("strdup: %s\n", strerror(errno));
|
||||||
|
@ -278,25 +279,28 @@ xstrdup(char *s)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t utf8decode(const char* chr, Rune* u, size_t chr_len)
|
||||||
utf8decode(const char *c, Rune *u, size_t clen)
|
|
||||||
{
|
{
|
||||||
size_t i, j, len, type;
|
size_t i, j, len, type;
|
||||||
Rune udecoded;
|
Rune udecoded;
|
||||||
|
|
||||||
*u = UTF_INVALID;
|
*u = UTF_INVALID;
|
||||||
if (!clen)
|
if (!chr_len) // chr_len is 0, so just return 0
|
||||||
return 0;
|
return 0;
|
||||||
udecoded = utf8decodebyte(c[0], &len);
|
|
||||||
if (!BETWEEN(len, 1, UTF_SIZ))
|
udecoded = utf8decodebyte(chr[0], &len);
|
||||||
|
if (!BETWEEN(len, 1, UTF_SIZE))
|
||||||
return 1;
|
return 1;
|
||||||
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
|
||||||
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
for (i = 1, j = 1; i < chr_len && j < len; ++i, ++j) {
|
||||||
|
udecoded = (udecoded << 6) | utf8decodebyte(chr[i], &type);
|
||||||
if (type != 0)
|
if (type != 0)
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j < len)
|
if (j < len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*u = udecoded;
|
*u = udecoded;
|
||||||
utf8validate(u, len);
|
utf8validate(u, len);
|
||||||
|
|
||||||
|
@ -319,7 +323,7 @@ utf8encode(Rune u, char *c)
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
|
|
||||||
len = utf8validate(&u, 0);
|
len = utf8validate(&u, 0);
|
||||||
if (len > UTF_SIZ)
|
if (len > UTF_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = len - 1; i != 0; --i) {
|
for (i = len - 1; i != 0; --i) {
|
||||||
|
@ -379,7 +383,7 @@ base64dec(const char *src)
|
||||||
|
|
||||||
if (in_len % 4)
|
if (in_len % 4)
|
||||||
in_len += 4 - (in_len % 4);
|
in_len += 4 - (in_len % 4);
|
||||||
result = dst = xmalloc(in_len / 4 * 3 + 1);
|
result = dst = safe_malloc(in_len / 4 * 3 + 1);
|
||||||
while (*src) {
|
while (*src) {
|
||||||
int a = base64_digits[(unsigned char) base64dec_getc(&src)];
|
int a = base64_digits[(unsigned char) base64dec_getc(&src)];
|
||||||
int b = base64_digits[(unsigned char) base64dec_getc(&src)];
|
int b = base64_digits[(unsigned char) base64dec_getc(&src)];
|
||||||
|
@ -597,8 +601,8 @@ getsel(void)
|
||||||
if (sel.ob.x == -1)
|
if (sel.ob.x == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ;
|
bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZE;
|
||||||
ptr = str = xmalloc(bufsize);
|
ptr = str = safe_malloc(bufsize);
|
||||||
|
|
||||||
/* append every set & selected glyph to the selection */
|
/* append every set & selected glyph to the selection */
|
||||||
for (y = sel.nb.y; y <= sel.ne.y; y++) {
|
for (y = sel.nb.y; y <= sel.ne.y; y++) {
|
||||||
|
@ -1205,7 +1209,7 @@ tsetchar(Rune u, Glyph *attr, int x, int y)
|
||||||
*/
|
*/
|
||||||
if (term.trantbl[term.charset] == CS_GRAPHIC0 &&
|
if (term.trantbl[term.charset] == CS_GRAPHIC0 &&
|
||||||
BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41])
|
BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41])
|
||||||
utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ);
|
utf8decode(vt100_0[u - 0x41], &u, UTF_SIZE);
|
||||||
|
|
||||||
if (term.line[y][x].mode & ATTR_WIDE) {
|
if (term.line[y][x].mode & ATTR_WIDE) {
|
||||||
if (x+1 < term.col) {
|
if (x+1 < term.col) {
|
||||||
|
@ -1966,7 +1970,7 @@ void
|
||||||
strreset(void)
|
strreset(void)
|
||||||
{
|
{
|
||||||
strescseq = (STREscape){
|
strescseq = (STREscape){
|
||||||
.buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
|
.buf = safe_realloc(strescseq.buf, STR_BUF_SIZ),
|
||||||
.siz = STR_BUF_SIZ,
|
.siz = STR_BUF_SIZ,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2020,7 +2024,7 @@ tdumpsel(void)
|
||||||
void
|
void
|
||||||
tdumpline(int n)
|
tdumpline(int n)
|
||||||
{
|
{
|
||||||
char buf[UTF_SIZ];
|
char buf[UTF_SIZE];
|
||||||
Glyph *bp, *end;
|
Glyph *bp, *end;
|
||||||
|
|
||||||
bp = &term.line[n][0];
|
bp = &term.line[n][0];
|
||||||
|
@ -2303,7 +2307,7 @@ eschandle(uchar ascii)
|
||||||
void
|
void
|
||||||
tputc(Rune u)
|
tputc(Rune u)
|
||||||
{
|
{
|
||||||
char c[UTF_SIZ];
|
char c[UTF_SIZE];
|
||||||
int control;
|
int control;
|
||||||
int width, len;
|
int width, len;
|
||||||
Glyph *gp;
|
Glyph *gp;
|
||||||
|
@ -2349,10 +2353,10 @@ tputc(Rune u)
|
||||||
* term.esc = 0;
|
* term.esc = 0;
|
||||||
* strhandle();
|
* strhandle();
|
||||||
*/
|
*/
|
||||||
if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2)
|
if (strescseq.siz > (SIZE_MAX - UTF_SIZE) / 2)
|
||||||
return;
|
return;
|
||||||
strescseq.siz *= 2;
|
strescseq.siz *= 2;
|
||||||
strescseq.buf = xrealloc(strescseq.buf, strescseq.siz);
|
strescseq.buf = safe_realloc(strescseq.buf, strescseq.siz);
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove(&strescseq.buf[strescseq.len], c, len);
|
memmove(&strescseq.buf[strescseq.len], c, len);
|
||||||
|
@ -2505,21 +2509,21 @@ tresize(int col, int row)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* resize to new height */
|
/* resize to new height */
|
||||||
term.line = xrealloc(term.line, row * sizeof(Line));
|
term.line = safe_realloc(term.line, row * sizeof(Line));
|
||||||
term.alt = xrealloc(term.alt, row * sizeof(Line));
|
term.alt = safe_realloc(term.alt, row * sizeof(Line));
|
||||||
term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
|
term.dirty = safe_realloc(term.dirty, row * sizeof(*term.dirty));
|
||||||
term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
|
term.tabs = safe_realloc(term.tabs, col * sizeof(*term.tabs));
|
||||||
|
|
||||||
/* resize each row to new width, zero-pad if needed */
|
/* resize each row to new width, zero-pad if needed */
|
||||||
for (i = 0; i < minrow; i++) {
|
for (i = 0; i < minrow; i++) {
|
||||||
term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
|
term.line[i] = safe_realloc(term.line[i], col * sizeof(Glyph));
|
||||||
term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph));
|
term.alt[i] = safe_realloc(term.alt[i], col * sizeof(Glyph));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate any new rows */
|
/* allocate any new rows */
|
||||||
for (/* i = minrow */; i < row; i++) {
|
for (/* i = minrow */; i < row; i++) {
|
||||||
term.line[i] = xmalloc(col * sizeof(Glyph));
|
term.line[i] = safe_malloc(col * sizeof(Glyph));
|
||||||
term.alt[i] = xmalloc(col * sizeof(Glyph));
|
term.alt[i] = safe_malloc(col * sizeof(Glyph));
|
||||||
}
|
}
|
||||||
if (col > term.col) {
|
if (col > term.col) {
|
||||||
bp = term.tabs + term.col;
|
bp = term.tabs + term.col;
|
||||||
|
|
|
@ -94,9 +94,9 @@ char *getsel(void);
|
||||||
|
|
||||||
size_t utf8encode(Rune, char *);
|
size_t utf8encode(Rune, char *);
|
||||||
|
|
||||||
void *xmalloc(size_t);
|
void *safe_malloc(size_t);
|
||||||
void *xrealloc(void *, size_t);
|
void *safe_realloc(void *, size_t);
|
||||||
char *xstrdup(char *);
|
char *safe_strdup(char *);
|
||||||
|
|
||||||
/* config.h globals */
|
/* config.h globals */
|
||||||
extern char *utmp;
|
extern char *utmp;
|
||||||
|
|
12
src/x.c
12
src/x.c
|
@ -264,7 +264,7 @@ clipcopy(const Arg *dummy)
|
||||||
xsel.clipboard = NULL;
|
xsel.clipboard = NULL;
|
||||||
|
|
||||||
if (xsel.primary != NULL) {
|
if (xsel.primary != NULL) {
|
||||||
xsel.clipboard = xstrdup(xsel.primary);
|
xsel.clipboard = safe_strdup(xsel.primary);
|
||||||
clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
|
clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
|
||||||
XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
|
XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,7 @@ xresize(int col, int row)
|
||||||
xclear(0, 0, win.w, win.h);
|
xclear(0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* resize to new width */
|
/* resize to new width */
|
||||||
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
|
xw.specbuf = safe_realloc(xw.specbuf, col * sizeof(GlyphFontSpec));
|
||||||
}
|
}
|
||||||
|
|
||||||
ushort
|
ushort
|
||||||
|
@ -785,7 +785,7 @@ xloadcols(void)
|
||||||
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
|
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
|
||||||
} else {
|
} else {
|
||||||
dc.collen = MAX(LEN(colorname), 256);
|
dc.collen = MAX(LEN(colorname), 256);
|
||||||
dc.col = xmalloc(dc.collen * sizeof(Color));
|
dc.col = safe_malloc(dc.collen * sizeof(Color));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < dc.collen; i++)
|
for (i = 0; i < dc.collen; i++)
|
||||||
|
@ -1155,7 +1155,7 @@ xinit(int cols, int rows)
|
||||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* font spec buffer */
|
/* font spec buffer */
|
||||||
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
|
xw.specbuf = safe_malloc(cols * sizeof(GlyphFontSpec));
|
||||||
|
|
||||||
/* Xft rendering context */
|
/* Xft rendering context */
|
||||||
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
||||||
|
@ -1310,7 +1310,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||||
/* Allocate memory for the new cache entry. */
|
/* Allocate memory for the new cache entry. */
|
||||||
if (frclen >= frccap) {
|
if (frclen >= frccap) {
|
||||||
frccap += 16;
|
frccap += 16;
|
||||||
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
frc = safe_realloc(frc, frccap * sizeof(Fontcache));
|
||||||
}
|
}
|
||||||
|
|
||||||
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
||||||
|
@ -2037,7 +2037,7 @@ main(int argc, char *argv[])
|
||||||
opt_embed = EARGF(usage());
|
opt_embed = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
die("%s %s \n", argv0, VERSION);
|
die("%s\n", VERSION);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
|
Reference in New Issue