added tail and head
This commit is contained in:
parent
4403e7edc2
commit
a94b5bcd94
8 changed files with 385 additions and 51 deletions
|
@ -4,7 +4,7 @@
|
|||
A terrible busybox/gnu coreutils clone.
|
||||
|
||||
Currently the only supported commands are:
|
||||
`dd`, `cat`, `yes`, `echo`, `printf`, `id`, `groups`, `ls`, `tail`
|
||||
`dd`, `cat`, `yes`, `echo`, `printf`, `id`, `groups`, `ls`, `tail`, `head`
|
||||
|
||||
## How to
|
||||
|
||||
|
|
|
@ -18,3 +18,4 @@ COMMAND_EMPTY(groups);
|
|||
COMMAND_EMPTY(user_id);
|
||||
COMMAND(ls);
|
||||
COMMAND(tail);
|
||||
COMMAND(head);
|
||||
|
|
145
src/commands/head.c
Normal file
145
src/commands/head.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
#include "../command.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct Flags {
|
||||
int count;
|
||||
bool lines;
|
||||
bool print_headers;
|
||||
bool dont_print_headers;
|
||||
};
|
||||
|
||||
static void head_file_lines(FILE* file, struct Flags* flags) {
|
||||
size_t len = 0;
|
||||
char* line = NULL;
|
||||
|
||||
int count = flags->count;
|
||||
while(count > 0 && getline(&line, &len, file) != -1) {
|
||||
printf("%s", line);
|
||||
count--;
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
static void head_file_chars(FILE* file, struct Flags* flags) {
|
||||
char c;
|
||||
int count = flags->count;
|
||||
while(count > 0 && (c = getc(file)) != EOF) {
|
||||
putchar(c);
|
||||
count--;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
static void help() {
|
||||
printf("Usage: head [OPTIONS] [FILE]...\n\n");
|
||||
printf("Print first 10 lines of FILEs (or stdin)\n");
|
||||
printf("With more than one FILE, precede each with a filename header.\n\n");
|
||||
printf("\t-c [+]N[bkm]\tPrint first N bytes\n");
|
||||
printf("\t-n N[bkm]\tPrint first N lines\n");
|
||||
printf("\t\t\t(b:*512 k:*1024 m:*1024^2)\n");
|
||||
printf("\t-q\t\tNever print headers\n");
|
||||
printf("\t-v\t\tAlways print headers\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static char* next_arg(int argc, char** argv, int index) {
|
||||
if (index >= argc) {
|
||||
error("error: expected another argument after option");
|
||||
}
|
||||
return argv[index];
|
||||
}
|
||||
|
||||
static void print_header(char* path, struct Flags* flags, bool many) {
|
||||
if (flags->dont_print_headers) return;
|
||||
if (!many && !flags->print_headers) return;
|
||||
if (streql("-", path)) {
|
||||
printf("\n==> standard input <==\n");
|
||||
} else {
|
||||
printf("\n=>> %s <==\n", path);
|
||||
}
|
||||
}
|
||||
|
||||
static void head_file(char* path, struct Flags* flags, bool many) {
|
||||
FILE* file = get_file(path, "r");
|
||||
print_header(path, flags, many);
|
||||
if (flags->lines) {
|
||||
head_file_lines(file, flags);
|
||||
} else {
|
||||
head_file_chars(file, flags);
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND(head) {
|
||||
struct Flags flags;
|
||||
flags.count = 10;
|
||||
flags.lines = true;
|
||||
flags.print_headers = false;
|
||||
flags.dont_print_headers = false;
|
||||
|
||||
int start = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!prefix("-", argv[i])) break;
|
||||
if (streql(argv[0], "--help")) help();
|
||||
start++;
|
||||
int i_s = i;
|
||||
for (size_t j = 1; j < strlen(argv[i_s]); j++) {
|
||||
char c = argv[i_s][j];
|
||||
switch(c) {
|
||||
case 'c': {
|
||||
start++;
|
||||
flags.lines = false;
|
||||
char* arg = next_arg(argc, argv, ++i);
|
||||
long int bkm = get_blkm(arg);
|
||||
if (bkm < 1) {
|
||||
error("error: bkm cannot be less than 1");
|
||||
}
|
||||
flags.count = bkm;
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
start++;
|
||||
flags.lines = true;
|
||||
char* arg = next_arg(argc, argv, ++i);
|
||||
long int bkm = get_blkm(arg);
|
||||
if (bkm < 1) {
|
||||
error("error: bkm cannot be less than 1");
|
||||
}
|
||||
flags.count = bkm;
|
||||
break;
|
||||
}
|
||||
case 'q':
|
||||
flags.dont_print_headers = true;
|
||||
break;
|
||||
case 'v':
|
||||
flags.print_headers = true;
|
||||
break;
|
||||
default: {
|
||||
error("error: unknown option -%c", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = argc - start;
|
||||
|
||||
if (count < 1) {
|
||||
head_file_lines(stdin, &flags);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
head_file(argv[start], &flags, false);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
head_file(argv[start + i], &flags, true);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -25,6 +25,7 @@ struct Flags {
|
|||
bool more_info;
|
||||
bool one_column;
|
||||
bool recurse;
|
||||
bool colored;
|
||||
};
|
||||
|
||||
struct FileInfo {
|
||||
|
@ -34,10 +35,11 @@ struct FileInfo {
|
|||
struct group* grp;
|
||||
char size[5];
|
||||
char date[13];
|
||||
struct dirent* file;
|
||||
char name[PATH_MAX];
|
||||
bool set_uid;
|
||||
bool set_gid;
|
||||
bool exec;
|
||||
unsigned char type;
|
||||
};
|
||||
|
||||
struct FileListInfo {
|
||||
|
@ -61,14 +63,17 @@ static DIR* get_directory(char* path) {
|
|||
return d;
|
||||
}
|
||||
|
||||
static void append_path(char buf[PATH_MAX], const char* dir_path, const struct dirent* file) {
|
||||
static void append_path(char buf[PATH_MAX], const char* dir_path, const char* file_path) {
|
||||
size_t dir_len = strlen(dir_path);
|
||||
size_t file_len = strlen(file_path);
|
||||
|
||||
memcpy(buf, dir_path, dir_len);
|
||||
if (buf[dir_len-1] != '/') {
|
||||
buf[dir_len] = '/';
|
||||
dir_len++;
|
||||
}
|
||||
memcpy(buf + dir_len, file->d_name, strlen(file->d_name) + 1);
|
||||
memcpy(buf + dir_len, file_path, file_len);
|
||||
buf[dir_len + file_len] = '\0';
|
||||
}
|
||||
|
||||
static bool get_file_info(struct dirent* file, const char* dir_path, struct FileInfo* info) {
|
||||
|
@ -77,17 +82,20 @@ static bool get_file_info(struct dirent* file, const char* dir_path, struct File
|
|||
gid_t gid = getgid();
|
||||
|
||||
char buf[PATH_MAX];
|
||||
append_path(buf, dir_path, file);
|
||||
append_path(buf, dir_path, file->d_name);
|
||||
|
||||
struct stat s;
|
||||
memset(&s, 0, sizeof(struct stat));
|
||||
|
||||
if (stat(buf, &s) < 0) {
|
||||
printf("\x1b[0merror: failed to read file '%s': %s\n", buf, strerror(errno));
|
||||
// printf("\x1b[0merror: failed to read file '%s': %s\n", buf, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
info->set_uid = false;
|
||||
info->set_gid = false;
|
||||
info->exec = false;
|
||||
info->name[0] = '\0';
|
||||
|
||||
if (file->d_type == DT_DIR)
|
||||
info->mode[0] = 'd';
|
||||
|
@ -137,8 +145,10 @@ static bool get_file_info(struct dirent* file, const char* dir_path, struct File
|
|||
|
||||
info->usr = getpwuid(s.st_uid);
|
||||
info->grp = getgrgid(s.st_gid);
|
||||
info->file = file;
|
||||
info->links = s.st_nlink;
|
||||
info->type = file->d_type;
|
||||
|
||||
strcpy(info->name, file->d_name);
|
||||
|
||||
print_file_size(s.st_size, info->size);
|
||||
print_date_time(s.st_mtim.tv_sec + s.st_mtim.tv_nsec / 1000000, info->date);
|
||||
|
@ -147,9 +157,9 @@ static bool get_file_info(struct dirent* file, const char* dir_path, struct File
|
|||
|
||||
static char* get_file_color(struct FileInfo* info) {
|
||||
char* color;
|
||||
if (info->file->d_type == DT_DIR) {
|
||||
if (info->type == DT_DIR) {
|
||||
color = DIR_COLOR;
|
||||
} else if (info->file->d_type == DT_LNK) {
|
||||
} else if (info->type == DT_LNK) {
|
||||
color = LINK_COLOR;
|
||||
} else {
|
||||
if (info->set_uid) {
|
||||
|
@ -171,6 +181,7 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo
|
|||
|
||||
if (!isatty(1)) {
|
||||
flags->one_column = true;
|
||||
flags->colored = false;
|
||||
}
|
||||
|
||||
char* color;
|
||||
|
@ -179,7 +190,6 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo
|
|||
|
||||
for (int i = 0; i < file_len; i++) {
|
||||
struct FileInfo finfo = files[i];
|
||||
if (strlen(finfo.file->d_name) < 1) continue;
|
||||
color = get_file_color(&finfo);
|
||||
if (flags->more_info) {
|
||||
printf("%s %*d %*s %*s %*s %s %s%s\x1b[0m",
|
||||
|
@ -193,12 +203,12 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo
|
|||
info.max_size,
|
||||
finfo.size,
|
||||
finfo.date,
|
||||
color,
|
||||
finfo.file->d_name
|
||||
flags->colored ? color : FILE_COLOR,
|
||||
finfo.name
|
||||
);
|
||||
if (finfo.file->d_type == DT_LNK) {
|
||||
if (finfo.type == DT_LNK) {
|
||||
char path[PATH_MAX];
|
||||
append_path(path, dir_path, finfo.file);
|
||||
append_path(path, dir_path, finfo.name);
|
||||
|
||||
char lnk[PATH_MAX];
|
||||
if (readlink(path, lnk, PATH_MAX) < 0) {
|
||||
|
@ -211,13 +221,13 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo
|
|||
putchar('\n');
|
||||
}
|
||||
} else if (flags->one_column) {
|
||||
printf("%s%s\x1b[0m\n", color, finfo.file->d_name);
|
||||
printf("%s%s\x1b[0m\n", color, finfo.name);
|
||||
} else {
|
||||
if (info.total_len > w.ws_col) {
|
||||
if (i != 0 && i % row_count == 0) putchar('\n');
|
||||
printf("%s%*s\x1b[0m", color, column_width, finfo.file->d_name);
|
||||
printf("%s%*s\x1b[0m", flags->colored ? color : FILE_COLOR, -column_width, finfo.name);
|
||||
} else {
|
||||
printf("%s%s\x1b[0m ", color, finfo.file->d_name);
|
||||
printf("%s%s\x1b[0m ", flags->colored ? color : FILE_COLOR, finfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +328,7 @@ static bool recurse_directory(char* path, struct Flags* flags) {
|
|||
if (!flags->hidden && prefix(".", file->d_name)) continue;
|
||||
if (is_dot_dir(file->d_name)) continue;
|
||||
char buf[PATH_MAX];
|
||||
append_path(buf, path, file);
|
||||
append_path(buf, path, file->d_name);
|
||||
recurse_directory(buf, flags);
|
||||
}
|
||||
|
||||
|
@ -374,11 +384,17 @@ COMMAND(ls) {
|
|||
flags.hide_dot = false;
|
||||
flags.one_column = false;
|
||||
flags.recurse = false;
|
||||
flags.colored = false;
|
||||
|
||||
int start = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!prefix("-", argv[i])) break;
|
||||
if (streql("--help", argv[i])) help();
|
||||
start++;
|
||||
if (streql("--color=auto", argv[i]) || streql("--color=yes", argv[i])) {
|
||||
flags.colored = true;
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 1; j < strlen(argv[i]); j++) {
|
||||
char c = argv[i][j];
|
||||
switch (c) {
|
||||
|
|
|
@ -2,19 +2,31 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void tail_file(FILE* file) {
|
||||
char* ring[10];
|
||||
memset(ring, 0, sizeof(char*) * 10);
|
||||
struct Flags {
|
||||
bool lines;
|
||||
int count;
|
||||
bool print_headers;
|
||||
bool dont_print_headers;
|
||||
bool print_as_grow;
|
||||
int grow_wait;
|
||||
};
|
||||
|
||||
int ring_len[10];
|
||||
static size_t tail_file_lines(FILE* file, unsigned int count, size_t skip) {
|
||||
char* ring[count];
|
||||
memset(ring, 0, sizeof(char*) * count);
|
||||
|
||||
int ring_len[count];
|
||||
|
||||
int index = 0;
|
||||
int size = 0;
|
||||
unsigned int size = 0;
|
||||
|
||||
int read;
|
||||
size_t len = 0;
|
||||
fseek(file, skip, SEEK_SET);
|
||||
size_t len = skip;
|
||||
char* line = NULL;
|
||||
while ((read = getline(&line, &len, file)) != -1) {
|
||||
|
||||
|
@ -23,57 +35,189 @@ static void tail_file(FILE* file) {
|
|||
ring_len[index] = read;
|
||||
|
||||
index++;
|
||||
index %= 10;
|
||||
if (size < 10) size++;
|
||||
index %= count;
|
||||
if (size < count) size++;
|
||||
|
||||
line = NULL;
|
||||
}
|
||||
|
||||
index += 10 - size;
|
||||
index %= 10;
|
||||
index += count - size;
|
||||
index %= count;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
fwrite(ring[index], ring_len[index], 1, stdout);
|
||||
free(ring[index]);
|
||||
index += 1;
|
||||
index %= 10;
|
||||
index %= count;
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static size_t tail_file_chars(FILE* file, unsigned int count, size_t skip) {
|
||||
char ring[count];
|
||||
memset(ring, 0, count);
|
||||
|
||||
int index = 0;
|
||||
unsigned int size = 0;
|
||||
|
||||
fseek(file, skip, SEEK_SET);
|
||||
int read = skip;
|
||||
int c;
|
||||
while((c = getc(file)) != EOF) {
|
||||
ring[index] = c;
|
||||
index++;
|
||||
read++;
|
||||
index %= count;
|
||||
if (size < count) size++;
|
||||
}
|
||||
|
||||
index += count - size;
|
||||
index %= count;
|
||||
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
putchar(ring[index]);
|
||||
index += 1;
|
||||
index %= count;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
static void help() {
|
||||
printf("Usage: tail [FILE]...\n\n");
|
||||
printf("Usage: tail [OPTIONS] [FILE]...\n\n");
|
||||
printf("Print last 10 lines of FILEs (or stdin) to.\n");
|
||||
printf("With more than one FILE, precede each with a filename header.\n");
|
||||
printf("With more than one FILE, precede each with a filename header.\n\n");
|
||||
printf("\t-c [+]N[bkm]\tPrint last N bytes\n");
|
||||
printf("\t-n N[bkm]\tPrint last N lines\n");
|
||||
printf("\t\t\t(b:*512 k:*1024 m:*1024^2)\n");
|
||||
printf("\t-q\t\tNever print headers\n");
|
||||
printf("\t-v\t\tAlways print headers\n");
|
||||
printf("\t-f\t\tPrint data as file grows\n");
|
||||
printf("\t-s SECONDS\tWait SECONDS between reads with -f\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
COMMAND(tail) {
|
||||
if (argc < 1) {
|
||||
tail_file(stdin);
|
||||
return EXIT_SUCCESS;
|
||||
static char* next_arg(int argc, char** argv, int index) {
|
||||
if (index >= argc) {
|
||||
error("error: expected another argument after option");
|
||||
}
|
||||
return argv[index];
|
||||
}
|
||||
|
||||
if (streql(argv[0], "--help")) help();
|
||||
|
||||
if (argc == 1) {
|
||||
FILE* file = get_file(argv[0], "r");
|
||||
tail_file(file);
|
||||
return EXIT_SUCCESS;
|
||||
static void print_header(char* path, struct Flags* flags, bool many) {
|
||||
if (flags->dont_print_headers) return;
|
||||
if (!many && !flags->print_headers) return;
|
||||
if (streql("-", path)) {
|
||||
printf("\n==> standard input <==\n");
|
||||
} else {
|
||||
printf("\n=>> %s <==\n", path);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
FILE* file;
|
||||
if (streql("-", argv[i])) {
|
||||
file = stdin;
|
||||
static void tail_file(char* path, struct Flags* flags, bool many) {
|
||||
FILE* file = get_file(path, "r");
|
||||
print_header(path, flags, many);
|
||||
|
||||
size_t skip = 0;
|
||||
while (true) {
|
||||
if (flags->lines) {
|
||||
skip = tail_file_lines(file, flags->count, skip);
|
||||
} else {
|
||||
file = get_file_s(argv[i], "r");
|
||||
if (file == NULL) continue;
|
||||
skip = tail_file_chars(file, flags->count, skip);
|
||||
}
|
||||
printf("\n==> %s <==\n", argv[i]);
|
||||
tail_file(file);
|
||||
if (!flags->print_as_grow) break;
|
||||
sleep(flags->grow_wait);
|
||||
get_file(path, "r");
|
||||
};
|
||||
}
|
||||
|
||||
COMMAND(tail) {
|
||||
|
||||
struct Flags flags;
|
||||
flags.count = 10;
|
||||
flags.dont_print_headers = false;
|
||||
flags.print_headers = false;
|
||||
flags.lines = true;
|
||||
flags.print_as_grow = false;
|
||||
flags.grow_wait = 10;
|
||||
|
||||
int start = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!prefix("-", argv[i])) break;
|
||||
if (streql(argv[0], "--help")) help();
|
||||
start++;
|
||||
int i_s = i;
|
||||
for (size_t j = 1; j < strlen(argv[i_s]); j++) {
|
||||
char c = argv[i_s][j];
|
||||
switch(c) {
|
||||
case 'c': {
|
||||
start++;
|
||||
flags.lines = false;
|
||||
char* arg = next_arg(argc, argv, ++i);
|
||||
long int bkm = get_blkm(arg);
|
||||
if (bkm < 1) {
|
||||
error("error: bkm cannot be less than 1");
|
||||
}
|
||||
flags.count = bkm;
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
start++;
|
||||
flags.lines = true;
|
||||
char* arg = next_arg(argc, argv, ++i);
|
||||
long int bkm = get_blkm(arg);
|
||||
if (bkm < 1) {
|
||||
error("error: bkm cannot be less than 1");
|
||||
}
|
||||
flags.count = bkm;
|
||||
break;
|
||||
}
|
||||
case 'q':
|
||||
flags.dont_print_headers = true;
|
||||
break;
|
||||
case 'v':
|
||||
flags.print_headers = true;
|
||||
break;
|
||||
case 'f':
|
||||
flags.print_as_grow = true;
|
||||
break;
|
||||
case 's': {
|
||||
start++;
|
||||
char* arg = next_arg(argc, argv, ++i);
|
||||
long int sec = get_number(arg);
|
||||
if (sec < 1) {
|
||||
error("error: wait seconds cannot be less than 1");
|
||||
}
|
||||
flags.grow_wait = sec;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
error("error: unknown option -%c", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = argc - start;
|
||||
|
||||
if (count < 1) {
|
||||
tail_file_lines(stdin, 10, 0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
tail_file(argv[start], &flags, false);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
tail_file(argv[start + i], &flags, true);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -20,7 +20,7 @@ int main (ARGUMENTS) {
|
|||
if (argc < 2) {
|
||||
printf("usage: lazysphere [function [arguments]...]\n\n");
|
||||
printf("currently defined functions:\n");
|
||||
printf("\tdd, cat, yes, echo, printf, id, groups, ls, tail\n");
|
||||
printf("\tdd, cat, yes, echo, printf, id, groups, ls, tail, head\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
argc--;
|
||||
|
@ -52,6 +52,8 @@ int main (ARGUMENTS) {
|
|||
return ls(NEXT_ARGS);
|
||||
} else if (streql(cmd, "tail")) {
|
||||
return tail(NEXT_ARGS);
|
||||
} else if (streql(cmd, "head")) {
|
||||
return head(NEXT_ARGS);
|
||||
} else {
|
||||
error("error: invalid command %s", cmd);
|
||||
}
|
||||
|
|
25
src/shared.c
25
src/shared.c
|
@ -34,6 +34,7 @@ FILE* get_file_s(const char* path, const char* type) {
|
|||
}
|
||||
|
||||
FILE* get_file(const char* path, const char* type) {
|
||||
if (streql("-", path)) return stdin;
|
||||
FILE* file = get_file_s(path, type);
|
||||
if (file == NULL) exit(EXIT_FAILURE);
|
||||
return file;
|
||||
|
@ -48,6 +49,30 @@ long int get_number(const char* text) {
|
|||
return n;
|
||||
}
|
||||
|
||||
long int get_blkm(const char* text) {
|
||||
char* end;
|
||||
long int n = strtol(text, &end, 10);
|
||||
if (text == end) {
|
||||
error("error: %s is not a valid bkm", text);
|
||||
}
|
||||
if (*end == '\0') return n;
|
||||
switch (*end) {
|
||||
case 'K':
|
||||
case 'k':
|
||||
return n * 1024;
|
||||
case 'B':
|
||||
case 'b':
|
||||
return n * 512;
|
||||
case 'M':
|
||||
case 'm':
|
||||
return n * 1024 * 1204;
|
||||
default:
|
||||
error("error: invalid bkm type %c", *end);
|
||||
}
|
||||
// shouldnt get here anyways
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool streql(const char* a, const char* b) {
|
||||
if (*a != *b) return false;
|
||||
int n = 0;
|
||||
|
|
|
@ -10,6 +10,7 @@ void error(const char* format, ...);
|
|||
FILE* get_file_s(const char* path, const char* type);
|
||||
FILE* get_file(const char* path, const char* type);
|
||||
long int get_number(const char* text);
|
||||
long int get_blkm(const char* text);
|
||||
|
||||
bool streql(const char* a, const char* b);
|
||||
bool prefix(const char* pre, const char* str);
|
||||
|
|
Loading…
Reference in a new issue