From 54093060cb9fcc794e0eec21f5e0d51b288e30c8 Mon Sep 17 00:00:00 2001 From: Dan Cross Date: Tue, 9 Oct 2018 15:55:16 +0000 Subject: [PATCH] More cleanups. More cleaning up construction of arrays of things. Introduce a utility function called, `split_on_space` that tokenizes a string on a space character; use it in most places where `strtok()` had been called. More use of the ptr_vector type. Introduce a utility function to get access to the pointers without consuming the vector; this is used in the files code. Signed-off-by: Dan Cross --- src/bbs.h | 2 + src/blog.c | 2 +- src/bluewave.c | 20 +---- src/doors.c | 9 +-- src/email.c | 49 ++++++------ src/files.c | 210 +++++++++++++++++++++---------------------------- src/strings.c | 93 ++++++++++++---------- src/util.c | 5 ++ 8 files changed, 175 insertions(+), 215 deletions(-) diff --git a/src/bbs.h b/src/bbs.h index e728dae..b78de7d 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -273,6 +273,7 @@ extern int ptr_vector_put(struct ptr_vector *vec, void *p, size_t i); extern void *ptr_vector_del(struct ptr_vector *vec, size_t i); extern int ptr_vector_append(struct ptr_vector *vec, void *p); extern size_t ptr_vector_len(struct ptr_vector *vec); +extern void **ptr_vector_ptrs(struct ptr_vector *vec); extern void **consume_ptr_vector(struct ptr_vector *vec); extern void destroy_ptr_vector(struct ptr_vector *vec); @@ -388,6 +389,7 @@ extern void bwave_upload_reply(); extern void load_strings(); extern char *get_string(int offset); extern void chomp(char *string); +extern char **split_on_space(char *str, size_t *lenp); extern void die(const char *msg); extern void *malloz(size_t size); diff --git a/src/blog.c b/src/blog.c index 3bb8831..9a04d7e 100644 --- a/src/blog.c +++ b/src/blog.c @@ -48,7 +48,7 @@ int blog_load(struct blog_entry_t ***entries) { sqlite3_close(db); blog_entry_count = ptr_vector_len(&blog_entries); - *entries = consume_ptr_vector(&blog_entries); + *entries = (struct blog_entry_t **)consume_ptr_vector(&blog_entries); return blog_entry_count; } diff --git a/src/bluewave.c b/src/bluewave.c index 2f6a1a8..58e6d08 100644 --- a/src/bluewave.c +++ b/src/bluewave.c @@ -318,7 +318,6 @@ void bwave_create_packet() { int totmsgs = 0; int ret; char **args, *arg; - struct ptr_vector args_vec; char *cmd; pid_t pid; @@ -530,14 +529,7 @@ void bwave_create_packet() { dup2(bbs_stdin, STDIN_FILENO); } - init_ptr_vector(&args_vec); - arg = strtok(buffer, " "); - ptr_vector_append(&args_vec, arg); - while (arg != NULL) { - arg = strtok(NULL, " "); - ptr_vector_append(&args_vec, arg); - } - args = (char **)consume_ptr_vector(&args_vec); + args = split_on_space(buffer, NULL); cmd = args[0]; pid = fork(); if (pid == 0) { @@ -813,7 +805,6 @@ void bwave_upload_reply() { char *isql = "INSERT INTO email (sender, recipient, subject, body, date, seen) VALUES(?, ?, ?, ?, ?, 0)"; char *err_msg = 0; char **args, *arg; - struct ptr_vector args_vec; char *cmd; pid_t pid; int ret; @@ -866,14 +857,7 @@ void bwave_upload_reply() { dup2(bbs_stderr, STDERR_FILENO); dup2(bbs_stdin, STDIN_FILENO); } - init_ptr_vector(&args_vec); - arg = strtok(buffer, " "); - ptr_vector_append(&args_vec, arg); - while (arg != NULL) { - arg = strtok(NULL, " "); - ptr_vector_append(&args_vec, arg); - } - args = (char **)consume_ptr_vector(&args_vec); + args = split_on_space(buffer, NULL); cmd = args[0]; pid = fork(); if (pid == 0) { diff --git a/src/doors.c b/src/doors.c index ce8bb90..d8d892b 100644 --- a/src/doors.c +++ b/src/doors.c @@ -523,14 +523,7 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c if (cwd != NULL) { chdir(cwd); } - init_ptr_vector(&args_vec); - arg = strtok(buffer, " "); - ptr_vector_append(&args_vec, arg); - while (arg != NULL) { - arg = strtok(NULL, " "); - ptr_vector_append(&args_vec, arg); - } - args = (char **)consume_ptr_vector(&args_vec); + args = split_on_space(buffer, NULL); cmd = args[0]; pid = fork(); if (pid == 0) { diff --git a/src/email.c b/src/email.c index 8b7ad5a..6807603 100644 --- a/src/email.c +++ b/src/email.c @@ -143,6 +143,8 @@ void show_email(struct user_record *user, int msgno, int email_count, struct ema int quit = 0; while (!quit) { + struct ptr_vector lines_vec; + char *line; s_printf(get_string(57), emails[msgno]->from); s_printf(get_string(58), emails[msgno]->subject); @@ -158,24 +160,19 @@ void show_email(struct user_record *user, int msgno, int email_count, struct ema msg_line_count = 0; start_line = 0; + init_ptr_vector(&lines_vec); // count the number of lines... for (z = 0; z < strlen(emails[msgno]->body); z++) { if (emails[msgno]->body[z] == '\r' || chars == 79) { - if (msg_line_count == 0) { - msg_lines = (char **)malloz(sizeof(char *)); - } else { - msg_lines = (char **)realloc(msg_lines, sizeof(char *) * (msg_line_count + 1)); - } - - msg_lines[msg_line_count] = (char *)malloz(sizeof(char) * (z - start_line + 1)); + line = (char *)malloz(z - start_line + 1); + ptr_vector_append(&lines_vec, line); if (z == start_line) { - msg_lines[msg_line_count][0] = '\0'; + line[0] = '\0'; } else { - strncpy(msg_lines[msg_line_count], &emails[msgno]->body[start_line], z - start_line); - msg_lines[msg_line_count][z - start_line] = '\0'; + strncpy(line, &emails[msgno]->body[start_line], z - start_line); + line[z - start_line] = '\0'; } - msg_line_count++; if (emails[msgno]->body[z] == '\r') { start_line = z + 1; } else { @@ -186,6 +183,8 @@ void show_email(struct user_record *user, int msgno, int email_count, struct ema chars++; } } + msg_line_count = ptr_vector_len(&lines_vec); + msg_lines = (char **)consume_ptr_vector(&lines_vec); lines = 0; @@ -362,6 +361,7 @@ void list_emails(struct user_record *user) { int rc; char *sql = "SELECT sender,subject,seen,date,body,id FROM email WHERE recipient LIKE ?"; struct email_msg **emails; + struct ptr_vector emails_vec; int email_count; int msgid; int msgtoread; @@ -395,24 +395,19 @@ void list_emails(struct user_record *user) { msgid = 0; s_printf(get_string(63)); - email_count = 0; + init_ptr_vector(&emails_vec); while (sqlite3_step(res) == SQLITE_ROW) { - if (email_count == 0) { - emails = (struct email_msg **)malloz(sizeof(struct email_msg *)); - } else { - emails = (struct email_msg **)realloc(emails, sizeof(struct email_msg *) * (email_count + 1)); - } - - emails[email_count] = (struct email_msg *)malloz(sizeof(struct email_msg)); - - emails[email_count]->from = strdup((char *)sqlite3_column_text(res, 0)); - emails[email_count]->subject = strdup((char *)sqlite3_column_text(res, 1)); - emails[email_count]->seen = sqlite3_column_int(res, 2); - emails[email_count]->date = (time_t)sqlite3_column_int(res, 3); - emails[email_count]->body = strdup((char *)sqlite3_column_text(res, 4)); - emails[email_count]->id = sqlite3_column_int(res, 5); - email_count++; + struct email_msg *email = (struct email_msg *)malloz(sizeof(struct email_msg)); + ptr_vector_append(&emails_vec, email); + email->from = strdup((char *)sqlite3_column_text(res, 0)); + email->subject = strdup((char *)sqlite3_column_text(res, 1)); + email->seen = sqlite3_column_int(res, 2); + email->date = (time_t)sqlite3_column_int(res, 3); + email->body = strdup((char *)sqlite3_column_text(res, 4)); + email->id = sqlite3_column_int(res, 5); } + email_count = ptr_vector_len(&emails_vec); + emails = (struct email_msg **)consume_ptr_vector(&emails_vec); sqlite3_finalize(res); sqlite3_close(db); diff --git a/src/files.c b/src/files.c index e2dcd19..392708a 100644 --- a/src/files.c +++ b/src/files.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "Xmodem/zmodem.h" #include "bbs.h" #include "lua/lua.h" @@ -299,7 +300,6 @@ char *get_file_id_diz(char *filename) { int ret; pid_t pid; char **args; - int arg_count; char *cmd; ext = 0; arch = -1; @@ -370,15 +370,8 @@ char *get_file_id_diz(char *filename) { dup2(bbs_stderr, STDERR_FILENO); dup2(bbs_stdin, STDIN_FILENO); } - args = (char **)malloz(sizeof(char *)); - arg_count = 0; - args[arg_count] = strtok(buffer, " "); - while (args[arg_count] != NULL) { - arg_count++; - args = (char **)realloc(args, sizeof(char *) * (arg_count + 1)); - args[arg_count] = strtok(NULL, " "); - } - cmd = strdup(args[0]); + args = split_on_space(buffer, NULL); + cmd = args[0]; pid = fork(); if (pid == 0) { execvp(cmd, args); @@ -388,7 +381,6 @@ char *get_file_id_diz(char *filename) { } else { ret = -1; } - free(cmd); free(args); if (sshBBS) { @@ -1009,10 +1001,12 @@ void do_list_files(struct file_entry **files_e, int files_c) { int z; int k; int match; + struct ptr_vector files; char buffer[6]; s_printf("\r\n"); + init_ptr_vector(&files); for (i = 0; i < files_c; i++) { file_size = files_e[i]->size; if (file_size > 1024 * 1024 * 1024) { @@ -1066,17 +1060,14 @@ void do_list_files(struct file_entry **files_e, int files_c) { } } if (match == 0) { - if (tagged_count == 0) { - tagged_files = (struct tagged_file **)malloz(sizeof(struct tagged_file *)); - } else { - tagged_files = (struct tagged_file **)realloc(tagged_files, sizeof(struct tagged_file *) * (tagged_count + 1)); - } - tagged_files[tagged_count] = (struct tagged_file *)malloz(sizeof(struct tagged_file)); - tagged_files[tagged_count]->filename = strdup(files_e[z]->filename); - tagged_files[tagged_count]->dir = files_e[z]->dir; - tagged_files[tagged_count]->sub = files_e[z]->sub; - tagged_files[tagged_count]->fid = files_e[z]->fid; + struct tagged_file *file = (struct tagged_file *)malloz(sizeof(struct tagged_file)); + file->filename = strdup(files_e[z]->filename); + file->dir = files_e[z]->dir; + file->sub = files_e[z]->sub; + file->fid = files_e[z]->fid; + ptr_vector_append(&files, file); tagged_count++; + tagged_files = (struct tagged_file **)ptr_vector_ptrs(&files); s_printf(get_string(71), basename(files_e[z]->filename)); } else { s_printf(get_string(72)); @@ -1124,17 +1115,14 @@ void do_list_files(struct file_entry **files_e, int files_c) { } } if (match == 0) { - if (tagged_count == 0) { - tagged_files = (struct tagged_file **)malloz(sizeof(struct tagged_file *)); - } else { - tagged_files = (struct tagged_file **)realloc(tagged_files, sizeof(struct tagged_file *) * (tagged_count + 1)); - } - tagged_files[tagged_count] = (struct tagged_file *)malloz(sizeof(struct tagged_file)); - tagged_files[tagged_count]->filename = strdup(files_e[z]->filename); - tagged_files[tagged_count]->dir = files_e[z]->dir; - tagged_files[tagged_count]->sub = files_e[z]->sub; - tagged_files[tagged_count]->fid = files_e[z]->fid; + struct tagged_file *file = (struct tagged_file *)malloz(sizeof(struct tagged_file)); + file->filename = strdup(files_e[z]->filename); + file->dir = files_e[z]->dir; + file->sub = files_e[z]->sub; + file->fid = files_e[z]->fid; + ptr_vector_append(&files, file); tagged_count++; + tagged_files = (struct tagged_file **)ptr_vector_ptrs(&files); s_printf(get_string(71), basename(files_e[z]->filename)); } else { s_printf(get_string(72)); @@ -1171,17 +1159,14 @@ void do_list_files(struct file_entry **files_e, int files_c) { } } if (match == 0) { - if (tagged_count == 0) { - tagged_files = (struct tagged_file **)malloz(sizeof(struct tagged_file *)); - } else { - tagged_files = (struct tagged_file **)realloc(tagged_files, sizeof(struct tagged_file *) * (tagged_count + 1)); - } - tagged_files[tagged_count] = (struct tagged_file *)malloz(sizeof(struct tagged_file)); - tagged_files[tagged_count]->filename = strdup(files_e[z]->filename); - tagged_files[tagged_count]->dir = files_e[z]->dir; - tagged_files[tagged_count]->sub = files_e[z]->sub; - tagged_files[tagged_count]->fid = files_e[z]->fid; + struct tagged_file *file = (struct tagged_file *)malloz(sizeof(struct tagged_file)); + file->filename = strdup(files_e[z]->filename); + file->dir = files_e[z]->dir; + file->sub = files_e[z]->sub; + file->fid = files_e[z]->fid; + ptr_vector_append(&files, file); tagged_count++; + tagged_files = (struct tagged_file **)ptr_vector_ptrs(&files); s_printf(get_string(71), basename(files_e[z]->filename)); } else { s_printf(get_string(72)); @@ -1201,7 +1186,7 @@ void file_search() { char buffer[PATH_MAX]; char sqlbuffer[1024]; char **searchterms; - int searchterm_count = 0; + size_t searchterm_count = 0; char *ptr; int i; int j; @@ -1212,6 +1197,7 @@ void file_search() { int rc; int files_c; struct file_entry **files_e; + struct ptr_vector files; s_printf(get_string(236)); ch = s_getc(); @@ -1240,18 +1226,9 @@ void file_search() { s_printf(get_string(238)); return; } - ptr = strtok(buffer, " "); - while (ptr != NULL) { - if (searchterm_count == 0) { - searchterms = (char **)malloz(sizeof(char *)); - } else { - searchterms = (char **)realloc(searchterms, sizeof(char *) * (searchterm_count + 1)); - } - - searchterms[searchterm_count] = malloz(strlen(ptr) + 3); - sprintf(searchterms[searchterm_count], "%%%s%%", ptr); - searchterm_count++; - ptr = strtok(NULL, " "); + searchterms = split_on_space(buffer, &searchterm_count); + for (size_t i = 0; i < searchterm_count; ++i) { + searchterms[i] = str3dup("%%", searchterms[i], "%%"); } if (stype == 0) { snprintf(sqlbuffer, 1024, "select id, filename, description, size, dlcount, uploaddate from files where approved=1 AND (filename LIKE ?"); @@ -1314,23 +1291,21 @@ void file_search() { } } + init_ptr_vector(&files); while (sqlite3_step(res) == SQLITE_ROW) { - if (files_c == 0) { - files_e = (struct file_entry **)malloz(sizeof(struct file_entry *)); - } else { - files_e = (struct file_entry **)realloc(files_e, sizeof(struct file_entry *) * (files_c + 1)); - } - files_e[files_c] = (struct file_entry *)malloz(sizeof(struct file_entry)); - files_e[files_c]->fid = sqlite3_column_int(res, 0); - files_e[files_c]->filename = strdup((char *)sqlite3_column_text(res, 1)); - files_e[files_c]->description = strdup((char *)sqlite3_column_text(res, 2)); - files_e[files_c]->size = sqlite3_column_int(res, 3); - files_e[files_c]->dlcount = sqlite3_column_int(res, 4); - files_e[files_c]->uploaddate = sqlite3_column_int(res, 5); - files_e[files_c]->dir = gUser->cur_file_dir; - files_e[files_c]->sub = gUser->cur_file_sub; - files_c++; + struct file_entry *file = (struct file_entry *)malloz(sizeof(struct file_entry)); + file->fid = sqlite3_column_int(res, 0); + file->filename = strdup((char *)sqlite3_column_text(res, 1)); + file->description = strdup((char *)sqlite3_column_text(res, 2)); + file->size = sqlite3_column_int(res, 3); + file->dlcount = sqlite3_column_int(res, 4); + file->uploaddate = sqlite3_column_int(res, 5); + file->dir = gUser->cur_file_dir; + file->sub = gUser->cur_file_sub; + ptr_vector_append(&files, file); } + files_c = ptr_vector_len(&files); + files_e = (struct file_entry **)consume_ptr_vector(&files); sqlite3_finalize(res); sqlite3_close(db); @@ -1376,23 +1351,22 @@ void file_search() { } } + init_ptr_vector(&files); while (sqlite3_step(res) == SQLITE_ROW) { - if (files_c == 0) { - files_e = (struct file_entry **)malloz(sizeof(struct file_entry *)); - } else { - files_e = (struct file_entry **)realloc(files_e, sizeof(struct file_entry *) * (files_c + 1)); - } - files_e[files_c] = (struct file_entry *)malloz(sizeof(struct file_entry)); - files_e[files_c]->fid = sqlite3_column_int(res, 0); - files_e[files_c]->filename = strdup((char *)sqlite3_column_text(res, 1)); - files_e[files_c]->description = strdup((char *)sqlite3_column_text(res, 2)); - files_e[files_c]->size = sqlite3_column_int(res, 3); - files_e[files_c]->dlcount = sqlite3_column_int(res, 4); - files_e[files_c]->uploaddate = sqlite3_column_int(res, 5); - files_e[files_c]->dir = gUser->cur_file_dir; - files_e[files_c]->sub = gUser->cur_file_sub; - files_c++; + struct file_entry *file = (struct file_entry *)malloz(sizeof(struct file_entry)); + file->fid = sqlite3_column_int(res, 0); + file->filename = strdup((char *)sqlite3_column_text(res, 1)); + file->description = strdup((char *)sqlite3_column_text(res, 2)); + file->size = sqlite3_column_int(res, 3); + file->dlcount = sqlite3_column_int(res, 4); + file->uploaddate = sqlite3_column_int(res, 5); + file->dir = gUser->cur_file_dir; + file->sub = gUser->cur_file_sub; + ptr_vector_append(&files, file); } + files_c = ptr_vector_len(&files); + files_e = (struct file_entry **)consume_ptr_vector(&files); + sqlite3_finalize(res); sqlite3_close(db); } @@ -1422,6 +1396,7 @@ void list_files(struct user_record *user) { char ch; struct file_entry **files_e; + struct ptr_vector files; s_printf(get_string(233)); ch = s_getc(); @@ -1461,25 +1436,22 @@ void list_files(struct user_record *user) { sqlite3_bind_int(res, 1, userlaston); } - files_c = 0; - + init_ptr_vector(&files); while (sqlite3_step(res) == SQLITE_ROW) { - if (files_c == 0) { - files_e = (struct file_entry **)malloz(sizeof(struct file_entry *)); - } else { - files_e = (struct file_entry **)realloc(files_e, sizeof(struct file_entry *) * (files_c + 1)); - } - files_e[files_c] = (struct file_entry *)malloz(sizeof(struct file_entry)); - files_e[files_c]->fid = sqlite3_column_int(res, 0); - files_e[files_c]->filename = strdup((char *)sqlite3_column_text(res, 1)); - files_e[files_c]->description = strdup((char *)sqlite3_column_text(res, 2)); - files_e[files_c]->size = sqlite3_column_int(res, 3); - files_e[files_c]->dlcount = sqlite3_column_int(res, 4); - files_e[files_c]->uploaddate = sqlite3_column_int(res, 5); - files_e[files_c]->dir = user->cur_file_dir; - files_e[files_c]->sub = user->cur_file_sub; - files_c++; + struct file_entry *file = (struct file_entry *)malloz(sizeof(struct file_entry)); + file->fid = sqlite3_column_int(res, 0); + file->filename = strdup((char *)sqlite3_column_text(res, 1)); + file->description = strdup((char *)sqlite3_column_text(res, 2)); + file->size = sqlite3_column_int(res, 3); + file->dlcount = sqlite3_column_int(res, 4); + file->uploaddate = sqlite3_column_int(res, 5); + file->dir = user->cur_file_dir; + file->sub = user->cur_file_sub; + ptr_vector_append(&files, file); } + files_c = ptr_vector_len(&files); + files_e = (struct file_entry **)consume_ptr_vector(&files); + sqlite3_finalize(res); sqlite3_close(db); @@ -1504,21 +1476,19 @@ void choose_subdir() { int start = 0; int selected = 0; char c; + struct ptr_vector subs; + init_ptr_vector(&subs); for (i = 0; i < conf.file_directories[gUser->cur_file_dir]->file_sub_count; i++) { if (conf.file_directories[gUser->cur_file_dir]->file_subs[i]->download_sec_level <= gUser->sec_level) { - if (list_tmp == 0) { - sub_tmp = (struct subdir_tmp_t **)malloz(sizeof(struct subdir_tmp_t *)); - } else { - sub_tmp = (struct subdir_tmp_t **)realloc(sub_tmp, sizeof(struct subdir_tmp_t *) * (list_tmp + 1)); - } - - sub_tmp[list_tmp] = (struct subdir_tmp_t *)malloz(sizeof(struct subdir_tmp_t)); - sub_tmp[list_tmp]->sub = conf.file_directories[gUser->cur_file_dir]->file_subs[i]; - sub_tmp[list_tmp]->index = i; - list_tmp++; + struct subdir_tmp_t *sub = (struct subdir_tmp_t *)malloz(sizeof(struct subdir_tmp_t)); + sub->sub = conf.file_directories[gUser->cur_file_dir]->file_subs[i]; + sub->index = i; + ptr_vector_append(&subs, sub); } } + list_tmp = ptr_vector_len(&subs); + sub_tmp = (struct subdir_tmp_t **)consume_ptr_vector(&subs); while (1) { if (redraw) { @@ -1642,21 +1612,19 @@ void choose_directory() { int start = 0; int selected = 0; char c; + struct ptr_vector dirs; + init_ptr_vector(&dirs); for (i = 0; i < conf.file_directory_count; i++) { if (conf.file_directories[i]->sec_level <= gUser->sec_level) { - if (list_tmp == 0) { - dir_tmp = (struct dir_tmp_t **)malloz(sizeof(struct dir_tmp_t *)); - } else { - dir_tmp = (struct dir_tmp_t **)realloc(dir_tmp, sizeof(struct dir_tmp_t *) * (list_tmp + 1)); - } - - dir_tmp[list_tmp] = (struct dir_tmp_t *)malloz(sizeof(struct dir_tmp_t)); - dir_tmp[list_tmp]->dir = conf.file_directories[i]; - dir_tmp[list_tmp]->index = i; - list_tmp++; + struct dir_tmp_t *dir = (struct dir_tmp_t *)malloz(sizeof(struct dir_tmp_t)); + dir->dir = conf.file_directories[i]; + dir->index = i; + ptr_vector_append(&dirs, dir); } } + list_tmp = ptr_vector_len(&dirs); + dir_tmp = (struct dir_tmp_t **)consume_ptr_vector(&dirs); while (1) { if (redraw) { diff --git a/src/strings.c b/src/strings.c index 725e1b9..fda3e1b 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1,53 +1,55 @@ -#include "bbs.h" +#include #include #include #include +#include "bbs.h" + extern struct bbs_config conf; char *undefined = "Undefined String"; -char **strings; +static struct ptr_vector strings; int string_count; -void chomp(char *string) { - while (strlen(string) && (string[strlen(string) - 1] == '\r' || string[strlen(string) - 1] == '\n')) { - string[strlen(string) - 1] = '\0'; +void chomp(char *str) { + char *end; + assert(str != NULL); + size_t len = strlen(str); + if (len == 0) { + return; + } + end = str + len - 1; + while (end != str && (*end == '\r' || *end == '\n')) { + *end-- = '\0'; } } -char *parse_newlines(char *string) { - char *newstring = (char *)malloz(strlen(string) + 1); - int pos = 0; - int i; - for (i = 0; i < strlen(string); i++) { - if (string[i] == '\\') { - if (i < strlen(string) - 1) { - i++; - if (string[i] == 'n') { - newstring[pos++] = '\n'; - } else if (string[i] == 'r') { - newstring[pos++] = '\r'; - } else if (string[i] == '\\') { - newstring[pos++] = '\\'; - } else if (string[i] == 'e') { - newstring[pos++] = '\e'; - } - newstring[pos] = '\0'; - } - } else { - newstring[pos++] = string[i]; - newstring[pos] = '\0'; +char *parse_newlines(char *str) { + char *nstring = strdup(str); + char *s, *p; + for (s = p = nstring; *s != '\0'; ++s) { + if (*s != '\\') { + *p++ = *s; + continue; + } + switch (*++s) { + case '\0': continue; + case 'n': *p++ = '\n'; break; + case 'r': *p++ = '\r'; break; + case 'e': *p++ = '\e'; break; + case '\\': *p++ = '\\'; break; } } - return newstring; + *p = '\0'; + return nstring; } char *get_string(int offset) { - if (offset >= string_count) { + char *str = ptr_vector_get(&strings, offset); + if (str == NULL) { return undefined; } - - return strings[offset]; + return str; } void load_strings() { @@ -65,19 +67,30 @@ void load_strings() { exit(-1); } - string_count = 0; - + init_ptr_vector(&strings); fgets(buffer, 1024, fptr); while (!feof(fptr)) { chomp(buffer); - if (string_count == 0) { - strings = (char **)malloz(sizeof(char *)); - } else { - strings = (char **)realloc(strings, sizeof(char *) * (string_count + 1)); - } - strings[string_count] = parse_newlines(buffer); - string_count++; + ptr_vector_append(&strings, parse_newlines(buffer)); fgets(buffer, 1024, fptr); } fclose(fptr); } + +char **split_on_space(char *str, size_t *lenp) { + struct ptr_vector tokens; + char *token; + + init_ptr_vector(&tokens); + token = strtok(str, " "); + ptr_vector_append(&tokens, token); + while (token != NULL) { + token = strtok(NULL, " "); + ptr_vector_append(&tokens, token); + } + if (lenp != NULL) { + *lenp = ptr_vector_len(&tokens); + } + + return (char **)consume_ptr_vector(&tokens); +} diff --git a/src/util.c b/src/util.c index ec7b85a..6bfd491 100644 --- a/src/util.c +++ b/src/util.c @@ -153,6 +153,11 @@ size_t ptr_vector_len(struct ptr_vector *vec) { return vec->len; } +void **ptr_vector_ptrs(struct ptr_vector *vec) { + assert(vec != NULL); + return vec->ptrs; +} + void **consume_ptr_vector(struct ptr_vector *vec) { assert(vec != NULL); void **ps = realloc(vec->ptrs, vec->len * sizeof(void *));