mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-03 10:14:44 +08:00
remove unnecessary header files
This commit is contained in:
@@ -1,96 +0,0 @@
|
||||
/* Name frobnication for compiling argp outside of glibc
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !_LIBC
|
||||
/* This code is written for inclusion in gnu-libc, and uses names in the
|
||||
namespace reserved for libc. If we're not compiling in libc, define those
|
||||
names to be the normal ones instead. */
|
||||
|
||||
/* argp-parse functions */
|
||||
#undef __argp_parse
|
||||
#define __argp_parse argp_parse
|
||||
#undef __option_is_end
|
||||
#define __option_is_end _option_is_end
|
||||
#undef __option_is_short
|
||||
#define __option_is_short _option_is_short
|
||||
#undef __argp_input
|
||||
#define __argp_input _argp_input
|
||||
|
||||
/* argp-help functions */
|
||||
#undef __argp_help
|
||||
#define __argp_help argp_help
|
||||
#undef __argp_error
|
||||
#define __argp_error argp_error
|
||||
#undef __argp_failure
|
||||
#define __argp_failure argp_failure
|
||||
#undef __argp_state_help
|
||||
#define __argp_state_help argp_state_help
|
||||
#undef __argp_usage
|
||||
#define __argp_usage argp_usage
|
||||
#undef __argp_basename
|
||||
#define __argp_basename _argp_basename
|
||||
#undef __argp_short_program_name
|
||||
#define __argp_short_program_name _argp_short_program_name
|
||||
|
||||
/* argp-fmtstream functions */
|
||||
#undef __argp_make_fmtstream
|
||||
#define __argp_make_fmtstream argp_make_fmtstream
|
||||
#undef __argp_fmtstream_free
|
||||
#define __argp_fmtstream_free argp_fmtstream_free
|
||||
#undef __argp_fmtstream_putc
|
||||
#define __argp_fmtstream_putc argp_fmtstream_putc
|
||||
#undef __argp_fmtstream_puts
|
||||
#define __argp_fmtstream_puts argp_fmtstream_puts
|
||||
#undef __argp_fmtstream_write
|
||||
#define __argp_fmtstream_write argp_fmtstream_write
|
||||
#undef __argp_fmtstream_printf
|
||||
#define __argp_fmtstream_printf argp_fmtstream_printf
|
||||
#undef __argp_fmtstream_set_lmargin
|
||||
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
|
||||
#undef __argp_fmtstream_set_rmargin
|
||||
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
|
||||
#undef __argp_fmtstream_set_wmargin
|
||||
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
|
||||
#undef __argp_fmtstream_point
|
||||
#define __argp_fmtstream_point argp_fmtstream_point
|
||||
#undef __argp_fmtstream_update
|
||||
#define __argp_fmtstream_update _argp_fmtstream_update
|
||||
#undef __argp_fmtstream_ensure
|
||||
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
|
||||
#undef __argp_fmtstream_lmargin
|
||||
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
|
||||
#undef __argp_fmtstream_rmargin
|
||||
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
|
||||
#undef __argp_fmtstream_wmargin
|
||||
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
||||
|
||||
/* normal libc functions we call */
|
||||
#undef __sleep
|
||||
#define __sleep sleep
|
||||
#undef __strcasecmp
|
||||
#define __strcasecmp strcasecmp
|
||||
#undef __vsnprintf
|
||||
#define __vsnprintf vsnprintf
|
||||
|
||||
#endif /* !_LIBC */
|
||||
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(e) (errno = (e))
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,403 +0,0 @@
|
||||
#ifndef ARGPARSE_C_H_
|
||||
#define ARGPARSE_C_H_
|
||||
|
||||
/**
|
||||
* Copyright (C) 2012-2015 Yecheng Fu <cofyc.jackson at gmail dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a MIT-style license that can be found
|
||||
* in the LICENSE file.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include "argparse.h"
|
||||
|
||||
#define OPT_UNSET 1
|
||||
#define OPT_LONG (1 << 1)
|
||||
|
||||
/* We define these the same for all machines.
|
||||
Changes from this to the outside world should be done in `_exit'. */
|
||||
#define EXIT_FAILURE 1 /* Failing exit status. */
|
||||
#define EXIT_SUCCESS 0 /* Successful exit status. */
|
||||
|
||||
static const char *
|
||||
prefix_skip(const char *str, const char *prefix)
|
||||
{
|
||||
size_t len = strlen(prefix);
|
||||
return strncmp(str, prefix, len) ? NULL : str + len;
|
||||
}
|
||||
|
||||
static 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, const struct argparse_option *opt,
|
||||
const char *reason, int flags)
|
||||
{
|
||||
(void)self;
|
||||
if (flags & OPT_LONG) {
|
||||
printf("error: option `--%s` %s\n", opt->long_name, reason);
|
||||
} else {
|
||||
printf("error: option `-%c` %s\n", opt->short_name, reason);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int
|
||||
argparse_getvalue(struct argparse *self, const struct argparse_option *opt,
|
||||
int flags)
|
||||
{
|
||||
const char *s = NULL;
|
||||
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--;
|
||||
*(const char **)opt->value = *++self->argv;
|
||||
} else {
|
||||
argparse_error(self, opt, "requires a value", flags);
|
||||
}
|
||||
break;
|
||||
case ARGPARSE_OPT_INTEGER:
|
||||
// errno = 0;
|
||||
if (self->optvalue) {
|
||||
*(int *)opt->value = strtol(self->optvalue, (char **)&s, 0);
|
||||
self->optvalue = NULL;
|
||||
} else if (self->argc > 1) {
|
||||
self->argc--;
|
||||
*(int *)opt->value = strtol(*++self->argv, (char **)&s, 0);
|
||||
} else {
|
||||
argparse_error(self, opt, "requires a value", flags);
|
||||
}
|
||||
// if (errno == ERANGE)
|
||||
// argparse_error(self, opt, "numerical result out of range", flags);
|
||||
if (s[0] != '\0') // no digits or contains invalid characters
|
||||
argparse_error(self, opt, "expects an integer value", flags);
|
||||
break;
|
||||
case ARGPARSE_OPT_FLOAT:
|
||||
// errno = 0;
|
||||
if (self->optvalue) {
|
||||
*(float *)opt->value = strtod(self->optvalue, (char **)&s);
|
||||
self->optvalue = NULL;
|
||||
} else if (self->argc > 1) {
|
||||
self->argc--;
|
||||
*(float *)opt->value = strtod(*++self->argv, (char **)&s);
|
||||
} else {
|
||||
argparse_error(self, opt, "requires a value", flags);
|
||||
}
|
||||
// if (errno == ERANGE)
|
||||
// argparse_error(self, opt, "numerical result out of range", flags);
|
||||
if (s[0] != '\0') // no digits or contains invalid characters
|
||||
argparse_error(self, opt, "expects a numerical value", flags);
|
||||
break;
|
||||
default:
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
skipped:
|
||||
if (opt->callback) {
|
||||
return opt->callback(self, opt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
argparse_options_check(const 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_FLOAT:
|
||||
case ARGPARSE_OPT_STRING:
|
||||
case ARGPARSE_OPT_GROUP:
|
||||
continue;
|
||||
default:
|
||||
printf("wrong option type: %d", options->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
argparse_short_opt(struct argparse *self, const 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, const 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 disabled?
|
||||
if (options->flags & OPT_NONEG) {
|
||||
continue;
|
||||
}
|
||||
// only OPT_BOOLEAN/OPT_BIT supports negation
|
||||
if (options->type != ARGPARSE_OPT_BOOLEAN && options->type !=
|
||||
ARGPARSE_OPT_BIT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefix_cmp(self->argv[0] + 2, "no-")) {
|
||||
continue;
|
||||
}
|
||||
rest = prefix_skip(self->argv[0] + 2 + 3, options->long_name);
|
||||
if (!rest)
|
||||
continue;
|
||||
opt_flags |= OPT_UNSET;
|
||||
}
|
||||
if (*rest) {
|
||||
if (*rest != '=')
|
||||
continue;
|
||||
self->optvalue = rest + 1;
|
||||
}
|
||||
return argparse_getvalue(self, options, opt_flags | OPT_LONG);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
int
|
||||
argparse_init(struct argparse *self, struct argparse_option *options,
|
||||
const char *const *usages, int flags)
|
||||
{
|
||||
memset(self, 0, sizeof(*self));
|
||||
self->options = options;
|
||||
self->usages = usages;
|
||||
self->flags = flags;
|
||||
self->description = NULL;
|
||||
self->epilog = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
argparse_describe(struct argparse *self, const char *description,
|
||||
const char *epilog)
|
||||
{
|
||||
self->description = description;
|
||||
self->epilog = epilog;
|
||||
}
|
||||
|
||||
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 verbatim
|
||||
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:
|
||||
printf("error: unknown option `%s`\n", self->argv[0]);
|
||||
argparse_usage(self);
|
||||
if (!(self->flags & ARGPARSE_IGNORE_UNKNOWN_ARGS)) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (self->usages) {
|
||||
printf("Usage: %s\n", *self->usages++);
|
||||
while (*self->usages && **self->usages)
|
||||
printf(" or: %s\n", *self->usages++);
|
||||
} else {
|
||||
printf("Usage:\n");
|
||||
}
|
||||
|
||||
// print description
|
||||
if (self->description)
|
||||
printf("%s\n", self->description);
|
||||
|
||||
putchar('\n');
|
||||
|
||||
const 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 += strlen("=<int>");
|
||||
}
|
||||
if (options->type == ARGPARSE_OPT_FLOAT) {
|
||||
len += strlen("=<flt>");
|
||||
} else if (options->type == ARGPARSE_OPT_STRING) {
|
||||
len += strlen("=<str>");
|
||||
}
|
||||
len = (len + 3) - ((len + 3) & 3);
|
||||
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) {
|
||||
putchar('\n');
|
||||
printf("%s", options->help);
|
||||
putchar('\n');
|
||||
continue;
|
||||
}
|
||||
pos = printf(" ");
|
||||
if (options->short_name) {
|
||||
pos += printf("-%c", options->short_name);
|
||||
}
|
||||
if (options->long_name && options->short_name) {
|
||||
pos += printf(", ");
|
||||
}
|
||||
if (options->long_name) {
|
||||
pos += printf("--%s", options->long_name);
|
||||
}
|
||||
if (options->type == ARGPARSE_OPT_INTEGER) {
|
||||
pos += printf("=<int>");
|
||||
} else if (options->type == ARGPARSE_OPT_FLOAT) {
|
||||
pos += printf("=<flt>");
|
||||
} else if (options->type == ARGPARSE_OPT_STRING) {
|
||||
pos += printf("=<str>");
|
||||
}
|
||||
if (pos <= usage_opts_width) {
|
||||
pad = usage_opts_width - pos;
|
||||
} else {
|
||||
putchar('\n');
|
||||
pad = usage_opts_width;
|
||||
}
|
||||
printf(" %s\n", options->help);
|
||||
}
|
||||
|
||||
// print epilog
|
||||
if (self->epilog)
|
||||
printf("%s\n", self->epilog);
|
||||
}
|
||||
|
||||
int
|
||||
argparse_help_cb_no_exit(struct argparse *self,
|
||||
const struct argparse_option *option)
|
||||
{
|
||||
(void)option;
|
||||
argparse_usage(self);
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
argparse_help_cb(struct argparse *self, const struct argparse_option *option)
|
||||
{
|
||||
argparse_help_cb_no_exit(self, option);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#endif /* ARGPARSE_C_H */
|
||||
@@ -1,133 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2012-2015 Yecheng Fu <cofyc.jackson at gmail dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a MIT-style license that can be found
|
||||
* in the LICENSE file.
|
||||
*/
|
||||
#ifndef ARGPARSE_H
|
||||
#define ARGPARSE_H
|
||||
|
||||
/* For c++ compatibility */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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 << 0,
|
||||
ARGPARSE_IGNORE_UNKNOWN_ARGS = 1 << 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_FLOAT,
|
||||
ARGPARSE_OPT_STRING,
|
||||
};
|
||||
|
||||
enum argparse_option_flags {
|
||||
OPT_NONEG = 1, /* disable negation */
|
||||
};
|
||||
|
||||
/**
|
||||
* argparse option
|
||||
*
|
||||
* `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.
|
||||
*
|
||||
* `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;
|
||||
const char *help;
|
||||
argparse_callback *callback;
|
||||
intptr_t data;
|
||||
int flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* argpparse
|
||||
*/
|
||||
struct argparse {
|
||||
// user supplied
|
||||
const struct argparse_option *options;
|
||||
const char *const *usages;
|
||||
int flags;
|
||||
const char *description; // a description after usage
|
||||
const char *epilog; // a description at the end
|
||||
// internal context
|
||||
int argc;
|
||||
const char **argv;
|
||||
const char **out;
|
||||
int cpidx;
|
||||
const char *optvalue; // current option value
|
||||
};
|
||||
|
||||
// built-in callbacks
|
||||
int argparse_help_cb(struct argparse *self,
|
||||
const struct argparse_option *option);
|
||||
int argparse_help_cb_no_exit(struct argparse *self,
|
||||
const struct argparse_option *option);
|
||||
|
||||
// built-in option macros
|
||||
#define OPT_END() { ARGPARSE_OPT_END, 0, NULL, NULL, 0, NULL, 0, 0 }
|
||||
#define OPT_BOOLEAN(...) { ARGPARSE_OPT_BOOLEAN, __VA_ARGS__ }
|
||||
#define OPT_BIT(...) { ARGPARSE_OPT_BIT, __VA_ARGS__ }
|
||||
#define OPT_INTEGER(...) { ARGPARSE_OPT_INTEGER, __VA_ARGS__ }
|
||||
#define OPT_FLOAT(...) { ARGPARSE_OPT_FLOAT, __VA_ARGS__ }
|
||||
#define OPT_STRING(...) { ARGPARSE_OPT_STRING, __VA_ARGS__ }
|
||||
#define OPT_GROUP(h) { ARGPARSE_OPT_GROUP, 0, NULL, NULL, h, NULL, 0, 0 }
|
||||
#define OPT_HELP() OPT_BOOLEAN('h', "help", NULL, \
|
||||
"show this help message and exit", \
|
||||
argparse_help_cb, 0, OPT_NONEG)
|
||||
|
||||
int argparse_init(struct argparse *self, struct argparse_option *options,
|
||||
const char *const *usages, int flags);
|
||||
void argparse_describe(struct argparse *self, const char *description,
|
||||
const char *epilog);
|
||||
int argparse_parse(struct argparse *self, int argc, const char **argv);
|
||||
void argparse_usage(struct argparse *self);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,358 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
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.
|
||||
|
||||
A header only cJSON library for C and C++.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) \
|
||||
&& (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) \
|
||||
|| defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/**
|
||||
* When compiling for windows, we specify a specific calling convention to avoid
|
||||
* issues where we are being called from a project with a different default
|
||||
* calling convention. For windows you have 3 define options:
|
||||
* CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever
|
||||
* dllexport symbols
|
||||
* CJSON_EXPORT_SYMBOLS - Define this on library build when you want to
|
||||
* dllexport symbols (default)
|
||||
* CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
*
|
||||
* For *nix builds that support visibility attribute, you can define similar
|
||||
* behavior by setting default visibility to hidden by adding
|
||||
* -fvisibility=hidden (for gcc)
|
||||
* or
|
||||
* -xldscope=hidden (for sun cc)
|
||||
* to CFLAGS, then using the CJSON_API_VISIBILITY flag to "export" the same
|
||||
* symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and
|
||||
header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) \
|
||||
&& !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) \
|
||||
&& defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 10
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use
|
||||
GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of
|
||||
the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list
|
||||
of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling
|
||||
* convention of the compiler, so ensure the hooks allow passing those
|
||||
* functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void(CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse
|
||||
them. This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char *) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from
|
||||
* all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib
|
||||
* free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is
|
||||
* cJSON_PrintPreallocated, where the caller has full responsibility of the
|
||||
* buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
|
||||
*/
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null
|
||||
* terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then
|
||||
* return_parse_end will contain a pointer to the error so will match
|
||||
* cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
|
||||
cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess
|
||||
* at the final size. guessing well reduces reallocation. fmt=0 gives
|
||||
* unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *)
|
||||
cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with
|
||||
* given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will
|
||||
* use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
|
||||
const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if
|
||||
* unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_GetObjectItem(const cJSON *const object, const char *const string);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_GetObjectItemCaseSensitive(const cJSON *const object,
|
||||
const char *const string);
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error.
|
||||
* You'll probably need to look a few chars back to make sense of it. Defined
|
||||
* when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON *const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and
|
||||
* will definitely survive the cJSON object. WARNING: When this function was
|
||||
* used, make sure to always check that (item->type & cJSON_StringIsConst) is
|
||||
* zero before writing to `item->string` */
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you
|
||||
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
|
||||
* existing cJSON. */
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void)
|
||||
cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void)
|
||||
cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_InsertItemInArray(
|
||||
cJSON *array, int which,
|
||||
cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
||||
cJSON *replacement);
|
||||
CJSON_PUBLIC(void)
|
||||
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void)
|
||||
cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
|
||||
CJSON_PUBLIC(void)
|
||||
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
|
||||
cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new
|
||||
memory that will need to be released. With recurse!=0, it will duplicate any
|
||||
children connected to the item. The item->next and ->prev pointers are always
|
||||
zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or
|
||||
* invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or
|
||||
* case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool)
|
||||
cJSON_Compare(const cJSON *const a, const cJSON *const b,
|
||||
const cJSON_bool case_sensitive);
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddNullToObject(cJSON *const object, const char *const name);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddTrueToObject(cJSON *const object, const char *const name);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddFalseToObject(cJSON *const object, const char *const name);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddBoolToObject(cJSON *const object, const char *const name,
|
||||
const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddNumberToObject(cJSON *const object, const char *const name,
|
||||
const double number);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddStringToObject(cJSON *const object, const char *const name,
|
||||
const char *const string);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddRawToObject(cJSON *const object, const char *const name,
|
||||
const char *const raw);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddObjectToObject(cJSON *const object, const char *const name);
|
||||
CJSON_PUBLIC(cJSON *)
|
||||
cJSON_AddArrayToObject(cJSON *const object, const char *const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble
|
||||
too. */
|
||||
#define cJSON_SetIntValue(object, number) \
|
||||
((object) ? (object)->valueint = (object)->valuedouble = (number) \
|
||||
: (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) \
|
||||
((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) \
|
||||
: (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) \
|
||||
for (element = (array != NULL) ? (array)->child : NULL; element != NULL; \
|
||||
element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with
|
||||
cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef ENTRY_H_
|
||||
#define ENTRY_H_
|
||||
|
||||
// header only helpers for develop wasm app
|
||||
#include "cJSON/cJSON.c"
|
||||
#include "helpers.h"
|
||||
|
||||
#define MAX_ARGS 32
|
||||
|
||||
int main(int argc, char **argv);
|
||||
int bpf_main(char *env_json, int str_len)
|
||||
{
|
||||
cJSON *env = cJSON_Parse(env_json);
|
||||
if (!env)
|
||||
{
|
||||
printf("cJSON_Parse failed for env json args.");
|
||||
return 1;
|
||||
}
|
||||
if (!cJSON_IsArray(env)) {
|
||||
printf("env json args is not an array.");
|
||||
return 1;
|
||||
}
|
||||
int argc = cJSON_GetArraySize(env);
|
||||
if (argc > MAX_ARGS) {
|
||||
printf("env json args is too long.");
|
||||
return 1;
|
||||
}
|
||||
char *argv[MAX_ARGS];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
cJSON *item = cJSON_GetArrayItem(env, i);
|
||||
if (!cJSON_IsString(item)) {
|
||||
printf("env json args is not a string.");
|
||||
return 1;
|
||||
}
|
||||
argv[i] = item->valuestring;
|
||||
}
|
||||
return main(argc, argv);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _ASM_GENERIC_ERRNO_BASE_H
|
||||
#define _ASM_GENERIC_ERRNO_BASE_H
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Argument list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No child processes */
|
||||
#define EAGAIN 11 /* Try again */
|
||||
#define ENOMEM 12 /* Out of memory */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Device or resource busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* File table overflow */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read-only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math argument out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef EWASM_APP_HELPERS_H_
|
||||
#define EWASM_APP_HELPERS_H_
|
||||
|
||||
#include "native-ewasm.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "cJSON/cJSON.h"
|
||||
|
||||
/// @brief start the eBPF program with JSON and wait for it to exit
|
||||
/// @param program_data the json data of eBPF program
|
||||
/// @return 0 on success, -1 on failure, the eBPF program will be terminated in failure case
|
||||
int
|
||||
start_bpf_program(char *program_data)
|
||||
{
|
||||
int res = create_bpf(program_data, strlen(program_data));
|
||||
if (res < 0) {
|
||||
printf("create_bpf failed %d", res);
|
||||
return -1;
|
||||
}
|
||||
res = run_bpf(res);
|
||||
if (res < 0) {
|
||||
printf("run_bpf failed %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
res = wait_and_poll_bpf(res);
|
||||
if (res < 0) {
|
||||
printf("wait_and_poll_bpf failed %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief set the global variable of bpf program to the value
|
||||
/// @param program the json program data
|
||||
/// @param key global
|
||||
/// @param value arg value
|
||||
/// @return new eBPF program
|
||||
cJSON *
|
||||
set_bpf_program_global_var(cJSON *program, char *key, cJSON *value)
|
||||
{
|
||||
|
||||
cJSON *args = cJSON_GetObjectItem(program, "runtime_args");
|
||||
if (args == NULL)
|
||||
{
|
||||
args = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(program, "runtime_args", args);
|
||||
}
|
||||
cJSON_AddItemToObject(args, key, value);
|
||||
return program;
|
||||
}
|
||||
|
||||
#endif // EWASM_APP_INIT_H
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef EWASM_NATIVE_API_H_
|
||||
#define EWASM_NATIVE_API_H_
|
||||
|
||||
/// c function interface to called from wasm
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/// @brief create a ebpf program with json data
|
||||
/// @param ebpf_json
|
||||
/// @return id on success, -1 on failure
|
||||
int
|
||||
create_bpf(char *ebpf_json, int str_len);
|
||||
|
||||
/// @brief start running the ebpf program
|
||||
/// @details load and attach the ebpf program to the kernel to run the ebpf
|
||||
/// program if the ebpf program has maps to export to user space, you need to
|
||||
/// call the wait and export.
|
||||
int
|
||||
run_bpf(int id);
|
||||
|
||||
/// @brief wait for the program to exit and receive data from export maps and
|
||||
/// print the data
|
||||
/// @details if the program has a ring buffer or perf event to export data
|
||||
/// to user space, the program will help load the map info and poll the
|
||||
/// events automatically.
|
||||
int
|
||||
wait_and_poll_bpf(int id);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// @brief init the eBPF program
|
||||
/// @param env_json the env config from input
|
||||
/// @return 0 on success, -1 on failure, the eBPF program will be terminated in
|
||||
/// failure case
|
||||
int
|
||||
bpf_main(char *env_json, int str_len);
|
||||
|
||||
/// @brief handle the event output from the eBPF program, valid only when
|
||||
/// wait_and_poll_events is called
|
||||
/// @param ctx user defined context
|
||||
/// @param e json event message
|
||||
/// @return 0 on success, -1 on failure,
|
||||
/// the event will be send to next handler in chain on success, or dropped in
|
||||
/// failure
|
||||
int
|
||||
process_event(int ctx, char *e, int str_len);
|
||||
|
||||
#endif // NATIVE_EWASM_H_
|
||||
@@ -1,195 +0,0 @@
|
||||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||
|
||||
/* THIS FILE IS AUTOGENERATED BY BPFTOOL! */
|
||||
#ifndef __SIGSNOOP_BPF_SKEL_H__
|
||||
#define __SIGSNOOP_BPF_SKEL_H__
|
||||
|
||||
extern int errno;
|
||||
#include <stdlib.h>
|
||||
|
||||
struct bpf_object_skeleton;
|
||||
struct bpf_object;
|
||||
struct bpf_map;
|
||||
struct bpf_program;
|
||||
struct bpf_object_open_opts;
|
||||
struct bpf_link;
|
||||
|
||||
struct sigsnoop_bpf {
|
||||
struct bpf_object_skeleton *skeleton;
|
||||
struct bpf_object *obj;
|
||||
struct {
|
||||
struct bpf_map *events;
|
||||
struct bpf_map *values;
|
||||
struct bpf_map *rodata;
|
||||
} maps;
|
||||
struct {
|
||||
struct bpf_program *kill_entry;
|
||||
struct bpf_program *kill_exit;
|
||||
struct bpf_program *tkill_entry;
|
||||
struct bpf_program *tkill_exit;
|
||||
struct bpf_program *tgkill_entry;
|
||||
struct bpf_program *tgkill_exit;
|
||||
struct bpf_program *sig_trace;
|
||||
} progs;
|
||||
struct {
|
||||
struct bpf_link *kill_entry;
|
||||
struct bpf_link *kill_exit;
|
||||
struct bpf_link *tkill_entry;
|
||||
struct bpf_link *tkill_exit;
|
||||
struct bpf_link *tgkill_entry;
|
||||
struct bpf_link *tgkill_exit;
|
||||
struct bpf_link *sig_trace;
|
||||
} links;
|
||||
struct sigsnoop_bpf__rodata {
|
||||
int filtered_pid;
|
||||
int target_signal;
|
||||
bool failed_only;
|
||||
} *rodata;
|
||||
|
||||
#ifdef __cplusplus
|
||||
static inline struct sigsnoop_bpf *open(const struct bpf_object_open_opts *opts = nullptr);
|
||||
static inline struct sigsnoop_bpf *open_and_load();
|
||||
static inline int load(struct sigsnoop_bpf *skel);
|
||||
static inline int attach(struct sigsnoop_bpf *skel);
|
||||
static inline void detach(struct sigsnoop_bpf *skel);
|
||||
static inline void destroy(struct sigsnoop_bpf *skel);
|
||||
static inline const void *elf_bytes(size_t *sz);
|
||||
#endif /* __cplusplus */
|
||||
};
|
||||
|
||||
static void
|
||||
sigsnoop_bpf__destroy(struct sigsnoop_bpf *obj)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline int
|
||||
sigsnoop_bpf__create_skeleton(struct sigsnoop_bpf *obj);
|
||||
|
||||
static inline struct sigsnoop_bpf *
|
||||
sigsnoop_bpf__open_opts(const struct bpf_object_open_opts *opts)
|
||||
{
|
||||
struct sigsnoop_bpf *obj;
|
||||
int err;
|
||||
|
||||
obj = (struct sigsnoop_bpf *)calloc(1, sizeof(*obj));
|
||||
if (!obj) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static inline struct sigsnoop_bpf *
|
||||
sigsnoop_bpf__open(void)
|
||||
{
|
||||
return sigsnoop_bpf__open_opts(NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
sigsnoop_bpf__load(struct sigsnoop_bpf *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct sigsnoop_bpf *
|
||||
sigsnoop_bpf__open_and_load(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int
|
||||
sigsnoop_bpf__attach(struct sigsnoop_bpf *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
sigsnoop_bpf__detach(struct sigsnoop_bpf *obj)
|
||||
{
|
||||
}
|
||||
|
||||
static inline const void *sigsnoop_bpf__elf_bytes(size_t *sz);
|
||||
|
||||
static inline int
|
||||
sigsnoop_bpf__create_skeleton(struct sigsnoop_bpf *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct sigsnoop_bpf *sigsnoop_bpf::open(const struct bpf_object_open_opts *opts) { return sigsnoop_bpf__open_opts(opts); }
|
||||
struct sigsnoop_bpf *sigsnoop_bpf::open_and_load() { return sigsnoop_bpf__open_and_load(); }
|
||||
int sigsnoop_bpf::load(struct sigsnoop_bpf *skel) { return sigsnoop_bpf__load(skel); }
|
||||
int sigsnoop_bpf::attach(struct sigsnoop_bpf *skel) { return sigsnoop_bpf__attach(skel); }
|
||||
void sigsnoop_bpf::detach(struct sigsnoop_bpf *skel) { sigsnoop_bpf__detach(skel); }
|
||||
void sigsnoop_bpf::destroy(struct sigsnoop_bpf *skel) { sigsnoop_bpf__destroy(skel); }
|
||||
const void *sigsnoop_bpf::elf_bytes(size_t *sz) { return sigsnoop_bpf__elf_bytes(sz); }
|
||||
#endif /* __cplusplus */
|
||||
|
||||
__attribute__((unused)) static void
|
||||
sigsnoop_bpf__assert(struct sigsnoop_bpf *s __attribute__((unused)))
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
#define _Static_assert static_assert
|
||||
#endif
|
||||
_Static_assert(sizeof(s->rodata->filtered_pid) == 4, "unexpected size of 'filtered_pid'");
|
||||
_Static_assert(sizeof(s->rodata->target_signal) == 4, "unexpected size of 'target_signal'");
|
||||
_Static_assert(sizeof(s->rodata->failed_only) == 1, "unexpected size of 'failed_only'");
|
||||
#ifdef __cplusplus
|
||||
#undef _Static_assert
|
||||
#endif
|
||||
}
|
||||
|
||||
struct perf_buffer;
|
||||
void perf_buffer__free(struct perf_buffer *pb) {
|
||||
}
|
||||
int perf_buffer__poll(struct perf_buffer *pb, int timeout_ms) {
|
||||
return start_bpf_program(program_data);
|
||||
}
|
||||
int bpf_program__set_autoload(struct bpf_program *prog, bool autoload) {
|
||||
return 0;
|
||||
}
|
||||
char* strerror(int errnum) {
|
||||
return "error";
|
||||
}
|
||||
int bpf_map__fd(const struct bpf_map *map) {
|
||||
return 0;
|
||||
}
|
||||
typedef void (*perf_buffer_sample_fn)(void *ctx, int cpu,
|
||||
void *data, unsigned int size);
|
||||
typedef void (*perf_buffer_lost_fn)(void *ctx, int cpu, unsigned long long cnt);
|
||||
struct perf_buffer;
|
||||
|
||||
perf_buffer_sample_fn global_cb;
|
||||
struct perf_buffer_opts;
|
||||
|
||||
struct perf_buffer *
|
||||
perf_buffer__new(int map_fd, size_t page_cnt,
|
||||
perf_buffer_sample_fn sample_cb, perf_buffer_lost_fn lost_cb, void *ctx,
|
||||
const struct perf_buffer_opts *opts) {
|
||||
global_cb = sample_cb;
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
int process_event(int ctx, char *e, int str_len)
|
||||
{
|
||||
struct event eve = {0};
|
||||
cJSON *json = cJSON_Parse(e);
|
||||
eve.sig = cJSON_GetObjectItem(json, "sig")->valueint;
|
||||
eve.pid = cJSON_GetObjectItem(json, "pid")->valueint;
|
||||
strcpy(eve.comm, cJSON_GetObjectItem(json, "comm")->valuestring);
|
||||
eve.tpid = cJSON_GetObjectItem(json, "tpid")->valueint;
|
||||
eve.ret = cJSON_GetObjectItem(json, "ret")->valueint;
|
||||
global_cb((void*)ctx, 0, &eve, str_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern const char argp_program_doc[];
|
||||
|
||||
void argp_state_help(const struct argp_state *__state, int flag) {
|
||||
printf("%s", argp_program_doc);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif /* __SIGSNOOP_BPF_SKEL_H__ */
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef EWASM_EWASM_APP_H_
|
||||
#define EWASM_EWASM_APP_H_
|
||||
|
||||
// header only helpers for develop wasm app
|
||||
#include "cJSON/cJSON.c"
|
||||
#include "helpers.h"
|
||||
|
||||
#endif // EWASM_EWASM_APP_H
|
||||
Reference in New Issue
Block a user