summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6777db4)
raw | patch | inline | side by side (parent: 6777db4)
author | Kalle Wallin <kaw@linux.se> | |
Thu, 25 Mar 2004 11:44:59 +0000 (11:44 +0000) | ||
committer | Kalle Wallin <kaw@linux.se> | |
Thu, 25 Mar 2004 11:44:59 +0000 (11:44 +0000) |
15 files changed:
Makefile.am | patch | blob | history | |
conf.c | [new file with mode: 0644] | patch | blob |
conf.h | [new file with mode: 0644] | patch | blob |
configure.ac | patch | blob | history | |
doc/ncmpcrc | [new file with mode: 0644] | patch | blob |
main.c | patch | blob | history | |
options.c | patch | blob | history | |
options.h | patch | blob | history | |
screen.c | patch | blob | history | |
screen.h | patch | blob | history | |
screen_file.c | patch | blob | history | |
screen_utils.c | patch | blob | history | |
screen_utils.h | patch | blob | history | |
support.c | patch | blob | history | |
support.h | patch | blob | history |
diff --git a/Makefile.am b/Makefile.am
index 96e6b1dd05dc72bd28cb9daf94884b1658f644d2..1e980df6da1251c541aad41b87b3abac4805e45e 100644 (file)
--- a/Makefile.am
+++ b/Makefile.am
doc_DATA = AUTHORS README ChangeLog
EXTRA_DIST = COPYING $(pkgdata_DATA) $(man_MANS) $(doc_DATA)
-ncmpc_headers = libmpdclient.h mpc.h options.h command.h screen.h \
+ncmpc_headers = libmpdclient.h mpc.h options.h conf.h command.h screen.h \
screen_utils.h screen_play.h screen_file.h screen_search.h \
- screen_help.h list_window.h support.h
+ screen_help.h list_window.h support.h
-ncmpc_SOURCES = libmpdclient.c main.c mpc.c options.c command.c \
+ncmpc_SOURCES = libmpdclient.c main.c mpc.c options.c conf.c command.c \
screen.c screen_utils.c screen_play.c screen_file.c \
screen_search.c screen_help.c \
list_window.c support.c $(ncmpc_headers)
diff --git a/conf.c b/conf.c
--- /dev/null
+++ b/conf.c
@@ -0,0 +1,263 @@
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ncurses.h>
+
+#include "config.h"
+#include "options.h"
+#include "support.h"
+#include "conf.h"
+
+#ifdef DEBUG
+#define D(x) x
+#else
+#define D(x)
+#endif
+
+#define RCFILE "." PACKAGE "rc"
+
+#define MAX_LINE_LENGTH 1024
+#define COMMENT_TOKEN '#'
+
+/* configuration field names */
+#define CONF_ENABLE_COLORS "enable_colors"
+#define CONF_COLOR_BACKGROUND "background_color"
+#define CONF_COLOR_TITLE "title_color"
+#define CONF_COLOR_LINE "line_color"
+#define CONF_COLOR_LIST "list_color"
+#define CONF_COLOR_PROGRESS "progress_color"
+#define CONF_COLOR_STATUS "status_color"
+#define CONF_COLOR_ALERT "alert_color"
+
+
+#define IS_WHITESPACE(c) (c==' ' || c=='\t' || c=='\r' || c=='\n')
+
+
+static int
+str2bool(char *str)
+{
+ if( !strcasecmp(str,"no") || !strcasecmp(str,"false") ||
+ !strcasecmp(str,"off") || !strcasecmp(str,"0") )
+ return 0;
+ return 1;
+}
+
+static int
+str2color(char *str)
+{
+ if( !strcasecmp(str,"black") )
+ return COLOR_BLACK;
+ else if( !strcasecmp(str,"red") )
+ return COLOR_RED;
+ else if( !strcasecmp(str,"green") )
+ return COLOR_GREEN;
+ else if( !strcasecmp(str,"yellow") )
+ return COLOR_YELLOW;
+ else if( !strcasecmp(str,"blue") )
+ return COLOR_BLUE;
+ else if( !strcasecmp(str,"magenta") )
+ return COLOR_MAGENTA;
+ else if( !strcasecmp(str,"cyan") )
+ return COLOR_CYAN;
+ else if( !strcasecmp(str,"white") )
+ return COLOR_WHITE;
+#if 0
+ else if( !strcasecmp(str,"grey") )
+ return COLOR_BLACK | A_BOLD;
+ else if( !strcasecmp(str,"brightred") )
+ return COLOR_RED | A_BOLD;
+ else if( !strcasecmp(str,"brightgreen") )
+ return COLOR_GREEN | A_BOLD;
+ else if( !strcasecmp(str,"brightyellow") )
+ return COLOR_YELLOW | A_BOLD;
+ else if( !strcasecmp(str,"brightblue") )
+ return COLOR_BLUE | A_BOLD;
+ else if( !strcasecmp(str,"brightmagenta") )
+ return COLOR_MAGENTA | A_BOLD;
+ else if( !strcasecmp(str,"brightcyan") )
+ return COLOR_CYAN | A_BOLD;
+ else if( !strcasecmp(str,"brightwhite") )
+ return COLOR_WHITE | A_BOLD;
+#endif
+ fprintf(stderr,"Warning: unknown color %s\n", str);
+ return -1;
+}
+
+int
+read_rc_file(char *filename, options_t *options)
+{
+ int fd;
+ int quit = 0;
+ int color = -1;
+ int free_filename = 0;
+
+ if( filename==NULL )
+ {
+ filename = concat_path(getenv("HOME"), RCFILE);
+ free_filename = 1;
+ }
+
+ D(printf("\n--Reading configuration file %s\n", filename));
+ if( (fd=open(filename,O_RDONLY)) <0 )
+ {
+ D(perror(filename));
+ if( free_filename )
+ free(filename);
+ return -1;
+ }
+
+ while( !quit )
+ {
+ int i,j;
+ int len;
+ int match_found;
+ char line[MAX_LINE_LENGTH];
+ char name[MAX_LINE_LENGTH];
+ char value[MAX_LINE_LENGTH];
+
+ line[0] = '\0';
+ value[0] = '\0';
+
+ i = 0;
+ /* read a line ending with '\n' */
+ do {
+ len = read( fd, &line[i], 1 );
+ if( len == 1 )
+ i++;
+ else
+ quit = 1;
+ } while( !quit && i<MAX_LINE_LENGTH && line[i-1]!='\n' );
+
+
+ /* remove trailing whitespace */
+ line[i] = '\0';
+ i--;
+ while( i>=0 && IS_WHITESPACE(line[i]) )
+ {
+ line[i] = '\0';
+ i--;
+ }
+ len = i+1;
+
+ if( len>0 )
+ {
+ i = 0;
+ /* skip whitespace */
+ while( i<len && IS_WHITESPACE(line[i]) )
+ i++;
+
+ /* continue if this line is not a comment */
+ if( line[i] != COMMENT_TOKEN )
+ {
+ /* get the name part */
+ j=0;
+ while( i<len && line[i]!='=' && !IS_WHITESPACE(line[i]) )
+ {
+ name[j++] = line[i++];
+ }
+ name[j] = '\0';
+
+ /* skip '=' and whitespace */
+ while( i<len && (line[i]=='=' || IS_WHITESPACE(line[i])) )
+ i++;
+
+ /* get the value part */
+ j=0;
+ while( i<len )
+ {
+ value[j++] = line[i++];
+ }
+ value[j] = '\0';
+
+ match_found = 0;
+
+ /* enable colors */
+ if( !strcasecmp(CONF_ENABLE_COLORS, name) )
+ {
+ options->enable_colors = str2bool(value);
+ match_found = 1;
+ }
+ /* background color */
+ else if( !strcasecmp(CONF_COLOR_BACKGROUND, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->bg_color = color;
+ match_found = 1;
+ }
+ /* color - top (title) window */
+ else if( !strcasecmp(CONF_COLOR_TITLE, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->title_color = color;
+ match_found = 1;
+ }
+ /* color - line (title) window */
+ else if( !strcasecmp(CONF_COLOR_LINE, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->line_color = color;
+ match_found = 1;
+ }
+ /* color - list window */
+ else if( !strcasecmp(CONF_COLOR_LIST, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->list_color = color;
+ match_found = 1;
+ }
+ /* color - progress bar */
+ else if( !strcasecmp(CONF_COLOR_PROGRESS, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->progress_color = color;
+ match_found = 1;
+ }
+ /* color - status window */
+ else if( !strcasecmp(CONF_COLOR_STATUS, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->status_color = color;
+ match_found = 1;
+ }
+ /* color - alerts */
+ else if( !strcasecmp(CONF_COLOR_ALERT, name) )
+ {
+ if( (color=str2color(value)) >= 0 )
+ options->alert_color = color;
+ match_found = 1;
+ }
+
+
+ if( !match_found )
+ fprintf(stderr,
+ "Unknown configuration parameter: %s\n",
+ name);
+#ifdef DEBUG
+ printf( " %s = %s %s\n",
+ name,
+ value,
+ match_found ? "" : "- UNKNOWN SETTING!" );
+#endif
+
+ }
+ }
+ }
+
+ D(printf( "--\n\n" ));
+
+ if( free_filename )
+ free(filename);
+
+ return 0;
+}
+
+
+
+
+
+
diff --git a/conf.h b/conf.h
--- /dev/null
+++ b/conf.h
@@ -0,0 +1,3 @@
+
+int read_rc_file(char *filename, options_t *options);
+
diff --git a/configure.ac b/configure.ac
index 501e00e88e32f55fa030cb470d0aa2f22ab9fb40..531cc3b29c61b78e973d853d4d62698433522a7a 100644 (file)
--- a/configure.ac
+++ b/configure.ac
CFLAGS="$CFLAGS -g -DDEBUG"
fi
-dnl Enable
-AC_ARG_ENABLE(colors,
- [ --enable-colors Enable colors [default=no]],
- ,
- enable_colors=no)
-
-if test "$enable_colors" = yes; then
- CFLAGS="$CFLAGS -DENABLE_COLORS"
-fi
-
-
dnl Default charset
AC_ARG_WITH(default-charset,
[ --with-default-charset=ARG Default charset (ISO-8859-1)],
diff --git a/doc/ncmpcrc b/doc/ncmpcrc
--- /dev/null
+++ b/doc/ncmpcrc
@@ -0,0 +1,39 @@
+#
+# Configuration file for ncmpc (~/.ncmpcrc)
+#
+
+
+#
+# Color configuration
+#
+# colors: black,red,green,yellow,blue,magenta,cyan,white
+#
+
+# enable/disable colors
+enable_colors = yes
+
+# background color
+#background_color = blue
+
+# text colors
+#title_color = white
+#line_color = green
+#list_color = yellow
+#progress_color = green
+#status_color = white
+#alert_color = yellow
+
+
+#
+# Key bindings - NOT IMPLEMENTED
+#
+# key_up = 13
+
+
+#
+# Key names - NOT IMPLEMENTED
+#
+#key_name 13 Enter
+#
+
+
index c2c29b3aca577e651b5f04b53a97805b6555f4bd..0e36133295c2477b76cb52963c4dbba3aaa9d4d2 100644 (file)
--- a/main.c
+++ b/main.c
#include "options.h"
#include "command.h"
#include "screen.h"
+#include "conf.h"
+
static mpd_client_t *mpc = NULL;
struct sigaction act;
int counter, connected;
+ /* initialize options */
+ options = options_init();
+
+ /* read configuration */
+ read_rc_file(NULL, options);
+
/* parse command line options */
- options_init();
- options = options_parse(argc, argv);
+ options_parse(argc, argv);
/* initialize local charset */
if( charset_init() )
diff --git a/options.c b/options.c
index 9685ce3b22cc5b4323daef204043ec1d352025b5..8f684a10845b87f899ee451fa0db5c8d3d56a004 100644 (file)
--- a/options.c
+++ b/options.c
-/*
- * $Id: options.c,v 1.7 2004/03/17 11:34:36 kalle Exp $
- *
- */
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <ncurses.h>
#include <popt.h>
#include "config.h"
#include "options.h"
#include "command.h"
-static options_t options;
+options_t options;
static struct poptOption optionsTable[] = {
#ifdef DEBUG
#endif
{ "version", 'V', 0, 0, 'V', "Display version information." },
{ "keys", 'k', 0, 0, 'k', "Display key bindings." },
+ { "colors", 'c', 0, 0, 'c', "Enable colors." },
+ { "no-colors", 'C', 0, 0, 'C', "Disable colors." },
{ "exit", 'e', 0, 0, 'e', "Exit on connection errors." },
{ "port", 'p', POPT_ARG_INT, &options.port, 0,
"Connect to server on port [" DEFAULT_PORT_STR "].", "PORT" },
options.debug = 1;
break;
#endif
+ case 'c':
+ options.enable_colors = 1;
+ break;
+ case 'C':
+ options.enable_colors = 0;
+ break;
case 'V':
printf("Version " VERSION "\n");
exit(EXIT_SUCCESS);
return &options;
}
-void
+options_t *
options_init( void )
{
char *value;
else
options.port = DEFAULT_PORT;
options.reconnect = 1;
+
+ options.bg_color = COLOR_BLACK;
+ options.title_color = COLOR_BLUE;
+ options.line_color = COLOR_GREEN;
+ options.list_color = COLOR_YELLOW;
+ options.progress_color = COLOR_GREEN;
+ options.status_color = COLOR_RED;
+ options.alert_color = COLOR_MAGENTA;;
+
+ return &options;
}
diff --git a/options.h b/options.h
index 49af19984540c5169d62d4ead9d73fdb346563e5..a8ac179817ae6d348340b36be30ffd5f964834a4 100644 (file)
--- a/options.h
+++ b/options.h
#define MPD_HOST_ENV "MPD_HOST"
#define MPD_PORT_ENV "MPD_PORT"
+#define NCMPCRC_ENV "NCMPCRC"
+
typedef struct
{
int reconnect;
int debug;
+ int enable_colors;
+ int bg_color;
+ int title_color;
+ int line_color;
+ int list_color;
+ int progress_color;
+ int status_color;
+ int alert_color;
+
} options_t;
-void options_init(void);
+extern options_t options;
+
+options_t *options_init(void);
options_t *options_parse(int argc, const char **argv);
-options_t *get_options(void);
+
+
diff --git a/screen.c b/screen.c
index 3012fa31ae668494f3126b78bffd67c271f9a119..86269512527dc1ec8a5a37010e56e220d0917619 100644 (file)
--- a/screen.c
+++ b/screen.c
-/*
- * $Id: screen.c,v 1.10 2004/03/17 14:50:12 kalle Exp $
- *
- */
-
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include "libmpdclient.h"
#include "mpc.h"
#include "command.h"
+#include "options.h"
#include "screen.h"
#include "screen_play.h"
#include "screen_file.h"
#include "screen_help.h"
#include "screen_search.h"
+#include "screen_utils.h"
#define STATUS_MESSAGE_TIMEOUT 3
#define STATUS_LINE_MAX_SIZE 512
char buf[12];
wattron(w, A_BOLD);
- mvwaddstr(w, 0, 0, header );
+ mvwaddstr(w, 0, 0, header);
wattroff(w, A_BOLD);
if( volume==MPD_STATUS_NO_VOLUME )
{
}
mvwaddstr(w, 0, screen->top_window.cols-12, buf);
+ if( options.enable_colors )
+ wattron(w, LINE_COLORS);
+
mvwhline(w, 1, 0, ACS_HLINE, screen->top_window.cols);
+ if( options.enable_colors )
+ wattroff(w, LINE_COLORS);
+
wrefresh(w);
}
}
p = ((double) c->status->elapsedTime) / ((double) c->status->totalTime);
width = (int) (p * (double) screen->progress_window.cols);
-
mvwhline(screen->progress_window.w,
0, 0,
ACS_HLINE,
screen->progress_window.cols);
-
whline(screen->progress_window.w, '=', width-1);
-
mvwaddch(screen->progress_window.w, 0, width-1, 'O');
wrefresh(screen->progress_window.w);
}
wattroff(w, A_BOLD);
break;
case MPD_STATUS_STATE_PLAY:
+ wattron(w, A_BOLD);
waddstr(w, "Playing:");
+ wattroff(w, A_BOLD);
break;
case MPD_STATUS_STATE_PAUSE:
wattron(w, A_BOLD);
- waddstr(w, "Paused:");
+ waddstr(w, "[Paused]");
wattroff(w, A_BOLD);
break;
default:
- waddstr(w, "Warning: Music Player Daemon in unknown state!");
+ my_waddstr(w,
+ "Warning: Music Player Daemon in unknown state!",
+ ALERT_COLORS);
break;
}
x += 10;
- if( IS_PLAYING(status->state) && song )
+ if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) && song )
{
+ // my_mvwaddstr(w, 0, x, mpc_get_song_name(song), COLOR_PAIR(2));
mvwaddstr(w, 0, x, mpc_get_song_name(song));
}
/* time */
- if( IS_PLAYING(status->state) )
+ if( IS_PLAYING(status->state) || IS_PAUSED(status->state) )
{
x = screen->status_window.cols - strlen(screen->buf);
" [%i:%02i/%i:%02i] ",
status->elapsedTime/60, status->elapsedTime%60,
status->totalTime/60, status->totalTime%60 );
+ //my_mvwaddstr(w, 0, x, screen->buf, COLOR_PAIR(1));
mvwaddstr(w, 0, x, screen->buf);
}
wmove(w, 0, 0);
wclrtoeol(w);
wattron(w, A_BOLD);
- waddstr(w, msg);
+ my_waddstr(w, msg, ALERT_COLORS);
wattroff(w, A_BOLD);
wrefresh(w);
screen->status_timestamp = time(NULL);
/* initialize the curses library */
initscr();
start_color();
- use_default_colors();
+ if( options.enable_colors )
+ {
+ init_pair(1, options.title_color, options.bg_color);
+ init_pair(2, options.line_color, options.bg_color);
+ init_pair(3, options.list_color, options.bg_color);
+ init_pair(4, options.progress_color, options.bg_color);
+ init_pair(5, options.status_color, options.bg_color);
+ init_pair(6, options.alert_color, options.bg_color);
+ }
+ else
+ use_default_colors();
+
/* tell curses not to do NL->CR/NL on output */
nonl();
/* take input chars one at a time, no wait for \n */
keypad(stdscr, TRUE);
timeout(100); /*void wtimeout(WINDOW *win, int delay);*/
-
if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
{
fprintf(stderr, "Error: Screen to small!\n");
screen->status_window.cols,
screen->rows-1,
0);
+
leaveok(screen->status_window.w, FALSE);
keypad(screen->status_window.w, TRUE);
+ if( options.enable_colors )
+ {
+ /* set background attributes */
+ wbkgd(screen->main_window.w, LIST_COLORS);
+ wbkgd(screen->top_window.w, TITLE_COLORS);
+ wbkgd(screen->playlist->w, LIST_COLORS);
+ wbkgd(screen->filelist->w, LIST_COLORS);
+ wbkgd(screen->helplist->w, LIST_COLORS);
+ wbkgd(screen->progress_window.w, PROGRESS_COLORS);
+ wbkgd(screen->status_window.w, STATUS_COLORS);
+ }
+
return 0;
}
}
+;
diff --git a/screen.h b/screen.h
index 7b667d8238497f99097320cb41936ceba814bb6f..78ca39c48f4005e155573d036551f287340320eb 100644 (file)
--- a/screen.h
+++ b/screen.h
#include <ncurses.h>
#include "list_window.h"
+/* top window headers */
#define TOP_HEADER_PREFIX "Music Player Client - "
#define TOP_HEADER_PLAY TOP_HEADER_PREFIX "Playlist"
#define TOP_HEADER_FILE TOP_HEADER_PREFIX "Browse"
#define TOP_HEADER_HELP TOP_HEADER_PREFIX "Help "
#define TOP_HEADER_SEARCH TOP_HEADER_PREFIX "Search "
+/* colors */
+#define TITLE_COLORS COLOR_PAIR(1)
+#define LINE_COLORS COLOR_PAIR(2)
+#define LIST_COLORS COLOR_PAIR(3)
+#define PROGRESS_COLORS COLOR_PAIR(4)
+#define STATUS_COLORS COLOR_PAIR(5)
+#define ALERT_COLORS COLOR_PAIR(6)
+
+/* minumum window size */
#define SCREEN_MIN_COLS 14
#define SCREEN_MIN_ROWS 5
#define IS_PLAYING(s) (s==MPD_STATUS_STATE_PLAY)
+#define IS_PAUSED(s) (s==MPD_STATUS_STATE_PAUSE)
typedef enum
{
diff --git a/screen_file.c b/screen_file.c
index 809ae3faf81f16f67319d0a6f243c66052180d26..69ec858085665aae35dbd6273d88fdce7f873926 100644 (file)
--- a/screen_file.c
+++ b/screen_file.c
mpd_Song *song = entity->info.song;
return mpc_get_song_name(song);
}
-
- return NULL;
+ else if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE )
+ {
+ mpd_PlaylistFile *plf = entity->info.playlistFile;
+ char *filename = utf8_to_locale(basename(plf->path));
+
+ snprintf(buf, BUFSIZE, "%s*", filename);
+ free(filename);
+ return buf;
+ }
+ return "Error: Unknow entry!";
}
static void
diff --git a/screen_utils.c b/screen_utils.c
index 49bd6692a2682c3e14bd53940203af0c99cc3f93..648291f03af4be47f49098edb5edda76dc0b7266 100644 (file)
--- a/screen_utils.c
+++ b/screen_utils.c
#include "mpc.h"
#include "support.h"
#include "command.h"
+#include "options.h"
#include "screen.h"
char *
return line;
}
+int
+my_waddstr(WINDOW *w, const char *text, int color)
+{
+ int ret;
+
+ if( options.enable_colors )
+ wattron(w, color);
+ ret = waddstr(w, text);
+ if( options.enable_colors )
+ wattroff(w, color);
+
+ return ret;
+}
+
+int
+my_mvwaddstr(WINDOW *w, int x, int y, const char *text, int color)
+{
+ int ret;
+
+ if( options.enable_colors )
+ wattron(w, color);
+ ret = mvwaddstr(w, x, y, text);
+ if( options.enable_colors )
+ wattroff(w, color);
+
+ return ret;
+}
diff --git a/screen_utils.h b/screen_utils.h
index 70091f5c86a675b6ade53b7b071752cd86b28849..a03c36d477a2fd1e9f84febecd5c3a22c961d621 100644 (file)
--- a/screen_utils.h
+++ b/screen_utils.h
char *screen_readln(WINDOW *w, char *prompt);
+
+int my_waddstr(WINDOW *, const char *, int);
+int my_mvwaddstr(WINDOW *, int, int, const char *, int);
diff --git a/support.c b/support.c
index 28297e41846657f2a20f81ce625f6c4835302aa0..d7c196a9402f55d2eae09db23b69f2fa577227c8 100644 (file)
--- a/support.c
+++ b/support.c
return str;
}
+
+char *
+concat_path(char *p1, char *p2)
+{
+ size_t size;
+ char *path;
+ char append_slash = 0;
+
+ size = strlen(p1);
+ if( size==0 || p1[size-1]!='/' )
+ {
+ size++;
+ append_slash = 1;
+ }
+ size += strlen(p2);
+ size++;
+
+ path = calloc(size, sizeof(char));
+ strncpy(path, p1, size);
+ if( append_slash )
+ strncat(path, "/", size);
+ strncat(path, p2, size);
+
+ return path;
+}
+
+
+
#ifndef HAVE_BASENAME
char *
basename(char *path)
diff --git a/support.h b/support.h
index da5ac5ed800457bd9740264bb884ab5e0a11ad92..9e1a1b866da84b2bb9907ec19aa0cd4d57663bd5 100644 (file)
--- a/support.h
+++ b/support.h
#include <libgen.h>
#endif
+char *concat_path(char *p1, char *p2);
#ifndef HAVE_BASENAME
char *basename(char *path);