From cfb897ee2d033fde9b8d1d887f445013785f50eb Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Tue, 14 May 2013 13:26:58 +0200 Subject: [PATCH] Vidcap, display: do not report errors on help --- src/host.c | 25 ++++++++++++++----------- src/host.h | 10 ++++++---- src/main.c | 24 +++++++++++++++++------- src/video_capture.c | 17 ++++++++++++----- src/video_capture.h | 9 ++++++++- src/video_capture/DirectShowGrabber.cpp | 2 +- src/video_capture/aggregate.c | 8 ++++---- src/video_capture/bluefish444.cpp | 2 +- src/video_capture/decklink.cpp | 9 +++++++-- src/video_capture/deltacast.cpp | 2 +- src/video_capture/deltacast_dvi.cpp | 2 +- src/video_capture/linsys.c | 2 +- src/video_capture/quicktime.c | 2 +- src/video_capture/screen.c | 2 +- src/video_capture/swmix.cpp | 9 +++++---- src/video_capture/testcard.c | 2 +- src/video_capture/testcard2.c | 2 +- src/video_capture/v4l2.c | 2 +- src/video_display.c | 16 +++++++++++----- src/video_display.h | 10 ++++++++-- src/video_display/aggregate.c | 10 ++++------ src/video_display/decklink.cpp | 2 +- src/video_display/dvs.c | 3 +-- src/video_display/gl.c | 2 +- src/video_display/quicktime.c | 2 +- src/video_display/sage.c | 2 +- src/video_display/sdl.c | 2 +- 27 files changed, 112 insertions(+), 68 deletions(-) diff --git a/src/host.c b/src/host.c index e1ce5fd3d..b7792d88b 100644 --- a/src/host.c +++ b/src/host.c @@ -41,15 +41,16 @@ extern void (*display_free_devices_extrn)(void); extern vidcap_id_t (*vidcap_get_null_device_id_extrn)(); extern display_id_t (*display_get_null_device_id_extrn)(); extern void (*decoder_destroy_extrn)(struct state_decoder *decoder); -extern struct vidcap *(*vidcap_init_extrn)(vidcap_id_t id, char *fmt, unsigned int flags); -extern struct display *(*display_init_extrn)(display_id_t id, char *fmt, unsigned int flags); +extern int (*vidcap_init_extrn)(vidcap_id_t id, char *fmt, unsigned int flags, struct vidcap **); +extern int (*display_init_extrn)(display_id_t id, char *fmt, unsigned int flags, struct display **); extern int (*vidcap_get_device_count_extrn)(void); extern int (*display_get_device_count_extrn)(void); extern int (*vidcap_init_devices_extrn)(void); extern int (*display_init_devices_extrn)(void); -struct vidcap *initialize_video_capture(const char *requested_capture, - char *fmt, unsigned int flags) +int initialize_video_capture(const char *requested_capture, + char *fmt, unsigned int flags, + struct vidcap **state) { struct vidcap_type *vt; vidcap_id_t id = 0; @@ -72,18 +73,19 @@ struct vidcap *initialize_video_capture(const char *requested_capture, if(i == vidcap_get_device_count_extrn()) { fprintf(stderr, "WARNING: Selected '%s' capture card " "was not found.\n", requested_capture); - return NULL; + return -1; } vidcap_free_devices_extrn(); pthread_mutex_unlock(vidcap_lock); rm_release_shared_lock("VIDCAP_LOCK"); - return vidcap_init_extrn(id, fmt, flags); + return vidcap_init_extrn(id, fmt, flags, state); } -struct display *initialize_video_display(const char *requested_display, - char *fmt, unsigned int flags) +int initialize_video_display(const char *requested_display, + char *fmt, unsigned int flags, + struct display **out) { struct display *d; display_type_t *dt; @@ -114,12 +116,13 @@ struct display *initialize_video_display(const char *requested_display, if(i == display_get_device_count_extrn()) { fprintf(stderr, "WARNING: Selected '%s' display card " "was not found.\n", requested_display); - return NULL; + return -1; } display_free_devices_extrn(); - d = display_init_extrn(id, fmt, flags); - return d; + int ret = display_init_extrn(id, fmt, flags, &d); + *out = d; + return ret; } void destroy_decoder(struct vcodec_state *video_decoder_state) { diff --git a/src/host.h b/src/host.h index afd1723c6..8e3eacc8a 100644 --- a/src/host.h +++ b/src/host.h @@ -79,10 +79,12 @@ extern char *sage_network_device; // for aggregate.c struct vidcap; struct display; -struct display *initialize_video_display(const char *requested_display, - char *fmt, unsigned int flags); -struct vidcap *initialize_video_capture(const char *requested_capture, - char *fmt, unsigned int flags); +int initialize_video_display(const char *requested_display, + char *fmt, unsigned int flags, + struct display **); +int initialize_video_capture(const char *requested_capture, + char *fmt, unsigned int flags, + struct vidcap **); struct vcodec_state; void destroy_decoder(struct vcodec_state *video_decoder_state); diff --git a/src/main.c b/src/main.c index d0aa4cf03..c819a1db5 100644 --- a/src/main.c +++ b/src/main.c @@ -955,6 +955,7 @@ int main(int argc, char *argv[]) unsigned vidcap_flags = 0, display_flags = 0; int compressed_audio_sample_rate = 48000; + int ret; #if defined DEBUG && defined HAVE_LINUX mtrace(); @@ -1348,23 +1349,32 @@ int main(int argc, char *argv[]) // Display initialization should be prior to modules that may use graphic card (eg. GLSL) in order // to initalize shared resource (X display) first - if ((uv->display_device = - initialize_video_display(uv->requested_display, display_cfg, display_flags)) == NULL) { + ret = + initialize_video_display(uv->requested_display, display_cfg, display_flags, &uv->display_device); + if (ret < 0) { printf("Unable to open display device: %s\n", uv->requested_display); exit_uv(EXIT_FAIL_DISPLAY); goto cleanup_wait_audio; } + if(ret > 0) { + exit_uv(EXIT_SUCCESS); + goto cleanup_wait_audio; + } printf("Display initialized-%s\n", uv->requested_display); - if ((uv->capture_device = - initialize_video_capture(uv->requested_capture, capture_cfg, vidcap_flags)) == NULL) { + ret = initialize_video_capture(uv->requested_capture, capture_cfg, vidcap_flags, &uv->capture_device); + if (ret < 0) { printf("Unable to open capture device: %s\n", uv->requested_capture); exit_uv(EXIT_FAIL_CAPTURE); goto cleanup_wait_audio; } + if(ret > 0) { + exit_uv(EXIT_SUCCESS); + goto cleanup_wait_audio; + } printf("Video capture initialized-%s\n", uv->requested_capture); signal(SIGINT, signal_handler); @@ -1495,9 +1505,9 @@ int main(int argc, char *argv[]) } free(requested_video_fec); } else { // SAGE - uv->sage_tx_device = initialize_video_display("sage", - sage_opts, 0); - if(uv->sage_tx_device == NULL) { + ret = initialize_video_display("sage", + sage_opts, 0, &uv->sage_tx_device); + if(ret != 0) { fprintf(stderr, "Unable to initialize SAGE TX.\n"); exit_uv(EXIT_FAIL_NETWORK); goto cleanup_wait_display; diff --git a/src/video_capture.c b/src/video_capture.c index 78a79c8d1..acfca1e16 100644 --- a/src/video_capture.c +++ b/src/video_capture.c @@ -80,11 +80,13 @@ void (*vidcap_finish_extrn)(struct vidcap *) = vidcap_finish; void (*vidcap_done_extrn)(struct vidcap *) = vidcap_done; vidcap_id_t (*vidcap_get_null_device_id_extrn)(void) = vidcap_get_null_device_id; struct vidcap_type *(*vidcap_get_device_details_extrn)(int index) = vidcap_get_device_details; -struct vidcap *(*vidcap_init_extrn)(vidcap_id_t id, char *fmt, unsigned int flags) = vidcap_init; +int (*vidcap_init_extrn)(vidcap_id_t id, char *fmt, unsigned int flags, struct vidcap **) = vidcap_init; struct video_frame *(*vidcap_grab_extrn)(struct vidcap *state, struct audio_frame **audio) = vidcap_grab; int (*vidcap_get_device_count_extrn)(void) = vidcap_get_device_count; int (*vidcap_init_devices_extrn)(void) = vidcap_init_devices; +int vidcap_init_noerr; + struct vidcap { void *state; int index; @@ -414,7 +416,7 @@ vidcap_id_t vidcap_get_null_device_id(void) /* API for video capture **************************************************************************/ -struct vidcap *vidcap_init(vidcap_id_t id, char *fmt, unsigned int flags) +int vidcap_init(vidcap_id_t id, char *fmt, unsigned int flags, struct vidcap **state) { unsigned int i; @@ -430,13 +432,18 @@ struct vidcap *vidcap_init(vidcap_id_t id, char *fmt, unsigned int flags) ("Unable to start video capture device 0x%08lx\n", id); free(d); - return NULL; + return -1; } - return d; + if(d->state == &vidcap_init_noerr) { + free(d); + return 1; + } + *state = d; + return 0; } } debug_msg("Unknown video capture device: 0x%08x\n", id); - return NULL; + return -1; } void vidcap_done(struct vidcap *state) diff --git a/src/video_capture.h b/src/video_capture.h index c82fa8bbc..3326fcd88 100644 --- a/src/video_capture.h +++ b/src/video_capture.h @@ -104,11 +104,18 @@ vidcap_id_t vidcap_get_null_device_id(void); struct vidcap; -struct vidcap *vidcap_init(vidcap_id_t id, char *fmt, unsigned int flags); +/** + * Semantics is similar to the semantic of display_init + * + * @see display_init + */ +int vidcap_init(vidcap_id_t id, char *fmt, unsigned int flags, struct vidcap **); void vidcap_done(struct vidcap *state); void vidcap_finish(struct vidcap *state); struct video_frame *vidcap_grab(struct vidcap *state, struct audio_frame **audio); +extern int vidcap_init_noerr; + #ifdef __cplusplus } #endif // __cplusplus diff --git a/src/video_capture/DirectShowGrabber.cpp b/src/video_capture/DirectShowGrabber.cpp index 8d810f182..592009eda 100644 --- a/src/video_capture/DirectShowGrabber.cpp +++ b/src/video_capture/DirectShowGrabber.cpp @@ -664,7 +664,7 @@ void * vidcap_dshow_init(char *init_fmt, unsigned int flags) { if (init_fmt && strcmp(init_fmt, "help") == 0) { show_help(s); cleanup(s); - return NULL; + return &vidcap_init_noerr; } if (!common_init(s)) { diff --git a/src/video_capture/aggregate.c b/src/video_capture/aggregate.c index 70fa15c93..315a9707b 100644 --- a/src/video_capture/aggregate.c +++ b/src/video_capture/aggregate.c @@ -128,7 +128,7 @@ vidcap_aggregate_init(char *init_fmt, unsigned int flags) if(!init_fmt || strcmp(init_fmt, "help") == 0) { show_help(); - return NULL; + return &vidcap_init_noerr; } @@ -161,10 +161,10 @@ vidcap_aggregate_init(char *init_fmt, unsigned int flags) dev_flags = flags & ~(VIDCAP_FLAG_AUDIO_EMBEDDED | VIDCAP_FLAG_AUDIO_AESEBU | VIDCAP_FLAG_AUDIO_ANALOG); } - s->devices[i] = initialize_video_capture(device, - device_cfg, dev_flags); + int ret = initialize_video_capture(device, + device_cfg, dev_flags, &s->devices[i]); free(config); - if(!s->devices[i]) { + if(ret != 0) { fprintf(stderr, "[aggregate] Unable to initialize device %d (%s:%s).\n", i, device, device_cfg); goto error; } diff --git a/src/video_capture/bluefish444.cpp b/src/video_capture/bluefish444.cpp index d70827542..52aada2e2 100644 --- a/src/video_capture/bluefish444.cpp +++ b/src/video_capture/bluefish444.cpp @@ -780,7 +780,7 @@ vidcap_bluefish444_init(char *init_fmt, unsigned int flags) if(init_fmt && strcmp(init_fmt, "help") == 0) { show_help(); - return NULL; + return &vidcap_init_noerr; } printf("vidcap_bluefish444_init\n"); diff --git a/src/video_capture/decklink.cpp b/src/video_capture/decklink.cpp index 7d39ff2d2..f2184f110 100644 --- a/src/video_capture/decklink.cpp +++ b/src/video_capture/decklink.cpp @@ -534,7 +534,7 @@ settings_init(void *state, char *fmt) char *save_ptr_top = NULL; if(strcmp(fmt, "help") == 0) { decklink_help(); - return 0; + return -1; } char *tmp; @@ -806,10 +806,15 @@ vidcap_decklink_init(char *fmt, unsigned int flags) s->flags = 0; // SET UP device and mode - if(settings_init(s, fmt) == 0) { + int ret = settings_init(s, fmt); + if(ret == 0) { free(s); return NULL; } + if(ret == -1) { + free(s); + return &vidcap_init_noerr; + } if(flags & (VIDCAP_FLAG_AUDIO_EMBEDDED | VIDCAP_FLAG_AUDIO_AESEBU | VIDCAP_FLAG_AUDIO_ANALOG)) { s->grab_audio = TRUE; diff --git a/src/video_capture/deltacast.cpp b/src/video_capture/deltacast.cpp index 2c5edfec6..4ab391daa 100644 --- a/src/video_capture/deltacast.cpp +++ b/src/video_capture/deltacast.cpp @@ -199,7 +199,7 @@ vidcap_deltacast_init(char *init_fmt, unsigned int flags) if(init_fmt && strcmp(init_fmt, "help") == 0) { usage(); - goto error; + return &vidcap_init_noerr; } if(init_fmt) diff --git a/src/video_capture/deltacast_dvi.cpp b/src/video_capture/deltacast_dvi.cpp index 3c31b255a..7260f44f8 100644 --- a/src/video_capture/deltacast_dvi.cpp +++ b/src/video_capture/deltacast_dvi.cpp @@ -473,7 +473,7 @@ vidcap_deltacast_dvi_init(char *init_fmt, unsigned int flags) if(init_fmt && strcmp(init_fmt, "help") == 0) { usage(); - goto error; + return &vidcap_init_noerr; } if(init_fmt) diff --git a/src/video_capture/linsys.c b/src/video_capture/linsys.c index 60642d85b..7ed65d75b 100644 --- a/src/video_capture/linsys.c +++ b/src/video_capture/linsys.c @@ -378,7 +378,7 @@ vidcap_linsys_init(char *init_fmt, unsigned int flags) if(!init_fmt || strcmp(init_fmt, "help") == 0) { print_output_modes(); - return NULL; + return &vidcap_init_noerr; } if(flags & VIDCAP_FLAG_AUDIO_EMBEDDED) { diff --git a/src/video_capture/quicktime.c b/src/video_capture/quicktime.c index d586886c8..ca31adcb4 100644 --- a/src/video_capture/quicktime.c +++ b/src/video_capture/quicktime.c @@ -527,7 +527,7 @@ static int qt_open_grabber(struct qt_grabber_state *s, char *fmt) } SGDisposeDeviceList(s->grabber, deviceList); } - return 0; + return &vidcap_init_noerr; } if (SGSetChannelUsage diff --git a/src/video_capture/screen.c b/src/video_capture/screen.c index bab63e64c..16e74744e 100644 --- a/src/video_capture/screen.c +++ b/src/video_capture/screen.c @@ -343,7 +343,7 @@ void * vidcap_screen_init(char *init_fmt, unsigned int flags) if(init_fmt) { if (strcmp(init_fmt, "help") == 0) { show_help(); - return NULL; + return &vidcap_init_noerr; } else if (strncasecmp(init_fmt, "fps=", strlen("fps=")) == 0) { s->fps = atoi(init_fmt + strlen("fps=")); } diff --git a/src/video_capture/swmix.cpp b/src/video_capture/swmix.cpp index e2ba95118..290bebbb6 100644 --- a/src/video_capture/swmix.cpp +++ b/src/video_capture/swmix.cpp @@ -745,9 +745,10 @@ static void *slave_worker(void *arg) { struct state_slave *s = (struct state_slave *) arg; - struct vidcap *device = - initialize_video_capture(s->device_vendor, s->device_cfg, s->vidcap_flags); - if(!device) { + struct vidcap *device; + int ret = + initialize_video_capture(s->device_vendor, s->device_cfg, s->vidcap_flags, &device); + if(ret != 0) { fprintf(stderr, "[swmix] Unable to initialize device %s (%s:%s).\n", s->name, s->device_vendor, s->device_cfg); return NULL; @@ -1060,7 +1061,7 @@ vidcap_swmix_init(char *init_fmt, unsigned int flags) if(!init_fmt || strcmp(init_fmt, "help") == 0) { show_help(); - return NULL; + return &vidcap_init_noerr; } memset(&desc, 0, sizeof(desc)); diff --git a/src/video_capture/testcard.c b/src/video_capture/testcard.c index 765d005c3..7a339ddd0 100644 --- a/src/video_capture/testcard.c +++ b/src/video_capture/testcard.c @@ -297,7 +297,7 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags) printf("\ti|sf - send as interlaced or segmented frame (if none of those is set, progressive is assumed)\n"); printf("\tstill - send still image\n"); show_codec_help("testcard"); - return NULL; + return &vidcap_init_noerr; } s = calloc(1, sizeof(struct testcard_state)); diff --git a/src/video_capture/testcard2.c b/src/video_capture/testcard2.c index ef45e0d23..0105e1da1 100644 --- a/src/video_capture/testcard2.c +++ b/src/video_capture/testcard2.c @@ -152,7 +152,7 @@ void *vidcap_testcard2_init(char *fmt, unsigned int flags) printf("testcard2 options:\n"); printf("\t-t testcard2::::\n"); show_codec_help("testcard"); - return NULL; + return &vidcap_init_noerr; } s = calloc(1, sizeof(struct testcard_state2)); diff --git a/src/video_capture/v4l2.c b/src/video_capture/v4l2.c index 22faa8823..1660094b1 100644 --- a/src/video_capture/v4l2.c +++ b/src/video_capture/v4l2.c @@ -262,7 +262,7 @@ void * vidcap_v4l2_init(char *init_fmt, unsigned int flags) if(init_fmt && strcmp(init_fmt, "help") == 0) { show_help(); - return NULL; + return &vidcap_init_noerr; } diff --git a/src/video_display.c b/src/video_display.c index f03accd06..e6dcf14ff 100644 --- a/src/video_display.c +++ b/src/video_display.c @@ -73,7 +73,7 @@ display_type_t *(*display_get_device_details_extrn)(int index) = display_get_device_details; void (*display_free_devices_extrn)(void) = display_free_devices; display_id_t (*display_get_null_device_id_extrn)(void) = display_get_null_device_id; -struct display *(*display_init_extrn)(display_id_t id, char *fmt, unsigned int flags) = display_init; +int (*display_init_extrn)(display_id_t id, char *fmt, unsigned int flags, struct display **) = display_init; int (*display_get_device_count_extrn)(void) = display_get_device_count; int (*display_init_devices_extrn)(void) = display_init_devices; @@ -424,7 +424,9 @@ struct display { void *state; }; -struct display *display_init(display_id_t id, char *fmt, unsigned int flags) +int display_init_noerr; + +int display_init(display_id_t id, char *fmt, unsigned int flags, struct display **state) { unsigned int i; @@ -439,13 +441,17 @@ struct display *display_init(display_id_t id, char *fmt, unsigned int flags) debug_msg("Unable to start display 0x%08lx\n", id); free(d); - return NULL; + return -1; + } else if (d->state == &display_init_noerr) { + free(d); + return 1; } - return d; + *state = d; + return 0; } } debug_msg("Unknown display id: 0x%08x\n", id); - return NULL; + return -1; } void display_finish(struct display *d) diff --git a/src/video_display.h b/src/video_display.h index 0cfb345af..3e3916e0a 100644 --- a/src/video_display.h +++ b/src/video_display.h @@ -101,14 +101,20 @@ display_id_t display_get_null_device_id(void); */ struct display; +extern int display_init_noerr; + /** * Initializes video display * * @param fmt command-line entered format string * @param flags bit sum of DISPLAY_FLAG_* params defined above - * @return opaque struct which will be passed in subsequent calls + * @param[out] display state if available, may be NULL if driver only shows help + * defined only if sucessful + * @retval 0 if sucessful + * @retval -1 if failed + * @retval 1 if successfully shown help */ -struct display *display_init(display_id_t id, char *fmt, unsigned int flags); +int display_init(display_id_t id, char *fmt, unsigned int flags, struct display **state); /** * This call is entered in main thread and the display may stay in this call until end of the program. diff --git a/src/video_display/aggregate.c b/src/video_display/aggregate.c index 0362c6d2f..19120a26d 100644 --- a/src/video_display/aggregate.c +++ b/src/video_display/aggregate.c @@ -112,8 +112,6 @@ void display_aggregate_run(void *state) void *display_aggregate_init(char *fmt, unsigned int flags) { - UNUSED(fmt); - UNUSED(flags); struct display_aggregate_state *s; char *save_ptr = NULL; char *item; @@ -124,7 +122,7 @@ void *display_aggregate_init(char *fmt, unsigned int flags) if(!fmt || strcmp(fmt, "help") == 0) { show_help(); - return NULL; + return &display_init_noerr; } s = (struct display_aggregate_state *) calloc(1, sizeof(struct display_aggregate_state)); @@ -158,10 +156,10 @@ void *display_aggregate_init(char *fmt, unsigned int flags) dev_flags = flags & ~(DISPLAY_FLAG_AUDIO_EMBEDDED | DISPLAY_FLAG_AUDIO_AESEBU | DISPLAY_FLAG_AUDIO_ANALOG); } - s->devices[i] = initialize_video_display(device, - device_cfg, dev_flags); + int ret = initialize_video_display(device, + device_cfg, dev_flags, &s->devices[i]); free(config); - if(!s->devices[i]) { + if(ret != 0) { fprintf(stderr, "[aggregate] Unable to initialize device %d (%s:%s).\n", i, device, device_cfg); goto error; } diff --git a/src/video_display/decklink.cpp b/src/video_display/decklink.cpp index 976cf5b39..50d8b7077 100644 --- a/src/video_display/decklink.cpp +++ b/src/video_display/decklink.cpp @@ -796,7 +796,7 @@ void *display_decklink_init(char *fmt, unsigned int flags) } else if (strcmp(fmt, "help") == 0) { show_help(); - return NULL; + return &display_init_noerr; } else { char *tmp = strdup(fmt); char *ptr; diff --git a/src/video_display/dvs.c b/src/video_display/dvs.c index 9afddfe1a..356455be9 100644 --- a/src/video_display/dvs.c +++ b/src/video_display/dvs.c @@ -658,8 +658,7 @@ void *display_dvs_init(char *fmt, unsigned int flags) if (fmt != NULL) { if (strcmp(fmt, "help") == 0) { show_help(); - - return NULL; + return &display_init_noerr; } if(strncmp(fmt, "PCI", 3) == 0) { name = fmt; diff --git a/src/video_display/gl.c b/src/video_display/gl.c index d80bce2d5..cd1637f47 100644 --- a/src/video_display/gl.c +++ b/src/video_display/gl.c @@ -271,7 +271,7 @@ void * display_gl_init(char *fmt, unsigned int flags) { if (strcmp(fmt, "help") == 0) { gl_show_help(); free(s); - return NULL; + return &display_init_noerr; } char *tmp = strdup(fmt); diff --git a/src/video_display/quicktime.c b/src/video_display/quicktime.c index 544d53d94..e98a1e750 100644 --- a/src/video_display/quicktime.c +++ b/src/video_display/quicktime.c @@ -593,7 +593,7 @@ void *display_quicktime_init(char *fmt, unsigned int flags) if (strcmp(fmt, "help") == 0) { show_help(0); free(s); - return NULL; + return &display_init_noerr; } if (strcmp(fmt, "fullhelp") == 0) { show_help(1); diff --git a/src/video_display/sage.c b/src/video_display/sage.c index 031323f39..a4dd05739 100644 --- a/src/video_display/sage.c +++ b/src/video_display/sage.c @@ -168,7 +168,7 @@ void *display_sage_init(char *fmt, unsigned int flags) printf("\t - FS manager IP address\n"); printf("\t - FourCC of codec that will be used to transmit to SAGE\n"); printf("\t Supported options are UYVY, RGBA, RGB or DXT1\n"); - return NULL; + return &display_init_noerr; } else { char *save_ptr = NULL; char *item; diff --git a/src/video_display/sdl.c b/src/video_display/sdl.c index b771b9248..32015be08 100644 --- a/src/video_display/sdl.c +++ b/src/video_display/sdl.c @@ -572,7 +572,7 @@ void *display_sdl_init(char *fmt, unsigned int flags) if (strcmp(fmt, "help") == 0) { show_help(); free(s); - return NULL; + return &display_init_noerr; } char *tmp = strdup(fmt);