Commit 2f4ce5ec authored by Josh Poimboeuf's avatar Josh Poimboeuf Committed by Arnaldo Carvalho de Melo

perf tools: Finalize subcmd independence

For the files that will be moved to the subcmd library, remove all their
perf-specific includes and duplicate any needed functionality.
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/6e12946f0f26ce4d543d34db68d9dae3c8551cb9.1450193761.git.jpoimboe@redhat.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 46113a54
#include "cache.h"
#include "exec_cmd.h"
#include "quote.h"
#include "subcmd-config.h"
#include <linux/compiler.h>
#include <linux/string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "subcmd-util.h"
#include "exec_cmd.h"
#include "subcmd-config.h"
#define MAX_ARGS 32
#define PATH_MAX 4096
static const char *argv_exec_path;
static const char *argv0_path;
......@@ -20,6 +25,49 @@ void exec_cmd_init(const char *exec_name, const char *prefix,
subcmd_config.exec_path_env = exec_path_env;
}
#define is_dir_sep(c) ((c) == '/')
static int is_absolute_path(const char *path)
{
return path[0] == '/';
}
static const char *get_pwd_cwd(void)
{
static char cwd[PATH_MAX + 1];
char *pwd;
struct stat cwd_stat, pwd_stat;
if (getcwd(cwd, PATH_MAX) == NULL)
return NULL;
pwd = getenv("PWD");
if (pwd && strcmp(pwd, cwd)) {
stat(cwd, &cwd_stat);
if (!stat(pwd, &pwd_stat) &&
pwd_stat.st_dev == cwd_stat.st_dev &&
pwd_stat.st_ino == cwd_stat.st_ino) {
strlcpy(cwd, pwd, PATH_MAX);
}
}
return cwd;
}
static const char *make_nonrelative_path(const char *path)
{
static char buf[PATH_MAX + 1];
if (is_absolute_path(path)) {
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
} else {
const char *cwd = get_pwd_cwd();
if (!cwd)
die("Cannot determine the current working directory");
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
}
return buf;
}
char *system_path(const char *path)
{
char *buf = NULL;
......@@ -151,8 +199,10 @@ int execl_cmd(const char *cmd,...)
break;
}
va_end(param);
if (MAX_ARGS <= argc)
return error("too many args to run %s", cmd);
if (MAX_ARGS <= argc) {
fprintf(stderr, " Error: too many args to run %s\n", cmd);
return -1;
}
argv[argc] = NULL;
return execv_cmd(argv);
......
#include "cache.h"
#include "../builtin.h"
#include "exec_cmd.h"
#include "help.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include "subcmd-util.h"
#include "help.h"
#include "exec_cmd.h"
void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
{
......@@ -70,6 +77,28 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
cmds->cnt = cj;
}
static void get_term_dimensions(struct winsize *ws)
{
char *s = getenv("LINES");
if (s != NULL) {
ws->ws_row = atoi(s);
s = getenv("COLUMNS");
if (s != NULL) {
ws->ws_col = atoi(s);
if (ws->ws_row && ws->ws_col)
return;
}
}
#ifdef TIOCGWINSZ
if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
ws->ws_row && ws->ws_col)
return;
#endif
ws->ws_row = 25;
ws->ws_col = 80;
}
static void pretty_print_string_list(struct cmdnames *cmds, int longest)
{
int cols = 1, rows;
......@@ -113,6 +142,14 @@ static int is_executable(const char *name)
return st.st_mode & S_IXUSR;
}
static int has_extension(const char *filename, const char *ext)
{
size_t len = strlen(filename);
size_t extlen = strlen(ext);
return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
}
static void list_commands_in_dir(struct cmdnames *cmds,
const char *path,
const char *prefix)
......@@ -168,7 +205,7 @@ void load_command_list(const char *prefix,
char *paths, *path, *colon;
path = paths = strdup(env_path);
while (1) {
if ((colon = strchr(path, PATH_SEP)))
if ((colon = strchr(path, ':')))
*colon = 0;
if (!exec_path || strcmp(path, exec_path))
list_commands_in_dir(other_cmds, path, prefix);
......
#ifndef __PERF_HELP_H
#define __PERF_HELP_H
#include <sys/types.h>
struct cmdnames {
size_t alloc;
size_t cnt;
struct cmdname {
size_t len; /* also used for similarity index in help.c */
char name[FLEX_ARRAY];
char name[];
} **names;
};
......
#include "cache.h"
#include <sys/select.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include "pager.h"
#include "run-command.h"
#include "sigchain.h"
#include "subcmd-config.h"
......
#include "util.h"
#include <linux/compiler.h>
#include <linux/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include "subcmd-util.h"
#include "parse-options.h"
#include "cache.h"
#include "header.h"
#include "subcmd-config.h"
#include <linux/string.h>
#include "pager.h"
#define OPT_SHORT 1
#define OPT_UNSET 2
......@@ -14,20 +18,29 @@ char *error_buf;
static int opterror(const struct option *opt, const char *reason, int flags)
{
if (flags & OPT_SHORT)
return error("switch `%c' %s", opt->short_name, reason);
if (flags & OPT_UNSET)
return error("option `no-%s' %s", opt->long_name, reason);
return error("option `%s' %s", opt->long_name, reason);
fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
else if (flags & OPT_UNSET)
fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
else
fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);
return -1;
}
static const char *skip_prefix(const char *str, const char *prefix)
{
size_t len = strlen(prefix);
return strncmp(str, prefix, len) ? NULL : str + len;
}
static void optwarning(const struct option *opt, const char *reason, int flags)
{
if (flags & OPT_SHORT)
warning("switch `%c' %s", opt->short_name, reason);
fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
else if (flags & OPT_UNSET)
warning("option `no-%s' %s", opt->long_name, reason);
fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
else
warning("option `%s' %s", opt->long_name, reason);
fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
}
static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
......@@ -71,10 +84,10 @@ static int get_value(struct parse_opt_ctx_t *p,
if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
p->excl_opt->long_name == NULL) {
scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
p->excl_opt->short_name);
} else {
scnprintf(msg, sizeof(msg), "cannot be used with %s",
snprintf(msg, sizeof(msg), "cannot be used with %s",
p->excl_opt->long_name);
}
opterror(opt, msg, flags);
......@@ -401,14 +414,16 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
return get_value(p, options, flags);
}
if (ambiguous_option)
return error("Ambiguous option: %s "
"(could be --%s%s or --%s%s)",
if (ambiguous_option) {
fprintf(stderr,
" Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
arg,
(ambiguous_flags & OPT_UNSET) ? "no-" : "",
ambiguous_option->long_name,
(abbrev_flags & OPT_UNSET) ? "no-" : "",
abbrev_option->long_name);
return -1;
}
if (abbrev_option)
return get_value(p, abbrev_option, abbrev_flags);
return -2;
......@@ -420,7 +435,7 @@ static void check_typos(const char *arg, const struct option *options)
return;
if (!prefixcmp(arg, "no-")) {
error ("did you mean `--%s` (with two dashes ?)", arg);
fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
exit(129);
}
......@@ -428,7 +443,7 @@ static void check_typos(const char *arg, const struct option *options)
if (!options->long_name)
continue;
if (!prefixcmp(options->long_name, arg)) {
error ("did you mean `--%s` (with two dashes ?)", arg);
fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
exit(129);
}
}
......@@ -746,16 +761,18 @@ static int option__cmp(const void *va, const void *vb)
static struct option *options__order(const struct option *opts)
{
int nr_opts = 0;
int nr_opts = 0, len;
const struct option *o = opts;
struct option *ordered;
for (o = opts; o->type != OPTION_END; o++)
++nr_opts;
ordered = memdup(opts, sizeof(*o) * (nr_opts + 1));
if (ordered == NULL)
len = sizeof(*o) * (nr_opts + 1);
ordered = malloc(len);
if (!ordered)
goto out;
memcpy(ordered, opts, len);
qsort(ordered, nr_opts, sizeof(*o), option__cmp);
out:
......
#ifndef __PERF_PARSE_OPTIONS_H
#define __PERF_PARSE_OPTIONS_H
#include <linux/kernel.h>
#include <stdbool.h>
#include <stdint.h>
enum parse_opt_type {
/* special types */
......
#include "cache.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include "subcmd-util.h"
#include "run-command.h"
#include "exec_cmd.h"
#include "debug.h"
#define STRERR_BUFSIZE 128
static inline void close_pair(int fd[2])
{
......@@ -164,7 +172,7 @@ static int wait_or_whine(pid_t pid)
if (waiting < 0) {
if (errno == EINTR)
continue;
error("waitpid failed (%s)",
fprintf(stderr, " Error: waitpid failed (%s)",
strerror_r(errno, sbuf, sizeof(sbuf)));
return -ERR_RUN_COMMAND_WAITPID;
}
......
#ifndef __PERF_RUN_COMMAND_H
#define __PERF_RUN_COMMAND_H
#include <unistd.h>
enum {
ERR_RUN_COMMAND_FORK = 10000,
ERR_RUN_COMMAND_EXEC,
......
#include <signal.h>
#include "subcmd-util.h"
#include "sigchain.h"
#include "cache.h"
#define SIGCHAIN_MAX_SIGNALS 32
......
#ifndef __PERF_SUBCMD_UTIL_H
#define __PERF_SUBCMD_UTIL_H
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#define NORETURN __attribute__((__noreturn__))
static inline void report(const char *prefix, const char *err, va_list params)
{
char msg[1024];
vsnprintf(msg, sizeof(msg), err, params);
fprintf(stderr, " %s%s\n", prefix, msg);
}
static NORETURN inline void die(const char *err, ...)
{
va_list params;
va_start(params, err);
report(" Fatal: ", err, params);
exit(128);
va_end(params);
}
#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
#define alloc_nr(x) (((x)+16)*3/2)
/*
* Realloc the buffer pointed at by variable 'x' so that it can hold
* at least 'nr' entries; the number of entries currently allocated
* is 'alloc', using the standard growing factor alloc_nr() macro.
*
* DO NOT USE any expression with side-effect for 'x' or 'alloc'.
*/
#define ALLOC_GROW(x, nr, alloc) \
do { \
if ((nr) > alloc) { \
if (alloc_nr(alloc) < (nr)) \
alloc = (nr); \
else \
alloc = alloc_nr(alloc); \
x = xrealloc((x), alloc * sizeof(*(x))); \
} \
} while(0)
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret) {
ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret)
die("Out of memory, realloc failed");
}
return ret;
}
#define astrcatf(out, fmt, ...) \
({ \
char *tmp = *(out); \
......@@ -21,4 +79,13 @@ static inline void astrcat(char **out, const char *add)
free(tmp);
}
static inline int prefixcmp(const char *str, const char *prefix)
{
for (; ; str++, prefix++)
if (!*prefix)
return 0;
else if (*str != *prefix)
return (unsigned char)*prefix - (unsigned char)*str;
}
#endif /* __PERF_SUBCMD_UTIL_H */
......@@ -151,12 +151,6 @@ extern void set_warning_routine(void (*routine)(const char *err, va_list params)
extern int prefixcmp(const char *str, const char *prefix);
extern void set_buildid_dir(const char *dir);
static inline const char *skip_prefix(const char *str, const char *prefix)
{
size_t len = strlen(prefix);
return strncmp(str, prefix, len) ? NULL : str + len;
}
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL
......@@ -187,14 +181,6 @@ static inline void *zalloc(size_t size)
#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
static inline int has_extension(const char *filename, const char *ext)
{
size_t len = strlen(filename);
size_t extlen = strlen(ext);
return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
}
/* Sane ctype - no locale, and works with signed chars */
#undef isascii
#undef isspace
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment