Skip to content
This repository has been archived by the owner on Mar 20, 2023. It is now read-only.

Commit

Permalink
Properly setup colorized printing functions
Browse files Browse the repository at this point in the history
Previously, non-colorized and colorized printing made use of the same
pw_*print family of functions.

Since we do most of the setup after we parse the user supplied arguments,
the user may supply the "--debug" option. This will cause a segmentation
fault as the color struct has not been initialized but a NULL string in it
is printed.

The pw_safe_*print family of functions is introduced to solve this.
Now, the pw_*print family of functions are just function pointers to the
pw_safe_*print family of functions until we confirm whether the output is
colorized. If so, then we call color_print_setup() to switch the pw_*print
function pointers to pw_c*print family of functions to support colorized
output.

Otherwise, the pw_*print family of functions will still point to the original
pw_safe_*print family of functions.

When we destroy the color struct, color_print_restore() is invoked to switch
the pw_*print pointers to the pw_safe_*print functions.

Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
  • Loading branch information
yanhan committed May 30, 2011
1 parent c9891df commit 774666e
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 6 deletions.
7 changes: 7 additions & 0 deletions environment.c
Expand Up @@ -57,6 +57,10 @@ static void colors_setup(void)
color.nocolor = xstrdup(NOCOLOR);
color.bold = xstrdup(BOLD);
color.votecol = xstrdup(VOTECOL);

/* Setup colorized print functions */
color_print_setup();

} else {
color.black = xstrdup("");
color.red = xstrdup("");
Expand All @@ -77,6 +81,9 @@ static void colors_setup(void)
color.nocolor = xstrdup("");
color.bold = xstrdup("");
color.votecol = xstrdup("");

/* Restore non-colorized print functions */
color_print_restore;
}
}

Expand Down
84 changes: 81 additions & 3 deletions util.c
Expand Up @@ -19,7 +19,69 @@
#include "powaur.h"
#include "util.h"

int pw_printf(enum pwloglevel_t lvl, const char *fmt, ...)
/* Safe family of print functions for use when color struct isnt initialized */
static int pw_safe_vfprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt,
va_list ap)
{
int ret = 0;
va_list copy_list;

if (!config || !(config->loglvl & lvl)) {
return ret;
}

va_copy(copy_list, ap);

switch (lvl) {
case PW_LOG_WARNING:
fprintf(stream, "WARNING: ");
break;
case PW_LOG_ERROR:
fprintf(stream, "error: ");
break;
case PW_LOG_INFO:
fprintf(stream, "==> ");
break;
case PW_LOG_DEBUG:
fprintf(stream, "debug: ");
break;
}

ret = vfprintf(stream, fmt, ap);
return ret;
}

static int pw_safe_printf(enum pwloglevel_t lvl, const char *fmt, ...)
{
int ret;
va_list ap;

va_start(ap, fmt);
ret = pw_safe_vfprintf(lvl, stdout, fmt, ap);
va_end(ap);

return ret;
}

static int pw_safe_fprintf(enum pwloglevel_t lvl, FILE *stream,
const char *fmt, ...)
{
int ret;
va_list ap;

va_start(ap, fmt);
ret = pw_safe_vfprintf(lvl, stderr, fmt, ap);
va_end(ap);

return ret;
}

int (*pw_printf)(enum pwloglevel_t lvl, const char *fmt, ...) = pw_safe_printf;
int (*pw_fprintf)(enum pwloglevel_t lvl, FILE *stream, const char *fmt, ...) = pw_safe_fprintf;
int (*pw_vfprintf)(enum pwloglevel_t lvl, FILE *stream, const char *fmt, va_list ap) = pw_safe_vfprintf;

/* Colorized output printing functions */
static int pw_cprintf(enum pwloglevel_t lvl, const char *fmt, ...)
{
int ret;
va_list ap;
Expand All @@ -31,7 +93,7 @@ int pw_printf(enum pwloglevel_t lvl, const char *fmt, ...)
return ret;
}

int pw_fprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, ...)
static int pw_cfprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, ...)
{
int ret;
va_list ap;
Expand All @@ -43,7 +105,7 @@ int pw_fprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, ...)
return ret;
}

int pw_vfprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, va_list ap)
static int pw_cvfprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, va_list ap)
{
int ret = 0;
va_list copy_list;
Expand Down Expand Up @@ -74,6 +136,22 @@ int pw_vfprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, va_list ap
return ret;
}

void color_print_setup(void)
{
if (config->color) {
pw_printf = pw_cprintf;
pw_fprintf = pw_cfprintf;
pw_vfprintf = pw_cvfprintf;
}
}

void color_print_restore(void)
{
pw_printf = pw_safe_printf;
pw_fprintf = pw_safe_fprintf;
pw_vfprintf = pw_safe_vfprintf;
}

/* Extracts the downloaded archive and removes it upon success.
* Assumed to be in destination directory before calling this.
* Returns -1 on fatal errors, > 0 on extraction errors, 0 on success.
Expand Down
12 changes: 9 additions & 3 deletions util.h
Expand Up @@ -15,15 +15,21 @@

int powaur_backup(alpm_list_t *targets);

int pw_printf(enum pwloglevel_t lvl, const char *fmt, ...)
extern int (*pw_printf)(enum pwloglevel_t lvl, const char *fmt, ...)
__attribute__((format (printf, 2, 3)));

int pw_fprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, ...)
extern int (*pw_fprintf)(enum pwloglevel_t lvl, FILE *stream, const char *fmt, ...)
__attribute__((format (printf, 3, 4)));

int pw_vfprintf(enum pwloglevel_t lvl, FILE *stream, const char *fmt, va_list ap)
extern int (*pw_vfprintf)(enum pwloglevel_t lvl, FILE *stream, const char *fmt, va_list ap)
__attribute__((format (printf, 3, 0)));

/* Setup color printing functions */
void color_print_setup(void);

/* Restore color printing functions to non-colorized versions */
void color_print_restore(void);

int extract_file(const char *filename);
int getcols(void);
char *strtrim(char *line);
Expand Down

0 comments on commit 774666e

Please sign in to comment.