[Forensics-changes] [yara] 228/407: Replace argparse with my own argument parsing code
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:28:29 UTC 2017
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag v3.3.0
in repository yara.
commit 116b5e1b3bdfa4e787f722f91de08f0dc26ccc3c
Author: Victor Manuel Alvarez <vmalvarez at virustotal.com>
Date: Sat Nov 22 23:38:48 2014 +0100
Replace argparse with my own argument parsing code
---
Makefile.am | 12 +-
argparse/.gitignore | 5 -
argparse/.travis.yml | 5 -
argparse/LICENSE | 21 ---
argparse/README.md | 89 ----------
argparse/argparse.c | 366 --------------------------------------
argparse/argparse.h | 165 ------------------
argparse/tap-functions | 445 -----------------------------------------------
argparse/test.sh | 46 -----
argparse/test_argparse.c | 57 ------
args.c | 278 +++++++++++++++++++++++++++++
args.h | 92 ++++++++++
yara.c | 64 ++++---
yarac.c | 50 ++++--
14 files changed, 456 insertions(+), 1239 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 6c237a4..74dd4e1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,18 +1,18 @@
AM_CFLAGS=-O3 -std=gnu99 -Wall -I$(srcdir)/libyara/include
# Build the library in the hand subdirectory first.
-SUBDIRS = libyara argparse
-DIST_SUBDIRS = libyara argparse
+SUBDIRS = libyara
+DIST_SUBDIRS = libyara
ACLOCAL_AMFLAGS=-I m4
bin_PROGRAMS = yara yarac
-yara_SOURCES = threading.c threading.h yara.c
-yara_LDADD = libyara/.libs/libyara.a argparse/libargparse.a
+yara_SOURCES = args.c args.h threading.c threading.h yara.c
+yara_LDADD = libyara/.libs/libyara.a
-yarac_SOURCES = yarac.c
-yarac_LDADD = libyara/.libs/libyara.a argparse/libargparse.a
+yarac_SOURCES = args.c args.h yarac.c
+yarac_LDADD = libyara/.libs/libyara.a
# man pages
man1_MANS = yara.man yarac.man
diff --git a/argparse/.gitignore b/argparse/.gitignore
deleted file mode 100755
index fb716d2..0000000
--- a/argparse/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-tags
-test_argparse
-*.[ao]
-*.dylib
-*.so
diff --git a/argparse/.travis.yml b/argparse/.travis.yml
deleted file mode 100755
index 41bac87..0000000
--- a/argparse/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: c
-compiler:
- - gcc
- - clang
-script: make test
diff --git a/argparse/LICENSE b/argparse/LICENSE
deleted file mode 100755
index 3c77749..0000000
--- a/argparse/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2012-2013 Yecheng Fu <cofyc.jackson at gmail.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/argparse/README.md b/argparse/README.md
deleted file mode 100755
index 6d2ee87..0000000
--- a/argparse/README.md
+++ /dev/null
@@ -1,89 +0,0 @@
-NAME
-====
-
-argparse - A command line arguments parsing library.
-
-[](https://travis-ci.org/Cofyc/argparse)
-
-DESCRIPTION
-===========
-
-This module is inspired by parse-options.c (git) and python's argparse
-module.
-
-Arguments parsing is common task in cli program, but traditional `getopt`
-libraries are not easy to use. This library provides high-level arguments
-parsing solutions.
-
-The program defines what arguments it requires, and `argparse` will figure
-out how to parse those out of `argc` and `argv`, it also automatically
-generates help and usage messages and issues errors when users give the
-program invalid arguments.
-
-Features
-========
-
- - handles both optional and positional arguments
- - produces highly informative usage messages
- - issures errors when given invalid arguments
-
-There are basically three types of options:
-
- - boolean options
- - options with mandatory argument
- - options with optional argument
-
-There are basically two forms of options:
-
- - short option consist of one dash (`-`) and one alphanumeric character.
- - long option begin with two dashes (`--`) and some alphanumeric characters.
-
-Short options may be bundled, e.g. `-a -b` can be specified as `-ab`.
-
-Options are case-sensitive.
-
-Options and non-option arguments can clearly be separated using the `--` option.
-
-Examples
-========
-
-```c
-#include "argparse.h"
-
-static const char *const usage[] = {
- "test_argparse [options] [[--] args]",
- NULL,
-};
-
-int
-main(int argc, const char **argv)
-{
- int force = 0;
- int num = 0;
- const char *path = NULL;
- struct argparse_option options[] = {
- OPT_HELP(),
- OPT_BOOLEAN('f', "force", &force, "force to do", NULL),
- OPT_STRING('p', "path", &path, "path to read", NULL),
- OPT_INTEGER('n', "num", &num, "selected num", NULL),
- OPT_END(),
- };
- struct argparse argparse;
- argparse_init(&argparse, options, usage, 0);
- argc = argparse_parse(&argparse, argc, argv);
- if (force != 0)
- printf("force: %d\n", force);
- if (path != NULL)
- printf("path: %s\n", path);
- if (num != 0)
- printf("num: %d\n", num);
- if (argc != 0) {
- printf("argc: %d\n", argc);
- int i;
- for (i = 0; i < argc; i++) {
- printf("argv[%d]: %s\n", i, *(argv + i));
- }
- }
- return 0;
-}
-```
diff --git a/argparse/argparse.c b/argparse/argparse.c
deleted file mode 100755
index e60b76c..0000000
--- a/argparse/argparse.c
+++ /dev/null
@@ -1,366 +0,0 @@
-#include "argparse.h"
-
-#define OPT_UNSET 1
-
-static const char *
-prefix_skip(const char *str, const char *prefix)
-{
- size_t len = strlen(prefix);
- return strncmp(str, prefix, len) ? NULL : str + len;
-}
-
-int
-prefix_cmp(const char *str, const char *prefix)
-{
- for (;; str++, prefix++)
- if (!*prefix)
- return 0;
- else if (*str != *prefix)
- return (unsigned char)*prefix - (unsigned char)*str;
-}
-
-static void
-argparse_error(struct argparse *self, struct argparse_option *opt,
- const char *reason)
-{
- if (!strncmp(self->argv[0], "--", 2)) {
- fprintf(stderr, "error: option `%s` %s\n", opt->long_name, reason);
- exit(1);
- } else {
- fprintf(stderr, "error: option `%c` %s\n", opt->short_name, reason);
- exit(1);
- }
-}
-
-static int
-argparse_getvalue(struct argparse *self, struct argparse_option *opt,
- int flags)
-{
- const char *s = NULL;
-
- if (opt->count == opt->max_count)
- argparse_error(self, opt, "repeated too many times");
-
- if (!opt->value)
- goto skipped;
-
- switch (opt->type) {
- case ARGPARSE_OPT_BOOLEAN:
- if (flags & OPT_UNSET) {
- *(int *)opt->value = *(int *)opt->value - 1;
- } else {
- *(int *)opt->value = *(int *)opt->value + 1;
- }
- if (*(int *)opt->value < 0) {
- *(int *)opt->value = 0;
- }
- break;
- case ARGPARSE_OPT_BIT:
- if (flags & OPT_UNSET) {
- *(int *)opt->value &= ~opt->data;
- } else {
- *(int *)opt->value |= opt->data;
- }
- break;
- case ARGPARSE_OPT_STRING:
- if (self->optvalue) {
- *(const char **)opt->value = self->optvalue;
- self->optvalue = NULL;
- } else if (self->argc > 1) {
- self->argc--;
- if (opt->max_count > 1) {
- ((const char**)opt->value)[opt->count] = *++self->argv;
- }
- else {
- *(const char **)opt->value = *++self->argv;
- }
- } else {
- argparse_error(self, opt, "requires a value");
- }
- break;
- case ARGPARSE_OPT_INTEGER:
- if (self->optvalue) {
- *(int *)opt->value = strtol(self->optvalue, (char **)&s, 0);
- self->optvalue = NULL;
- } else if (self->argc > 1) {
- self->argc--;
- if (opt->max_count > 1) {
- ((int*)opt->value)[opt->count] = strtol(*++self->argv, (char **)&s, 0);
- }
- else {
- *(int *)opt->value = strtol(*++self->argv, (char **)&s, 0);
- }
- } else {
- argparse_error(self, opt, "requires a value");
- }
- if (s[0] != '\0')
- argparse_error(self, opt, "expects a numerical value");
- break;
- default:
- assert(0);
- }
-
- opt->count++;
-
-skipped:
- if (opt->callback) {
- return opt->callback(self, opt);
- }
-
- return 0;
-}
-
-static void
-argparse_options_check(struct argparse_option *options)
-{
- for (; options->type != ARGPARSE_OPT_END; options++) {
- switch (options->type) {
- case ARGPARSE_OPT_END:
- case ARGPARSE_OPT_BOOLEAN:
- case ARGPARSE_OPT_BIT:
- case ARGPARSE_OPT_INTEGER:
- case ARGPARSE_OPT_STRING:
- case ARGPARSE_OPT_GROUP:
- continue;
- default:
- fprintf(stderr, "wrong option type: %d", options->type);
- break;
- }
- }
-}
-
-static int
-argparse_short_opt(struct argparse *self, struct argparse_option *options)
-{
- for (; options->type != ARGPARSE_OPT_END; options++) {
- if (options->short_name == *self->optvalue) {
- self->optvalue = self->optvalue[1] ? self->optvalue + 1 : NULL;
- return argparse_getvalue(self, options, 0);
- }
- }
- return -2;
-}
-
-static int
-argparse_long_opt(struct argparse *self, struct argparse_option *options)
-{
- for (; options->type != ARGPARSE_OPT_END; options++) {
- const char *rest;
- int opt_flags = 0;
- if (!options->long_name)
- continue;
-
- rest = prefix_skip(self->argv[0] + 2, options->long_name);
- if (!rest) {
- // Negation allowed?
- if (options->flags & OPT_NONEG) {
- continue;
- }
- // Only boolean/bit allow negation.
- if (options->type != ARGPARSE_OPT_BOOLEAN && options->type != ARGPARSE_OPT_BIT) {
- continue;
- }
-
- if (!prefix_cmp(self->argv[0] + 2, "no-")) {
- rest = prefix_skip(self->argv[0] + 2 + 3, options->long_name);
- if (!rest)
- continue;
- opt_flags |= OPT_UNSET;
- } else {
- continue;
- }
- }
- if (*rest) {
- if (*rest != '=')
- continue;
- self->optvalue = rest + 1;
- }
- return argparse_getvalue(self, options, opt_flags);
- }
- return -2;
-}
-
-int
-argparse_init(struct argparse *self, struct argparse_option *options,
- const char *const *usage, int flags)
-{
- memset(self, 0, sizeof(*self));
- self->options = options;
- self->usage = usage;
- self->flags = flags;
-
- for (; options->type != ARGPARSE_OPT_END; options++)
- options->count = 0;
-
- return 0;
-}
-
-int
-argparse_parse(struct argparse *self, int argc, const char **argv)
-{
- self->argc = argc - 1;
- self->argv = argv + 1;
- self->out = argv;
-
- argparse_options_check(self->options);
-
- for (; self->argc; self->argc--, self->argv++) {
- const char *arg = self->argv[0];
- if (arg[0] != '-' || !arg[1]) {
- if (self->flags & ARGPARSE_STOP_AT_NON_OPTION) {
- goto end;
- }
- // if it's not option or is a single char '-', copy verbatimly
- self->out[self->cpidx++] = self->argv[0];
- continue;
- }
- // short option
- if (arg[1] != '-') {
- self->optvalue = arg + 1;
- switch (argparse_short_opt(self, self->options)) {
- case -1:
- break;
- case -2:
- goto unknown;
- }
- while (self->optvalue) {
- switch (argparse_short_opt(self, self->options)) {
- case -1:
- break;
- case -2:
- goto unknown;
- }
- }
- continue;
- }
- // if '--' presents
- if (!arg[2]) {
- self->argc--;
- self->argv++;
- break;
- }
- // long option
- switch (argparse_long_opt(self, self->options)) {
- case -1:
- break;
- case -2:
- goto unknown;
- }
- continue;
-
-unknown:
- fprintf(stderr, "error: unknown option `%s`\n", self->argv[0]);
- argparse_usage(self);
- exit(1);
- }
-
-end:
- memmove(self->out + self->cpidx, self->argv,
- self->argc * sizeof(*self->out));
- self->out[self->cpidx + self->argc] = NULL;
-
- return self->cpidx + self->argc;
-}
-
-void
-argparse_usage(struct argparse *self)
-{
- fprintf(stdout, "Usage: %s\n", *self->usage++);
- while (*self->usage && **self->usage)
- fprintf(stdout, " or: %s\n", *self->usage++);
- fputc('\n', stdout);
-
- struct argparse_option *options;
-
- // figure out best width
- size_t usage_opts_width = 0;
- size_t len;
- options = self->options;
- for (; options->type != ARGPARSE_OPT_END; options++) {
- len = 0;
- if ((options)->short_name) {
- len += 2;
- }
- if ((options)->short_name && (options)->long_name) {
- len += 2; // separator ", "
- }
- if ((options)->long_name) {
- len += strlen((options)->long_name) + 2;
- }
- if (options->type == ARGPARSE_OPT_INTEGER) {
- len++; // equal sign "=" or space
- if (options->type_help != NULL)
- len += strlen(options->type_help);
- else
- len += strlen("<int>");
- } else if (options->type == ARGPARSE_OPT_STRING) {
- len++; // equal sign "=" or space
- if (options->type_help != NULL)
- len += strlen(options->type_help);
- else
- len += strlen("<str>");
- }
- len = (len / 4) * 4 + 4;
- if (usage_opts_width < len) {
- usage_opts_width = len;
- }
- }
- usage_opts_width += 4; // 4 spaces prefix
-
- options = self->options;
- for (; options->type != ARGPARSE_OPT_END; options++) {
- size_t pos = 0;
- size_t pad = 0;
- if (options->type == ARGPARSE_OPT_GROUP) {
- fputc('\n', stdout);
- fprintf(stdout, "%s", options->help);
- fputc('\n', stdout);
- continue;
- }
- pos = fprintf(stdout, " ");
- if (options->short_name) {
- pos += fprintf(stdout, "-%c", options->short_name);
- }
- if (options->long_name && options->short_name) {
- pos += fprintf(stdout, ", ");
- }
- if (options->long_name) {
- pos += fprintf(stdout, "--%s", options->long_name);
- }
- if (options->type == ARGPARSE_OPT_INTEGER) {
- if (options->long_name)
- pos += fprintf(stdout, "=");
- else
- pos += fprintf(stdout, " ");
- if (options->type_help != NULL)
- pos += fprintf(stdout, "%s", options->type_help);
- else
- pos += fprintf(stdout, "<int>");
- } else if (options->type == ARGPARSE_OPT_STRING) {
- if (options->long_name)
- pos += fprintf(stdout, "=");
- else
- pos += fprintf(stdout, " ");
- if (options->type_help != NULL)
- pos += fprintf(stdout, "%s", options->type_help);
- else
- pos += fprintf(stdout, "<str>");
- }
- if (pos <= usage_opts_width) {
- pad = usage_opts_width - pos;
- } else {
- fputc('\n', stdout);
- pad = usage_opts_width;
- }
- fprintf(stdout, "%*s%s\n", pad + 2, "", options->help);
- }
-}
-
-int
-argparse_help_cb(struct argparse *self, const struct argparse_option *option)
-{
- (void)option;
- argparse_usage(self);
- exit(0);
- return 0;
-}
diff --git a/argparse/argparse.h b/argparse/argparse.h
deleted file mode 100755
index 183be46..0000000
--- a/argparse/argparse.h
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef ARGPARSE_H
-#define ARGPARSE_H
-/**
- * Command-line arguments parsing library.
- *
- * This module is inspired by parse-options.c (git) and python's argparse
- * module.
- *
- * Arguments parsing is common task in cli program, but traditional `getopt`
- * libraries are not easy to use. This library provides high-level arguments
- * parsing solutions.
- *
- * The program defines what arguments it requires, and `argparse` will figure
- * out how to parse those out of `argc` and `argv`, it also automatically
- * generates help and usage messages and issues errors when users give the
- * program invalid arguments.
- *
- * Reserved namespaces:
- * argparse
- * OPT
- * Author: Yecheng Fu <cofyc.jackson at gmail.com>
- */
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct argparse;
-struct argparse_option;
-
-typedef int argparse_callback(struct argparse *self,
- const struct argparse_option *option);
-
-enum argparse_flag {
- ARGPARSE_STOP_AT_NON_OPTION = 1,
-};
-
-enum argparse_option_type {
- /* special */
- ARGPARSE_OPT_END,
- ARGPARSE_OPT_GROUP,
- /* options with no arguments */
- ARGPARSE_OPT_BOOLEAN,
- ARGPARSE_OPT_BIT,
- /* options with arguments (optional or required) */
- ARGPARSE_OPT_INTEGER,
- ARGPARSE_OPT_STRING,
- /* repetable options */
- ARGPARSE_OPT_INTEGER_MULTI,
- ARGPARSE_OPT_STRING_MULTI,
-};
-
-enum argparse_option_flags {
- OPT_NONEG = 1, /* Negation disabled. */
-};
-
-/*
- * Argparse option struct.
- *
- * `type`:
- * holds the type of the option, you must have an ARGPARSE_OPT_END last in your
- * array.
- *
- * `short_name`:
- * the character to use as a short option name, '\0' if none.
- *
- * `long_name`:
- * the long option name, without the leading dash, NULL if none.
- *
- * `value`:
- * stores pointer to the value to be filled.
- *
- * `max_count`:
- *
- * maximum number of times self option can appear in the command line.
- *
- * `help`:
- * the short help message associated to what the option does.
- * Must never be NULL (except for ARGPARSE_OPT_END).
- *
- * `callback`:
- * function is called when corresponding argument is parsed.
- *
- * `data`:
- * associated data. Callbacks can use it like they want.
- *
- * `flags`:
- * option flags.
- *
- *
- *
- */
-struct argparse_option {
- enum argparse_option_type type;
- const char short_name;
- const char *long_name;
- void *value;
- int max_count;
- const char *help;
- const char *type_help;
- argparse_callback *callback;
- intptr_t data;
- int flags;
- int count;
-};
-
-/*
- * argpparse
- */
-struct argparse {
- // user supplied
- struct argparse_option *options;
- const char *const *usage;
- int flags;
- // internal context
- int argc;
- const char **argv;
- const char **out;
- int cpidx;
- const char *optvalue; // current option value
-};
-
-// builtin callbacks
-int argparse_help_cb(struct argparse *self,
- const struct argparse_option *option);
-
-// builtin option macros
-#define OPT_BIT(short_name, long_name, value, ...) \
- { ARGPARSE_OPT_BIT, short_name, long_name, value, 1, __VA_ARGS__ }
-
-#define OPT_BOOLEAN(short_name, long_name, value, ...) \
- { ARGPARSE_OPT_BOOLEAN, short_name, long_name, value, 1, __VA_ARGS__ }
-
-#define OPT_INTEGER(short_name, long_name, value, ...) \
- { ARGPARSE_OPT_INTEGER, short_name, long_name, value, 1, __VA_ARGS__ }
-
-#define OPT_STRING_MULTI(short_name, long_name, value, max_count, ...) \
- { ARGPARSE_OPT_STRING, short_name, long_name, value, max_count, __VA_ARGS__ }
-
-#define OPT_STRING(short_name, long_name, value, ...) \
- OPT_STRING_MULTI(short_name, long_name, value, 1, __VA_ARGS__)
-
-
-#define OPT_GROUP(h) { ARGPARSE_OPT_GROUP, 0, NULL, NULL, h }
-#define OPT_END() { ARGPARSE_OPT_END, 0 }
-
-#define OPT_HELP() OPT_BOOLEAN('h', "help", NULL, "show self help message and exit", NULL, argparse_help_cb)
-
-
-int argparse_init(struct argparse *self, struct argparse_option *options,
- const char *const *usage, int flags);
-int argparse_parse(struct argparse *self, int argc, const char **argv);
-void argparse_usage(struct argparse *self);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/argparse/tap-functions b/argparse/tap-functions
deleted file mode 100755
index 84f700e..0000000
--- a/argparse/tap-functions
+++ /dev/null
@@ -1,445 +0,0 @@
-#!/bin/bash
-
-
-_version='1.02'
-
-_plan_set=0
-_no_plan=0
-_skip_all=0
-_test_died=0
-_expected_tests=0
-_executed_tests=0
-_failed_tests=0
-TODO=
-
-
-usage(){
- cat <<'USAGE'
-tap-functions: A TAP-producing BASH library
-
-PLAN:
- plan_no_plan
- plan_skip_all [REASON]
- plan_tests NB_TESTS
-
-TEST:
- ok RESULT [NAME]
- okx COMMAND
- is RESULT EXPECTED [NAME]
- isnt RESULT EXPECTED [NAME]
- like RESULT PATTERN [NAME]
- unlike RESULT PATTERN [NAME]
- pass [NAME]
- fail [NAME]
-
-SKIP:
- skip [CONDITION] [REASON] [NB_TESTS=1]
-
- skip $feature_not_present "feature not present" 2 || {
- is $a "a"
- is $b "b"
- }
-
-TODO:
- Specify TODO mode by setting $TODO:
- TODO="not implemented yet"
- ok $result "some not implemented test"
- unset TODO
-
-OTHER:
- diag MSG
-
-EXAMPLE:
- #!/bin/bash
-
- . tap-functions
-
- plan_tests 7
-
- me=$USER
- is $USER $me "I am myself"
- like $HOME $me "My home is mine"
- like "`id`" $me "My id matches myself"
-
- /bin/ls $HOME 1>&2
- ok $? "/bin/ls $HOME"
- # Same thing using okx shortcut
- okx /bin/ls $HOME
-
- [[ "`id -u`" != "0" ]]
- i_am_not_root=$?
- skip $i_am_not_root "Must be root" || {
- okx ls /root
- }
-
- TODO="figure out how to become root..."
- okx [ "$HOME" == "/root" ]
- unset TODO
-USAGE
- exit
-}
-
-opt=
-set_u=
-while getopts ":sx" opt ; do
- case $_opt in
- u) set_u=1 ;;
- *) usage ;;
- esac
-done
-shift $(( OPTIND - 1 ))
-# Don't allow uninitialized variables if requested
-[[ -n "$set_u" ]] && set -u
-unset opt set_u
-
-# Used to call _cleanup on shell exit
-trap _exit EXIT
-
-
-
-plan_no_plan(){
- (( _plan_set != 0 )) && "You tried to plan twice!"
-
- _plan_set=1
- _no_plan=1
-
- return 0
-}
-
-
-plan_skip_all(){
- local reason=${1:-''}
-
- (( _plan_set != 0 )) && _die "You tried to plan twice!"
-
- _print_plan 0 "Skip $reason"
-
- _skip_all=1
- _plan_set=1
- _exit 0
-
- return 0
-}
-
-
-plan_tests(){
- local tests=${1:?}
-
- (( _plan_set != 0 )) && _die "You tried to plan twice!"
- (( tests == 0 )) && _die "You said to run 0 tests! You've got to run something."
-
- _print_plan $tests
- _expected_tests=$tests
- _plan_set=1
-
- return $tests
-}
-
-
-_print_plan(){
- local tests=${1:?}
- local directive=${2:-''}
-
- echo -n "1..$tests"
- [[ -n "$directive" ]] && echo -n " # $directive"
- echo
-}
-
-
-pass(){
- local name=$1
- ok 0 "$name"
-}
-
-
-fail(){
- local name=$1
- ok 1 "$name"
-}
-
-
-# This is the workhorse method that actually
-# prints the tests result.
-ok(){
- local result=${1:?}
- local name=${2:-''}
-
- (( _plan_set == 0 )) && _die "You tried to run a test without a plan! Gotta have a plan."
-
- _executed_tests=$(( $_executed_tests + 1 ))
-
- if [[ -n "$name" ]] ; then
- if _matches "$name" "^[0-9]+$" ; then
- diag " You named your test '$name'. You shouldn't use numbers for your test names."
- diag " Very confusing."
- fi
- fi
-
- if (( result != 0 )) ; then
- echo -n "not "
- _failed_tests=$(( _failed_tests + 1 ))
- fi
- echo -n "ok $_executed_tests"
-
- if [[ -n "$name" ]] ; then
- local ename=${name//\#/\\#}
- echo -n " - $ename"
- fi
-
- if [[ -n "$TODO" ]] ; then
- echo -n " # TODO $TODO" ;
- if (( result != 0 )) ; then
- _failed_tests=$(( _failed_tests - 1 ))
- fi
- fi
-
- echo
- if (( result != 0 )) ; then
- local file='tap-functions'
- local func=
- local line=
-
- local i=0
- local bt=$(caller $i)
- while _matches "$bt" "tap-functions$" ; do
- i=$(( $i + 1 ))
- bt=$(caller $i)
- done
- local backtrace=
- eval $(caller $i | (read line func file ; echo "backtrace=\"$file:$func() at line $line.\""))
-
- local t=
- [[ -n "$TODO" ]] && t="(TODO) "
-
- if [[ -n "$name" ]] ; then
- diag " Failed ${t}test '$name'"
- diag " in $backtrace"
- else
- diag " Failed ${t}test in $backtrace"
- fi
- fi
-
- return $result
-}
-
-
-okx(){
- local command="$@"
-
- local line=
- diag "Output of '$command':"
- $command | while read line ; do
- diag "$line"
- done
- ok ${PIPESTATUS[0]} "$command"
-}
-
-
-_equals(){
- local result=${1:?}
- local expected=${2:?}
-
- if [[ "$result" == "$expected" ]] ; then
- return 0
- else
- return 1
- fi
-}
-
-
-# Thanks to Aaron Kangas for the patch to allow regexp matching
-# under bash < 3.
- _bash_major_version=${BASH_VERSION%%.*}
-_matches(){
- local result=${1:?}
- local pattern=${2:?}
-
- if [[ -z "$result" || -z "$pattern" ]] ; then
- return 1
- else
- if (( _bash_major_version >= 3 )) ; then
- eval '[[ "$result" =~ "$pattern" ]]'
- else
- echo "$result" | egrep -q "$pattern"
- fi
- fi
-}
-
-
-_is_diag(){
- local result=${1:?}
- local expected=${2:?}
-
- diag " got: '$result'"
- diag " expected: '$expected'"
-}
-
-
-is(){
- local result=${1:?}
- local expected=${2:?}
- local name=${3:-''}
-
- _equals "$result" "$expected"
- (( $? == 0 ))
- ok $? "$name"
- local r=$?
- (( r != 0 )) && _is_diag "$result" "$expected"
- return $r
-}
-
-
-isnt(){
- local result=${1:?}
- local expected=${2:?}
- local name=${3:-''}
-
- _equals "$result" "$expected"
- (( $? != 0 ))
- ok $? "$name"
- local r=$?
- (( r != 0 )) && _is_diag "$result" "$expected"
- return $r
-}
-
-
-like(){
- local result=${1:?}
- local pattern=${2:?}
- local name=${3:-''}
-
- _matches "$result" "$pattern"
- (( $? == 0 ))
- ok $? "$name"
- local r=$?
- (( r != 0 )) && diag " '$result' doesn't match '$pattern'"
- return $r
-}
-
-
-unlike(){
- local result=${1:?}
- local pattern=${2:?}
- local name=${3:-''}
-
- _matches "$result" "$pattern"
- (( $? != 0 ))
- ok $? "$name"
- local r=$?
- (( r != 0 )) && diag " '$result' matches '$pattern'"
- return $r
-}
-
-
-skip(){
- local condition=${1:?}
- local reason=${2:-''}
- local n=${3:-1}
-
- if (( condition == 0 )) ; then
- local i=
- for (( i=0 ; i<$n ; i++ )) ; do
- _executed_tests=$(( _executed_tests + 1 ))
- echo "ok $_executed_tests # skip: $reason"
- done
- return 0
- else
- return
- fi
-}
-
-
-diag(){
- local msg=${1:?}
-
- if [[ -n "$msg" ]] ; then
- echo "# $msg"
- fi
-
- return 1
-}
-
-
-_die(){
- local reason=${1:-'<unspecified error>'}
-
- echo "$reason" >&2
- _test_died=1
- _exit 255
-}
-
-
-BAIL_OUT(){
- local reason=${1:-''}
-
- echo "Bail out! $reason" >&2
- _exit 255
-}
-
-
-_cleanup(){
- local rc=0
-
- if (( _plan_set == 0 )) ; then
- diag "Looks like your test died before it could output anything."
- return $rc
- fi
-
- if (( _test_died != 0 )) ; then
- diag "Looks like your test died just after $_executed_tests."
- return $rc
- fi
-
- if (( _skip_all == 0 && _no_plan != 0 )) ; then
- _print_plan $_executed_tests
- fi
-
- local s=
- if (( _no_plan == 0 && _expected_tests < _executed_tests )) ; then
- s= ; (( _expected_tests > 1 )) && s=s
- local extra=$(( _executed_tests - _expected_tests ))
- diag "Looks like you planned $_expected_tests test$s but ran $extra extra."
- rc=-1 ;
- fi
-
- if (( _no_plan == 0 && _expected_tests > _executed_tests )) ; then
- s= ; (( _expected_tests > 1 )) && s=s
- diag "Looks like you planned $_expected_tests test$s but only ran $_executed_tests."
- fi
-
- if (( _failed_tests > 0 )) ; then
- s= ; (( _failed_tests > 1 )) && s=s
- diag "Looks like you failed $_failed_tests test$s of $_executed_tests."
- fi
-
- return $rc
-}
-
-
-_exit_status(){
- if (( _no_plan != 0 || _plan_set == 0 )) ; then
- return $_failed_tests
- fi
-
- if (( _expected_tests < _executed_tests )) ; then
- return $(( _executed_tests - _expected_tests ))
- fi
-
- return $(( _failed_tests + ( _expected_tests - _executed_tests )))
-}
-
-
-_exit(){
- local rc=${1:-''}
- if [[ -z "$rc" ]] ; then
- _exit_status
- rc=$?
- fi
-
- _cleanup
- local alt_rc=$?
- (( alt_rc != 0 )) && rc=$alt_rc
- trap - EXIT
- exit $rc
-}
-
diff --git a/argparse/test.sh b/argparse/test.sh
deleted file mode 100755
index fdb430a..0000000
--- a/argparse/test.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-. tap-functions
-plan_no_plan
-
-is "$(./test_argparse -f --path=/path/to/file a 2>&1)" 'force: 1
-path: /path/to/file
-argc: 1
-argv[0]: a'
-
-is "$(./test_argparse -f -f --force --no-force 2>&1)" 'force: 2'
-
-is "$(./test_argparse -n 2>&1)" 'error: option `n` requires a value'
-
-is "$(./test_argparse -n 2 2>&1)" 'num: 2'
-
-is "$(./test_argparse -n2 2>&1)" 'num: 2'
-
-is "$(./test_argparse -na 2>&1)" 'error: option `n` expects a numerical value'
-
-is "$(./test_argparse -f -- do -f -h 2>&1)" 'force: 1
-argc: 3
-argv[0]: do
-argv[1]: -f
-argv[2]: -h'
-
-is "$(./test_argparse -tf 2>&1)" 'force: 1
-test: 1'
-
-is "$(./test_argparse --read --write 2>&1)" 'perms: 3'
-
-is "$(./test_argparse -h)" 'Usage: test_argparse [options] [[--] args]
- or: test_argparse [options]
-
- -h, --help show this help message and exit
-
-OPTIONS
- -f, --force force to do
- -t, --test test only
- -p, --path=<str> path to read
- -n, --num=<int> selected num
-
-BITS
- --read read perm
- --write write perm
- --exec exec perm'
diff --git a/argparse/test_argparse.c b/argparse/test_argparse.c
deleted file mode 100755
index 6d95d35..0000000
--- a/argparse/test_argparse.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "argparse.h"
-
-static const char *const usage[] = {
- "test_argparse [options] [[--] args]",
- "test_argparse [options]",
- NULL,
-};
-
-#define PERM_READ (1<<0)
-#define PERM_WRITE (1<<1)
-#define PERM_EXEC (1<<2)
-
-int
-main(int argc, const char **argv)
-{
- int force = 0;
- int test = 0;
- int num = 0;
- const char *path = NULL;
- int perms = 0;
- struct argparse_option options[] = {
- OPT_HELP(),
- OPT_GROUP("OPTIONS"),
- OPT_BOOLEAN('f', "force", &force, "force to do"),
- OPT_BOOLEAN('t', "test", &test, "test only"),
- OPT_STRING('p', "path", &path, "path to read"),
- OPT_INTEGER('n', "num", &num, "selected num"),
- OPT_GROUP("BITS"),
- OPT_BIT(0, "read", &perms, "read perm", NULL, PERM_READ, OPT_NONEG),
- OPT_BIT(0, "write", &perms, "write perm", NULL, PERM_WRITE),
- OPT_BIT(0, "exec", &perms, "exec perm", NULL, PERM_EXEC),
- OPT_END(),
- };
-
- struct argparse argparse;
- argparse_init(&argparse, options, usage, 0);
- argc = argparse_parse(&argparse, argc, argv);
- if (force != 0)
- printf("force: %d\n", force);
- if (test != 0)
- printf("test: %d\n", test);
- if (path != NULL)
- printf("path: %s\n", path);
- if (num != 0)
- printf("num: %d\n", num);
- if (argc != 0) {
- printf("argc: %d\n", argc);
- int i;
- for (i = 0; i < argc; i++) {
- printf("argv[%d]: %s\n", i, *(argv + i));
- }
- }
- if (perms) {
- printf("perms: %d\n", perms);
- }
- return 0;
-}
diff --git a/args.c b/args.c
new file mode 100755
index 0000000..45f11ec
--- /dev/null
+++ b/args.c
@@ -0,0 +1,278 @@
+/*
+Copyright (c) 2014. The YARA Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "args.h"
+
+#define args_is_long_arg(arg) \
+ (arg[0] == '-' && arg[1] == '-' && arg[2] != '\0')
+
+
+#define args_is_short_arg(arg) \
+ (arg[0] == '-' && arg[1] != '-' && arg[1] != '\0')
+
+
+args_option_t* args_get_short_option(
+ args_option_t *options,
+ const char opt)
+{
+ while (options->type != ARGS_OPT_END)
+ {
+ if (opt == options->short_name)
+ return options;
+
+ options++;
+ }
+
+ return NULL;
+}
+
+
+args_option_t* args_get_long_option(
+ args_option_t *options,
+ const char* arg)
+{
+ arg += 2; // skip starting --
+
+ while (options->type != ARGS_OPT_END)
+ {
+ if (options->long_name != NULL)
+ {
+ int l = strlen(options->long_name);
+
+ if ((arg[l] == '\0' || arg[l] == '=') &&
+ strstr(arg, options->long_name) == arg)
+ {
+ return options;
+ }
+ }
+
+ options++;
+ }
+
+ return NULL;
+}
+
+
+args_error_type_t args_parse_option(
+ args_option_t* opt,
+ const char* opt_arg,
+ int* opt_arg_was_used)
+{
+ char *endptr = NULL;
+
+ if (opt_arg_was_used != NULL)
+ *opt_arg_was_used = 0;
+
+ if (opt->count == opt->max_count)
+ return ARGS_ERROR_TOO_MANY;
+
+ switch (opt->type)
+ {
+ case ARGS_OPT_BOOLEAN:
+ *(int*) opt->value = 1;
+ break;
+
+ case ARGS_OPT_INTEGER:
+
+ if (opt_arg == NULL)
+ return ARGS_ERROR_REQUIRED_INTEGER_ARG;
+
+ *(int*) opt->value = strtol(opt_arg, &endptr, 0);
+
+ if (*endptr != '\0')
+ return ARGS_ERROR_REQUIRED_INTEGER_ARG;
+
+ if (opt_arg_was_used != NULL)
+ *opt_arg_was_used = 1;
+
+ break;
+
+ case ARGS_OPT_STRING:
+
+ if (opt_arg == NULL)
+ return ARGS_ERROR_REQUIRED_STRING_ARG;
+
+ if (opt->max_count > 1)
+ ((const char**)opt->value)[opt->count] = opt_arg;
+ else
+ *(const char**) opt->value = opt_arg;
+
+ if (opt_arg_was_used != NULL)
+ *opt_arg_was_used = 1;
+
+ break;
+
+ default:
+ assert(0);
+ }
+
+ opt->count++;
+
+ return ARGS_ERROR_OK;
+}
+
+
+void args_print_error(
+ args_error_type_t error,
+ const char* option)
+{
+ switch(error)
+ {
+ case ARGS_ERROR_UKNOWN_OPT:
+ fprintf(stderr, "unknown option `%s`\n", option);
+ break;
+ case ARGS_ERROR_TOO_MANY:
+ fprintf(stderr, "too many `%s` options\n", option);
+ break;
+ case ARGS_ERROR_REQUIRED_INTEGER_ARG:
+ fprintf(stderr, "option `%s` requieres an integer argument\n", option);
+ break;
+ case ARGS_ERROR_REQUIRED_STRING_ARG:
+ fprintf(stderr, "option `%s` requieres a string argument\n", option);
+ break;
+ case ARGS_ERROR_UNEXPECTED_ARG:
+ fprintf(stderr, "option `%s` doesn't expect an argument\n", option);
+ break;
+ default:
+ return;
+ }
+}
+
+
+int args_parse(
+ args_option_t *options,
+ int argc,
+ const char **argv)
+{
+ args_error_type_t error = ARGS_ERROR_OK;
+
+ int i = 1; // start with i = 1, argv[0] is the program name
+ int o = 0;
+
+ while (i < argc)
+ {
+ const char* arg = argv[i];
+
+ if (args_is_long_arg(arg))
+ {
+ args_option_t* opt = args_get_long_option(options, arg);
+
+ if (opt != NULL)
+ {
+ const char* equal = strchr(arg, '=');
+
+ if (equal)
+ error = args_parse_option(opt, equal + 1, NULL);
+ else
+ error = args_parse_option(opt, NULL, NULL);
+ }
+ else
+ {
+ error = ARGS_ERROR_UKNOWN_OPT;
+ }
+ }
+ else if (args_is_short_arg(arg))
+ {
+ for (int j = 1; arg[j] != '\0'; j++)
+ {
+ args_option_t* opt = args_get_short_option(options, arg[j]);
+
+ if (opt != NULL)
+ {
+ if (arg[j + 1] == '\0')
+ {
+ int arg_used;
+
+ // short option followed by a space, argv[i + 1] could be
+ // an argument for the option (i.e: -a <arg>)
+ error = args_parse_option(opt, argv[i + 1], &arg_used);
+
+ // argv[i + 1] was actually an argument to the option, skip it.
+ if (arg_used)
+ i++;
+ }
+ else
+ {
+ // short option followed by another option (i.e: -ab), no
+ // argument for this option
+ error = args_parse_option(opt, NULL, NULL);
+ }
+ }
+ else
+ {
+ error = ARGS_ERROR_UKNOWN_OPT;
+ }
+
+ if (error != ARGS_ERROR_OK)
+ break;
+ }
+ }
+ else
+ {
+ argv[o++] = arg;
+ }
+
+ if (error != ARGS_ERROR_OK)
+ {
+ args_print_error(error, arg);
+ exit(1);
+ }
+
+ i++;
+ }
+
+ return o;
+}
+
+
+void args_print_usage(
+ args_option_t *options,
+ int help_alignment)
+{
+ char buffer[128];
+
+ for (; options->type != ARGS_OPT_END; options++)
+ {
+ int len = sprintf(buffer, " ");
+
+ if (options->short_name != '\0')
+ len += sprintf(buffer + len, "-%c", options->short_name);
+ else
+ len += sprintf(buffer + len, " ");
+
+ if (options->short_name != '\0' && options->long_name != NULL)
+ len += sprintf(buffer + len, ", ");
+
+ if (options->long_name != NULL)
+ len += sprintf(buffer + len, "--%s", options->long_name);
+
+ if (options->type == ARGS_OPT_STRING ||
+ options->type == ARGS_OPT_INTEGER)
+ {
+ len += sprintf(
+ buffer + len,
+ "%s%s",
+ (options->long_name != NULL) ? "=" : " ",
+ options->type_help);
+ }
+
+ printf("%-*s%s\n", help_alignment, buffer, options->help);
+ }
+}
diff --git a/args.h b/args.h
new file mode 100755
index 0000000..eec36a3
--- /dev/null
+++ b/args.h
@@ -0,0 +1,92 @@
+/*
+Copyright (c) 2014. The YARA Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef ARGPARSE_H
+#define ARGPARSE_H
+
+#include <stdio.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum _args_error_type {
+ ARGS_ERROR_OK,
+ ARGS_ERROR_UKNOWN_OPT,
+ ARGS_ERROR_TOO_MANY,
+ ARGS_ERROR_REQUIRED_INTEGER_ARG,
+ ARGS_ERROR_REQUIRED_STRING_ARG,
+ ARGS_ERROR_UNEXPECTED_ARG,
+} args_error_type_t;
+
+
+typedef enum _args_option_type {
+ // special
+ ARGS_OPT_END,
+ ARGS_OPT_GROUP,
+ // options with no arguments
+ ARGS_OPT_BOOLEAN,
+ // options with arguments (optional or required)
+ ARGS_OPT_INTEGER,
+ ARGS_OPT_STRING,
+} args_option_type_t;
+
+
+typedef struct _args_option {
+ args_option_type_t type;
+ const char short_name;
+ const char *long_name;
+ void *value;
+ int max_count;
+ const char *help;
+ const char *type_help;
+ int count;
+} args_option_t;
+
+
+#define OPT_BOOLEAN(short_name, long_name, value, ...) \
+ { ARGS_OPT_BOOLEAN, short_name, long_name, value, 1, __VA_ARGS__ }
+
+#define OPT_INTEGER(short_name, long_name, value, ...) \
+ { ARGS_OPT_INTEGER, short_name, long_name, value, 1, __VA_ARGS__ }
+
+#define OPT_STRING_MULTI(short_name, long_name, value, max_count, ...) \
+ { ARGS_OPT_STRING, short_name, long_name, value, max_count, __VA_ARGS__ }
+
+#define OPT_STRING(short_name, long_name, value, ...) \
+ OPT_STRING_MULTI(short_name, long_name, value, 1, __VA_ARGS__)
+
+#define OPT_END() { ARGS_OPT_END, 0 }
+
+
+int args_parse(
+ args_option_t *options,
+ int argc,
+ const char **argv);
+
+
+void args_print_usage(
+ args_option_t *options,
+ int aligment);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/yara.c b/yara.c
index f34a3cf..e28b538 100644
--- a/yara.c
+++ b/yara.c
@@ -35,9 +35,9 @@ limitations under the License.
#include <string.h>
#include <ctype.h>
-#include <argparse/argparse.h>
#include <yara.h>
+#include "args.h"
#include "threading.h"
#include "config.h"
@@ -93,6 +93,8 @@ int show_specified_rules = FALSE;
int show_strings = FALSE;
int show_meta = FALSE;
int show_namespace = FALSE;
+int show_version = FALSE;
+int show_help = FALSE;
int ignore_warnings = FALSE;
int fast_scan = FALSE;
int negate = FALSE;
@@ -102,22 +104,20 @@ int timeout = 0;
int threads = 8;
-static const char *const usage[] = {
- "yara [OPTION]... RULES_FILE FILE | DIRECTORY | PID",
- NULL,
-};
+#define USAGE_STRING \
+ "Usage: yara [OPTION]... RULES_FILE FILE | DIR | PID"
-struct argparse_option options[] =
+args_option_t options[] =
{
OPT_STRING_MULTI('t', "tag", &tags, MAX_ARGS_TAG,
- "only print rules tagged as <tag>.", "<tag>"),
+ "print only rules tagged as TAG", "TAG"),
OPT_STRING_MULTI('i', "identifier", &identifiers, MAX_ARGS_IDENTIFIER,
- "only print rules named <identifier>.", "<identifier>"),
+ "print only rules named IDENTIFIER", "IDENTIFIER"),
OPT_BOOLEAN('n', "negate", &negate,
- "only print not satisfied rules (negate)", NULL),
+ "print only not satisfied rules (negate)", NULL),
OPT_BOOLEAN('g', "print-tags", &show_tags,
"print tags"),
@@ -132,19 +132,19 @@ struct argparse_option options[] =
"print rules' namespace"),
OPT_INTEGER('p', "threads", &threads,
- "use the specified number of threads to scan a directory", "<number>"),
+ "use the specified NUMBER of threads to scan a directory", "NUMBER"),
OPT_INTEGER('l', "max-rules", &limit,
- "abort scanning after matching a number rules", "<number>"),
+ "abort scanning after matching a NUMBER of rules", "NUMBER"),
OPT_STRING_MULTI('d', NULL, &ext_vars, MAX_ARGS_EXT_VAR,
- "define external variable", "<identifier>=<value>"),
+ "define external variable", "VAR=VALUE"),
OPT_STRING_MULTI('x', NULL, &modules_data, MAX_ARGS_MODULE_DATA,
- "pass file's content as extra data to module", "<module>=<file>"),
+ "pass FILE's content as extra data to MODULE", "MODULE=FILE"),
OPT_INTEGER('a', "timeout", &timeout,
- "abort scanning after matching a number of rules", "<number>"),
+ "abort scanning after the given number of SECONDS", "SECONDS"),
OPT_BOOLEAN('r', "recursive", &recursive_search,
"recursively search directories"),
@@ -155,7 +155,12 @@ struct argparse_option options[] =
OPT_BOOLEAN('w', "no-warnings", &ignore_warnings,
"disable warnings"),
- OPT_HELP(),
+ OPT_BOOLEAN('v', "version", &show_version,
+ "show version information"),
+
+ OPT_BOOLEAN('h', "help", &show_help,
+ "show this help and exit"),
+
OPT_END()
};
@@ -800,12 +805,29 @@ int main(
YR_COMPILER* compiler = NULL;
YR_RULES* rules = NULL;
- struct argparse argparse;
int result;
- argparse_init(&argparse, options, usage, 0);
+ argc = args_parse(options, argc, argv);
- argc = argparse_parse(&argparse, argc, argv);
+ if (show_version)
+ {
+ printf("%s\n", PACKAGE_STRING);
+ return EXIT_FAILURE;
+ }
+
+ if (show_help)
+ {
+ printf(
+ "YARA %s, the pattern matching swiss army knife.\n"
+ "%s\n\n"
+ "Mandatory arguments to long options are mandatory for "
+ "short options too.\n\n", PACKAGE_VERSION, USAGE_STRING);
+
+ args_print_usage(options, 35);
+ printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);
+
+ return EXIT_FAILURE;
+ }
if (argc != 2)
{
@@ -813,8 +835,10 @@ int main(
// arguments, the rules file and the target file, directory or pid to
// be scanned.
- fprintf(stderr, "error: wrong number of arguments\n");
- argparse_usage(&argparse);
+ fprintf(stderr, "yara: wrong number of arguments\n");
+ fprintf(stderr, "%s\n\n", USAGE_STRING);
+ fprintf(stderr, "Try `--help` for more options\n");
+
return EXIT_FAILURE;
}
diff --git a/yarac.c b/yarac.c
index 4402c48..e0eb000 100644
--- a/yarac.c
+++ b/yarac.c
@@ -31,9 +31,9 @@ limitations under the License.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <argparse/argparse.h>
#include <yara.h>
+#include "args.h"
#include "config.h"
#ifndef MAX_PATH
@@ -45,23 +45,27 @@ limitations under the License.
char* ext_vars[MAX_ARGS_EXT_VAR + 1];
int ignore_warnings = FALSE;
+int show_version = FALSE;
+int show_help = FALSE;
-static const char *const usage[] = {
- "yarac [option]... [namespace:]rules_file... output_file",
- NULL,
-};
-
+#define USAGE_STRING \
+ "Usage: yarac [OPTION]... [NAMESPACE:]SOURCE_FILE... OUTPUT_FILE"
-struct argparse_option options[] =
+args_option_t options[] =
{
OPT_STRING_MULTI('d', NULL, &ext_vars, MAX_ARGS_EXT_VAR,
- "define external variable"),
+ "define external variable", "VAR=VALUE"),
OPT_BOOLEAN('w', "no-warnings", &ignore_warnings,
- "disable warnings", NULL),
+ "disable warnings"),
+
+ OPT_BOOLEAN('v', "version", &show_version,
+ "show version information"),
+
+ OPT_BOOLEAN('h', "help", &show_help,
+ "show this help and exit"),
- OPT_HELP(),
OPT_END()
};
@@ -156,16 +160,34 @@ int main(
YR_COMPILER* compiler = NULL;
YR_RULES* rules = NULL;
- struct argparse argparse;
int result;
- argparse_init(&argparse, options, usage, 0);
+ argc = args_parse(options, argc, argv);
- argc = argparse_parse(&argparse, argc, argv);
+ if (show_version)
+ {
+ printf("%s\n", PACKAGE_STRING);
+ printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);
+
+ return EXIT_FAILURE;
+ }
+
+ if (show_help)
+ {
+ printf("%s\n\n", USAGE_STRING);
+
+ args_print_usage(options, 25);
+ printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);
+
+ return EXIT_FAILURE;
+ }
if (argc < 2)
{
- fprintf(stderr, "error: wrong number of arguments\n");
+ fprintf(stderr, "yarac: wrong number of arguments\n");
+ fprintf(stderr, "%s\n\n", USAGE_STRING);
+ fprintf(stderr, "Try `--help` for more options\n");
+
exit_with_code(EXIT_FAILURE);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list