* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*/
-/*Modified 2003 by Andre Noll */
+/*Modified 2003, 2006 by Andre Noll */
#include <SDL/SDL.h>
#include "SFont.h"
void PutString2(SDL_Surface * Surface, SFont_FontInfo * Font, int x, int y,
- char *text)
+ const char *text)
{
int ofs;
int i = 0;
}
}
}
-#if 0
-void PutString(SDL_Surface * Surface, int x, int y, char *text)
-{
- PutString2(Surface, &InternalFont, x, y, text);
-}
-#endif
int TextWidth2(SFont_FontInfo * Font, char *text)
{
int ofs = 0;
return x;
}
-#if 0
-int TextWidth(char *text)
-{
- return TextWidth2(&InternalFont, text);
-}
-#endif
-
-void XCenteredString2(SDL_Surface * Surface, SFont_FontInfo * Font, int y,
- char *text)
-{
- PutString2(Surface, Font, Surface->w / 2 - TextWidth2(Font, text) / 2,
- y, text);
-}
-
-#if 0
-void XCenteredString(SDL_Surface * Surface, int y, char *text)
-{
- XCenteredString2(Surface, &InternalFont, y, text);
-}
-#endif
-
void SFont_InternalInput(SDL_Surface * Dest, SFont_FontInfo * Font, int x,
- int y, int PixelWidth, char *text)
+ int y, int PixelWidth, char *text)
{
SDL_Event event;
int ch = -1, blink = 0;
// Destination: the suface you want to blit to
// text: a string containing the text you want to blit.
void PutString (SDL_Surface *Surface, int x, int y, char *text);
-void PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text);
+void PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, const char *text);
// Returns the width of "text" in pixels
int TextWidth(char *text);
enum {E_SYNTAX, E_READ, E_WRITE, E_SOCKET, E_INIT_SOCK_ADDR, E_CONNECT, E_CREDENTIALS, E_SELECT, E_OVERRUN};
-void para_log(__unused int ll, __unused char* fmt,...) /* no logging */
+void para_log(__unused int ll, __unused const char* fmt,...) /* no logging */
{
}
static FILE *logfile;
static const struct timeval restart_delay = {0, 300 * 1000};
-static struct audio_format_info afi[] = {
-
-[AUDIO_FORMAT_MP3] =
- {
- .write_cmd = "para_play",
- },
-[AUDIO_FORMAT_OGG] =
- {
- .write_cmd = "para_play",
- },
-};
+static struct audio_format_info afi[NUM_AUDIO_FORMATS];
static struct audiod_command cmds[] = {
{
/*
* log function. first argument is loglevel.
*/
-void para_log(int ll, char* fmt,...)
+void para_log(int ll, const char* fmt,...)
{
va_list argp;
FILE *outfd;
exit(status);
}
-static char *glob_cmd(char *cmd)
+__malloc static char *glob_cmd(char *cmd)
{
char *ret, *replacement;
struct timeval tmp, delay, rss; /* real stream start */
int ret, fds[3] = {1, -1, -1};
struct slot_info *s = &slot[slot_num];
struct audio_format_info *a = &afi[s->format];
- char *glob = glob_cmd(a->write_cmd);
+ char *glob = NULL;
- PARA_INFO_LOG("starting stream writer: %s\n", glob? glob : a->write_cmd);
+ if (a->write_cmd)
+ glob = glob_cmd(a->write_cmd);
+ if (!glob)
+ glob = para_strdup("para_play");
+ PARA_INFO_LOG("starting stream writer: %s\n", glob);
open_filters(slot_num);
-
- ret = para_exec_cmdline_pid(&s->wpid, glob? glob : a->write_cmd, fds);
+ ret = para_exec_cmdline_pid(&s->wpid, glob, fds);
free(glob);
if (ret < 0) {
PARA_ERROR_LOG("exec failed (%d)\n", ret);
if (ret < 0)
goto out;
PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], filters[j].name);
- ret = add_filter(i, "wav");
+ ret = add_filter(i, para_strdup("wav"));
if (ret < 0)
goto out;
PARA_INFO_LOG("%s -> default filter: wav\n", audio_formats[i]);
static int open_stat_pipe(void)
{
int ret, fd[3] = {-1, 1, 0};
- char *argv[] = {BINDIR "/para_client", "stat", NULL};
pid_t pid;
- ret = para_exec(&pid, BINDIR "/para_client", argv, fd);
+ ret = para_exec_cmdline_pid(&pid, BINDIR "/para_client stat", fd);
if (ret >= 0) {
ret = fd[1];
PARA_NOTICE_LOG("stat pipe opened, fd %d\n", ret);
/*
* client log function
*/
-void para_log(int ll, char* fmt,...)
+void para_log(int ll, const char* fmt,...)
{
va_list argp;
FILE *outfd;
/* valid command and sufficient perms */
alarm(0);
argc = split_args(command, &argv, '\n');
- argv[0] = cmd->name;
mmd_lock();
mmd->num_commands++;
mmd_unlock();
static char **choices;
/* no looging */
-void para_log(__unused int ll, __unused char *fmt,...)
+void para_log(__unused int ll, __unused const char *fmt,...)
{
}
* \param args the argument array for the command
* \param fds a pointer to a value-result array
*
- * This function uses fork/exec to create a new process. \a fds must be a
- * pointer to three integers, corresponding to stdin, stdout and stderr
- * respectively. It specifies how to deal with fd 0, 1, 2 in the child. The
- * contents of \a fds are interpreted as follows:
- *
- * - fd[i] < 0: leave fd \a i alone
- * - fd[i] = 0: dup fd \a i to /dev/null
- * - fd[i] > 0: create a pipe and dup i to one end of that pipe.
- * Upon return, fd[i] contains the file descriptor of the pipe.
- *
- * In any case, all unneeded filedescriptors are closed.
- *
* \return Negative on errors, positive on success.
*
* \sa null(4), pipe(2), dup2(2), fork(2), exec(3)
*/
-int para_exec(pid_t *pid, const char *file, char *const args[], int *fds)
+static int para_exec(pid_t *pid, const char *file, char *const args[], int *fds)
{
int ret, in[2] = {-1, -1}, out[2] = {-1, -1}, err[2] = {-1, -1},
null = -1; /* ;) */
/**
* exec the given command
*
- * \param pid the same meaning as in para_exec()
+ * \param pid will hold the pid of the created process upon return
* \param cmdline holds the command and its arguments, seperated by spaces
- * \param fds the same meaning as in para_exec()
+ * \param fds a pointer to a value-result array
+ *
+ * This function uses fork/exec to create a new process. \a fds must be a
+ * pointer to three integers, corresponding to stdin, stdout and stderr
+ * respectively. It specifies how to deal with fd 0, 1, 2 in the child. The
+ * contents of \a fds are interpreted as follows:
+ *
+ * - fd[i] < 0: leave fd \a i alone
+ * - fd[i] = 0: dup fd \a i to /dev/null
+ * - fd[i] > 0: create a pipe and dup i to one end of that pipe.
+ * Upon return, fd[i] contains the file descriptor of the pipe.
*
- * A wrapper for para_exec() which calls split_args() to seperate
- * the command line arguments.
+ * In any case, all unneeded filedescriptors are closed.
*
* \return positive on success, negative on errors
*/
-int para_exec_cmdline_pid(pid_t *pid, char *cmdline, int *fds)
+int para_exec_cmdline_pid(pid_t *pid, const char *cmdline, int *fds)
{
int argc, ret;
char **argv, *tmp = para_strdup(cmdline);
struct gengetopt_args_info args_info;
-void para_log(__unused int ll, char *fmt,...)
+void para_log(__unused int ll, const char *fmt,...)
{
va_list argp;
time_t t1;
return 1;
}
-static int client_cmd(char *cmd,...)
+static int client_cmd(const char *cmd,...)
{
int ret, fds[3] = {0, 0, 0};
- pid_t pid;
+ pid_t pid;
char *cmdline = make_message(BINDIR "/para_client %s", cmd);
PARA_INFO_LOG("%s", cmdline);
ret = para_exec_cmdline_pid(&pid, cmdline, fds);
struct gengetopt_args_info conf;
-__printf_2_3 void para_log(int ll, char* fmt,...)
+__printf_2_3 void para_log(int ll, const char* fmt,...)
{
va_list argp;
{
struct filter *f = &filters[filter_num];
int i, argc = 2;
- char *dummy_args[] = {"", "", NULL};
char **argv;
// PARA_DEBUG_LOG("%s, options: %s, parser: %p\n", f->name,
// options? options : "(none)", f->parse_config);
if (!f->parse_config)
- return options? -E_BAD_FILTER_OPTIONS : filter_num;
- if (options) {
-// PARA_DEBUG_LOG("options: %s\n", options);
- argc = split_args(options, &argv, ' ');
+ return strlen(options)? -E_BAD_FILTER_OPTIONS : filter_num;
+// PARA_DEBUG_LOG("options: %s\n", options);
+ argc = split_args(options, &argv, ' ');
// PARA_DEBUG_LOG("argc = %d, argv[0]: %s\n", argc, argv[0]);
- for (i = argc; i >= 0; i--)
- argv[i + 1] = argv[i];
- argc += 2;
- *conf = f->parse_config(argc, argv);
- } else {
- /* is it OK to have no options? */
- *conf = f->parse_config(2, dummy_args);
- }
+ for (i = argc; i >= 0; i--)
+ argv[i + 1] = argv[i];
+ argc += 2;
+ *conf = f->parse_config(argc, argv);
return *conf? filter_num : -E_BAD_FILTER_OPTIONS;
}
continue;
if (c && !filters[j].parse_config)
return -E_BAD_FILTER_OPTIONS;
- return parse_filter_args(j, c? fa + len + 1 : NULL, conf);
+ return parse_filter_args(j, c? fa + len + 1 :
+ fa + strlen(fa), conf);
}
return -E_UNSUPPORTED_FILTER;
}
#define COLOR_BOT 40
struct gui_command {
- char *key;
- char *name;
- char *description;
+ const char *key;
+ const char *name;
+ const char *description;
void (*handler)(void);
};
* print aligned string to curses window. This function always prints
* exactly len chars.
*/
-static int align_str(WINDOW* win, char *string, unsigned int len,
+static int align_str(WINDOW* win, const char *string, unsigned int len,
unsigned int align)
{
int num; /* of spaces */
return 1;
}
-__printf_2_3 static void print_in_bar(int color, char *fmt,...)
+__printf_2_3 static void print_in_bar(int color, const char *fmt,...)
{
char *msg;
/*
* print formated output to bot win and refresh
*/
-__printf_2_3 static void outputf(int color, char* fmt,...)
+__printf_2_3 static void outputf(int color, const char* fmt,...)
{
char *msg;
rb_add_entry(COLOR_OUTPUT, para_strdup(line));
}
-void para_log(int ll, char *fmt,...)
+void para_log(int ll, const char *fmt,...)
{
int color;
char *msg;
/*
* exit curses and print given message to stdout/stderr
*/
-__printf_2_3 static void msg_n_exit(int ret, char* fmt, ...)
+__printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...)
{
va_list argp;
FILE *outfd = ret? stderr: stdout;
int i;
for (i = 0; i < conf.key_map_given; ++i) {
- char *s = conf.key_map_arg[i], *handler, *arg,
- *desc = "", tmp[MAXLINE];
+ char *handler, *arg, *tmp = para_strdup(conf.key_map_arg[i]);
+ const char *handler_text = "???", *desc = NULL;
- strcpy(tmp, s);
- if (!split_key_map(tmp, &handler, &arg))
+ if (!split_key_map(tmp, &handler, &arg)) {
+ free(tmp);
return;
- switch(*handler) {
+ }
+ switch (*handler) {
case 'i':
- handler = "internal";
+ handler_text = "internal";
desc = command_list[find_cmd_byname(arg)].description;
break;
- case 'x': handler = "external"; break;
- case 'd': handler = "display "; break;
- case 'p': handler = "para "; break;
+ case 'x': handler_text = "external"; break;
+ case 'd': handler_text = "display "; break;
+ case 'p': handler_text = "para "; break;
}
- outputf(COLOR_MSG, "%s\t%s\t%s%s\t%s", tmp, handler, arg,
+ outputf(COLOR_MSG, "%s\t%s\t%s%s\t%s", tmp, handler_text, arg,
strlen(arg) < 8? "\t" : "",
- desc);
+ desc? desc : "");
+ free(tmp);
}
for (i = 0; command_list[i].handler; i++) {
struct gui_command gc = command_list[i];
}
print_in_bar(COLOR_MSG, "try \"para_gui -h\" or \"para_client help\" "
"for more info");
- return;
}
static void com_shrink_top_win(void)
{
int i = -1, match;
struct http_client *hc, *tmp;
- char *err_msg;
+ const char *err_msg;
list_for_each_entry_safe(hc, tmp, &clients, node) {
i++;
};
static int frame_size_index[] = {24000, 72000, 72000};
-static char *mode_text[] = {"stereo", "joint stereo", "dual channel", "mono", "invalid"};
+static const char *mode_text[] = {"stereo", "joint stereo", "dual channel", "mono", "invalid"};
static struct mp3info mp3;
static char mp3buf[8192];
return frequencies[h->version][h->freq];
}
-static char *header_mode(struct mp3header *h)
+static const char *header_mode(struct mp3header *h)
{
if (h->mode > 4)
h->mode = 4; /* invalid */
}
};
-static int real_query(char *query)
+static int real_query(const char *query)
{
if (!mysql_ptr)
return -E_NOTCONN;
* Use open connection given by mysql_ptr to query server. Returns a
* result pointer on succes and NULL on errors
*/
-static struct MYSQL_RES *get_result(char *query)
+static struct MYSQL_RES *get_result(const char *query)
{
void *result;
free(name);
return ret;
}
-static int change_stream(char *stream)
+static int change_stream(const char *stream)
{
char *query;
int ret;
char *q, *ebn;
long unsigned id;
int i, ret;
- char *field = strcmp(argv[0], "picass")? "numplayed" : "pic_id";
+ const char *field = strcmp(argv[0], "picass")? "numplayed" : "pic_id";
if (argc < 2)
return -E_MYSQL_SYNTAX;
/* create database */
static int com_cdb(int fd, int argc, char *argv[])
{
- char *query, *name;
+ char *query;
int ret;
- if (argc < 1)
- name = "paraslash";
- else {
- ret = -E_NAMETOOLONG;
- name = argv[1];
- if (strlen(name) > MAXLINE)
- goto out;
- }
if (mysql_ptr) {
PARA_INFO_LOG("%s", "closing database\n");
mysql_close(mysql_ptr);
ret = -E_MYSQL_INIT;
if (init_mysql_server() < 0 || !mysql_ptr)
goto out;
- query = make_message("create database %s", name);
+ conf.mysql_database_arg = para_strdup((argc < 1)?
+ "paraslash" : argv[1]);
+ query = make_message("create database %s", conf.mysql_database_arg);
ret = real_query(query);
free(query);
if (ret < 0)
goto out;
/* reconnect with database just created */
mysql_close(mysql_ptr);
- conf.mysql_database_arg = para_strdup(name);
ret = -E_MYSQL_INIT;
if (init_mysql_server() < 0 || !mysql_ptr)
goto out;
if (real_query("insert into streams (name, def) values "
"('current_stream', '(none)')") < 0)
goto out;
- ret = send_va_buffer(fd, "successfully created database %s\n", name);
+ ret = send_va_buffer(fd, "successfully created database %s\n",
+ conf.mysql_database_arg);
out:
return ret;
}
*
* @return Positive on success, \p -E_SEND on errors.
*/
-__printf_2_3 int send_va_buffer(int fd, char *fmt, ...)
+__printf_2_3 int send_va_buffer(int fd, const char *fmt, ...)
{
char *msg;
int ret;
int para_connect(int, struct sockaddr_in *);
int send_buffer(int, const char *);
int send_bin_buffer(int, const char *, size_t);
-int send_va_buffer(int, char *, ...);
+int send_va_buffer(int, const char *, ...);
int recv_buffer(int, char *, ssize_t);
int recv_bin_buffer(int, char *, ssize_t);
int para_accept(int, void *addr, socklen_t size);
/* exec */
int file_exists(const char *);
-int para_exec(pid_t *, const char *, char *const [], int *);
-int para_exec_cmdline_pid(pid_t *, char *, int *);
+int para_exec_cmdline_pid(pid_t *pid, const char *cmdline, int *fds);
/* signal */
int para_signal_init(void);
unsigned for_each_line(char *, int, void (*)(char *));
struct stat_item_data {
- char *prefix, *postfix;
+ const char *prefix, *postfix;
unsigned x, y, len;
int fg, bg, align;
};
/* gui_theme */
struct gui_theme {
- char *name;
- char *author;
+ const char *name;
+ const char *author;
int sb_fg, sb_bg;
int cmd_fg, cmd_bg;
int output_fg, output_bg;
int err_msg_fg, err_msg_bg;
int welcome_fg, welcome_bg;
int sep_fg, sep_bg;
- char *sep_str;
+ const char *sep_str;
int default_fg, default_bg;
int top_lines_default, top_lines_min;
#define CENTER 3
-__printf_2_3 void para_log(int, char*, ...);
+__printf_2_3 void para_log(int, const char*, ...);
/* taken from printf man page */
#define PARA_VSPRINTF(fmt, p) \
INIT_RECV_ERRLISTS;
-__printf_2_3 void para_log(int ll, char* fmt,...)
+__printf_2_3 void para_log(int ll, const char* fmt,...)
{
va_list argp;
struct stat_item{
- char *name;
- char *prefix;
- char *postfix;
- char *content;
- unsigned x;
- unsigned y;
- unsigned w;
- unsigned h;
+ const char *name;
+ const char *prefix;
+ const char *postfix;
+ char *content;
+ unsigned x;
+ unsigned y;
+ unsigned w;
+ unsigned h;
Uint8 r;
Uint8 g;
Uint8 b;
- int font;
- int align;
+ int font;
+ int align;
};
struct font {
static struct stat_item stat_items[NUM_STAT_ITEMS];
-void para_log(__unused int ll, __unused char* fmt,...) /* no logging */
+void para_log(__unused int ll, __unused const char* fmt,...) /* no logging */
{
}
s[SI_STATUS_BAR].prefix = "";
s[SI_STATUS_BAR].postfix = "";
- s[SI_STATUS_BAR].content = "";
s[SI_STATUS_BAR].x = 0;
s[SI_STATUS_BAR].y = 10;
s[SI_STATUS_BAR].w = 100;
s[SI_PLAY_TIME].prefix = "";
s[SI_PLAY_TIME].postfix = "";
- s[SI_PLAY_TIME].content = "";
s[SI_PLAY_TIME].x = 35;
s[SI_PLAY_TIME].y = 20;
s[SI_PLAY_TIME].w = 65;
s[SI_STATUS].prefix = "";
s[SI_STATUS].postfix = "";
- s[SI_STATUS].content = "";
s[SI_STATUS].x = 35;
s[SI_STATUS].y = 28;
s[SI_STATUS].w = 12;
s[SI_STATUS_FLAGS].prefix = " (";
s[SI_STATUS_FLAGS].postfix = ")";
- s[SI_STATUS_FLAGS].content = "";
s[SI_STATUS_FLAGS].x = 47;
s[SI_STATUS_FLAGS].y = 28;
s[SI_STATUS_FLAGS].w = 15;
s[SI_NUM_PLAYED].prefix = "#";
s[SI_NUM_PLAYED].postfix = "";
- s[SI_NUM_PLAYED].content = "0";
s[SI_NUM_PLAYED].x = 62;
s[SI_NUM_PLAYED].y = 28;
s[SI_NUM_PLAYED].w = 13;
s[SI_UPTIME].prefix = "Up: ";
s[SI_UPTIME].postfix = "";
- s[SI_UPTIME].content = "";
s[SI_UPTIME].x = 75;
s[SI_UPTIME].y = 28;
s[SI_UPTIME].w = 25;
s[SI_SELECTOR].prefix = "selector: ";
s[SI_SELECTOR].postfix = "";
- s[SI_SELECTOR].content = "no content yet";
s[SI_SELECTOR].x = 35;
s[SI_SELECTOR].y = 48;
s[SI_SELECTOR].w = 35;
s[SI_FORMAT].prefix = "Format: ";
s[SI_FORMAT].postfix = "";
- s[SI_FORMAT].content = "";
s[SI_FORMAT].x = 70;
s[SI_FORMAT].y = 48;
s[SI_FORMAT].w = 30;
s[SI_MTIME].prefix = "MTime: ";
s[SI_MTIME].postfix = "";
- s[SI_MTIME].content = "";
s[SI_MTIME].x = 35;
s[SI_MTIME].y = 35;
s[SI_MTIME].w = 65;
s[SI_FILE_SIZE].prefix = "Size: ";
s[SI_FILE_SIZE].postfix = "kb";
- s[SI_FILE_SIZE].content = "";
s[SI_FILE_SIZE].x = 35;
s[SI_FILE_SIZE].y = 42;
s[SI_FILE_SIZE].w = 20;
s[SI_AUDIO_INFO1].prefix = "";
s[SI_AUDIO_INFO1].postfix = "";
- s[SI_AUDIO_INFO1].content = "";
s[SI_AUDIO_INFO1].x = 0;
s[SI_AUDIO_INFO1].y = 60;
s[SI_AUDIO_INFO1].w = 100;
s[SI_AUDIO_INFO2].prefix = "";
s[SI_AUDIO_INFO2].postfix = "";
- s[SI_AUDIO_INFO2].content = "";
s[SI_AUDIO_INFO2].x = 0;
s[SI_AUDIO_INFO2].y = 65;
s[SI_AUDIO_INFO2].w = 100;
s[SI_AUDIO_INFO3].prefix = "";
s[SI_AUDIO_INFO3].postfix = "";
- s[SI_AUDIO_INFO3].content = "";
s[SI_AUDIO_INFO3].x = 0;
s[SI_AUDIO_INFO3].y = 70;
s[SI_AUDIO_INFO3].w = 100;
s[SI_DBINFO1].name = "dbinfo1:";
s[SI_DBINFO1].prefix = "";
s[SI_DBINFO1].postfix = "";
- s[SI_DBINFO1].content = "";
s[SI_DBINFO1].x = 0;
s[SI_DBINFO1].y = 83;
s[SI_DBINFO1].w = 100;
s[SI_DBINFO2].prefix = "";
s[SI_DBINFO2].postfix = "";
- s[SI_DBINFO2].content = "";
s[SI_DBINFO2].x = 0;
s[SI_DBINFO2].y = 88;
s[SI_DBINFO2].w = 100;
s[SI_DBINFO3].name = "dbinfo3:";
s[SI_DBINFO3].prefix = "";
s[SI_DBINFO3].postfix = "";
- s[SI_DBINFO3].content = "";
s[SI_DBINFO3].x = 0;
s[SI_DBINFO3].y = 93;
s[SI_DBINFO3].w = 100;
}
}
-static void print_msg(char *msg)
+static void print_msg(const char *msg)
{
SFont_FontInfo *font = &(fonts[MSG_FONT].fontinfo);
char *buf = strdup(msg);
/*
* print message, wait for key (blocking), return 1 for 'q', 0 else
*/
-static SDLKey hit_key(char *msg)
+static SDLKey hit_key(const char *msg)
{
SDLKey sym;
* \param ll the log level
* \param fmt the format string describing the log message
*/
-void para_log(int ll, char* fmt,...)
+void para_log(int ll, const char* fmt,...)
{
va_list argp;
FILE *outfd;
*/
struct server_command {
/** the name of the command */
- char *name;
+ const char *name;
/** pointer to the function that handles the command */
int (*handler)(int, int, char **);
/** the privileges a user must have to execute this command */
unsigned int perms;
/** one-line description of the command */
- char *description;
+ const char *description;
/** summary of the command line options */
- char *synopsis;
+ const char *synopsis;
/** the long help text */
- char *help;
+ const char *help;
};
/** holds the arguments for the para_server's sender command */
char *streamname = NULL;
static Zmw_Float_0_1 *slider_vals, lastplayed_val, numplayed_val;
-void para_log(int ll, char* fmt,...) /* no logging */
+void para_log(int ll, const char* fmt,...) /* no logging */
{
}
* This function modifies \a args by replacing each occurance of \a delim by
* zero. A NULL-terminated array of pointers to char* is allocated dynamically
* and these pointers are initialized to point to the broken-up substrings
- * within \a args. A pointer to this array is returned via \a argv_ptr.
+ * within \a args. A pointer to this array is returned via \a argv_ptr. It's OK
+ * to call this function with \a args == NULL.
*
* \return The number of substrings found in \a args.
*/
char **argv;
ssize_t n = 0, i;
- while ((p = strchr(p, delim))) {
+ while (p && (p = strchr(p, delim))) {
p++;
n++;
}
- *argv_ptr = para_malloc((n + 3) * sizeof(char *));
+ *argv_ptr = para_calloc((n + 3) * sizeof(char *));
argv = *argv_ptr;
i = 0;
p = args;
i++;
}
}
- argv[n + 1] = NULL;
return n;
}
*/
struct para_macro {
/** the name of the macro */
- char *name;
+ const char *name;
/** the replacement text */
- char *replacement;
+ const char *replacement;
};
__must_check __malloc void *para_realloc(void *p, size_t size);
__must_check __malloc void *para_malloc(size_t size);