136 lines
4.0 KiB
C
136 lines
4.0 KiB
C
/* -*- mode: C -*- Time-stamp: "2019-01-03 09:44:20 jemarch"
|
|
*
|
|
* File: testrec.c
|
|
* Date: Fri Aug 23 21:41:00 2013
|
|
*
|
|
* GNU recutils - testrec bash loadable builtin.
|
|
*
|
|
*/
|
|
|
|
/* Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2022
|
|
* Jose E. Marchesi */
|
|
|
|
/* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <bash/config.h>
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
|
#include <rec.h>
|
|
|
|
#include "builtins.h"
|
|
#include "shell.h"
|
|
#include "common.h"
|
|
#include "builtins/bashgetopt.h"
|
|
|
|
/* The function implementing the builtin. It uses internal_getopt to
|
|
parse options. It is the same as getopt(3), but it takes a pointer
|
|
to a WORD_LIST.
|
|
|
|
If the builtin takes no options, call no_options(list) before doing
|
|
anything else. If it returns a non-zero value, your builtin should
|
|
immediately return EX_USAGE.
|
|
|
|
A builtin command returns EXECUTION_SUCCESS for success and
|
|
EXECUTION_FAILURE to indicate failure. */
|
|
int
|
|
testrec_builtin (WORD_LIST *list)
|
|
{
|
|
int res = EXECUTION_SUCCESS;
|
|
char **argv;
|
|
int argc;
|
|
SHELL_VAR *var;
|
|
rec_record_t record;
|
|
rec_parser_t parser;
|
|
char *record_str, *sex_str;
|
|
|
|
/* Get arguments and verify them. */
|
|
|
|
argv = make_builtin_argv (list, &argc);
|
|
if ((argc != 3)
|
|
|| ((strcmp (argv[0], "[%") == 0) && ((strlen (argv[2]) == 2) && ((argv[2][0] != '%') || (argv[2][1] != ']')))))
|
|
{
|
|
fprintf (stderr, "Usage: [%% SEX %%]\n");
|
|
return EXECUTION_FAILURE;
|
|
}
|
|
|
|
sex_str = argv[1];
|
|
|
|
/* Get the record to operate on from the REPLY_REC environment
|
|
variable. */
|
|
var = find_variable ("REPLY_REC");
|
|
if (!var)
|
|
return EXECUTION_FAILURE;
|
|
|
|
record_str = get_variable_value (var);
|
|
parser = rec_parser_new_str (record_str, "REPLY_REC");
|
|
if (!parser || !rec_parse_record (parser, &record))
|
|
{
|
|
fprintf (stderr, "testrec: error: invalid record in REPLY_REC\n");
|
|
return EXECUTION_FAILURE;
|
|
}
|
|
|
|
/* Apply the selection expression. */
|
|
{
|
|
bool status = false;
|
|
rec_sex_t sex = rec_sex_new (false);
|
|
if (!sex)
|
|
return EXECUTION_FAILURE;
|
|
|
|
if (!rec_sex_compile (sex, sex_str))
|
|
{
|
|
fprintf (stderr, "testrec: error: wrong selection expression\n");
|
|
return EXECUTION_FAILURE;
|
|
}
|
|
|
|
res = rec_sex_eval (sex, record, &status) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
|
|
rec_sex_destroy (sex);
|
|
}
|
|
|
|
/* Cleanup. */
|
|
rec_record_destroy (record);
|
|
|
|
return res;
|
|
}
|
|
|
|
/* An array of strings forming the `long' documentation for the builtin,
|
|
which is printed by `help xxx'. It must end with a NULL. By convention,
|
|
the first line is a short description. */
|
|
char *testrec_doc[] = {
|
|
"Evaluate a selection expression on the record stored in REPLY_REC.",
|
|
"",
|
|
"Evaluates a given selection expression on the record stored in the\n\
|
|
REPLY_REC variable, if any.\n\
|
|
\n\
|
|
Exit Status:\n\
|
|
The return code is zero if the selection expression evaluates to\n\
|
|
true, -1 otherwise.\n",
|
|
(char *) NULL
|
|
};
|
|
|
|
/* The standard structure describing a builtin command. bash keeps an
|
|
array of these structures. The flags must include BUILTIN_ENABLED
|
|
so the builtin can be used. */
|
|
struct builtin testrec_struct = {
|
|
"[%", /* builtin name */
|
|
testrec_builtin, /* function implementing the builtin */
|
|
BUILTIN_ENABLED, /* initial flags for builtin */
|
|
testrec_doc, /* array of long documentation strings. */
|
|
"testrec", /* usage synopsis; becomes short_doc */
|
|
0 /* reserved for internal use */
|
|
};
|