1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2012 Stefano Sabatini
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "config.h"
22cabdff1aSopenharmony_ci#if HAVE_UNISTD_H
23cabdff1aSopenharmony_ci#include <unistd.h>             /* getopt */
24cabdff1aSopenharmony_ci#endif
25cabdff1aSopenharmony_ci
26cabdff1aSopenharmony_ci#include "libavutil/eval.h"
27cabdff1aSopenharmony_ci#include "libavutil/mem.h"
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ci#if !HAVE_GETOPT
30cabdff1aSopenharmony_ci#include "compat/getopt.c"
31cabdff1aSopenharmony_ci#endif
32cabdff1aSopenharmony_ci
33cabdff1aSopenharmony_ci/**
34cabdff1aSopenharmony_ci * @file
35cabdff1aSopenharmony_ci * simple arithmetic expression evaluator
36cabdff1aSopenharmony_ci */
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_cistatic void usage(void)
39cabdff1aSopenharmony_ci{
40cabdff1aSopenharmony_ci    printf("Simple expression evalutor, please *don't* turn me to a feature-complete language interpreter\n");
41cabdff1aSopenharmony_ci    printf("usage: ffeval [OPTIONS]\n");
42cabdff1aSopenharmony_ci    printf("\n"
43cabdff1aSopenharmony_ci           "Options:\n"
44cabdff1aSopenharmony_ci           "-e                echo each input line on output\n"
45cabdff1aSopenharmony_ci           "-h                print this help\n"
46cabdff1aSopenharmony_ci           "-i INFILE         set INFILE as input file, stdin if omitted\n"
47cabdff1aSopenharmony_ci           "-o OUTFILE        set OUTFILE as output file, stdout if omitted\n"
48cabdff1aSopenharmony_ci           "-p PROMPT         set output prompt\n");
49cabdff1aSopenharmony_ci}
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ciint main(int argc, char **argv)
52cabdff1aSopenharmony_ci{
53cabdff1aSopenharmony_ci    int buf_size = 0;
54cabdff1aSopenharmony_ci    char *buf = NULL;
55cabdff1aSopenharmony_ci    const char *outfilename = NULL, *infilename = NULL;
56cabdff1aSopenharmony_ci    FILE *outfile = NULL, *infile = NULL;
57cabdff1aSopenharmony_ci    const char *prompt = "=> ";
58cabdff1aSopenharmony_ci    int count = 0, echo = 0;
59cabdff1aSopenharmony_ci    int c;
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci#define GROW_ARRAY()                                                    \
62cabdff1aSopenharmony_ci    do {                                                                \
63cabdff1aSopenharmony_ci        if (!av_dynarray2_add((void **)&buf, &buf_size, 1, NULL)) {     \
64cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR,                                  \
65cabdff1aSopenharmony_ci                   "Memory allocation problem occurred\n");             \
66cabdff1aSopenharmony_ci            return 1;                                                   \
67cabdff1aSopenharmony_ci        }                                                               \
68cabdff1aSopenharmony_ci    } while (0)
69cabdff1aSopenharmony_ci
70cabdff1aSopenharmony_ci    GROW_ARRAY();
71cabdff1aSopenharmony_ci    while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
72cabdff1aSopenharmony_ci        switch (c) {
73cabdff1aSopenharmony_ci        case 'e':
74cabdff1aSopenharmony_ci            echo = 1;
75cabdff1aSopenharmony_ci            break;
76cabdff1aSopenharmony_ci        case 'h':
77cabdff1aSopenharmony_ci            usage();
78cabdff1aSopenharmony_ci            return 0;
79cabdff1aSopenharmony_ci        case 'i':
80cabdff1aSopenharmony_ci            infilename = optarg;
81cabdff1aSopenharmony_ci            break;
82cabdff1aSopenharmony_ci        case 'o':
83cabdff1aSopenharmony_ci            outfilename = optarg;
84cabdff1aSopenharmony_ci            break;
85cabdff1aSopenharmony_ci        case 'p':
86cabdff1aSopenharmony_ci            prompt = optarg;
87cabdff1aSopenharmony_ci            break;
88cabdff1aSopenharmony_ci        case '?':
89cabdff1aSopenharmony_ci            return 1;
90cabdff1aSopenharmony_ci        }
91cabdff1aSopenharmony_ci    }
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_ci    if (!infilename || !strcmp(infilename, "-")) {
94cabdff1aSopenharmony_ci        infilename = "stdin";
95cabdff1aSopenharmony_ci        infile = stdin;
96cabdff1aSopenharmony_ci    } else {
97cabdff1aSopenharmony_ci        infile = fopen(infilename, "r");
98cabdff1aSopenharmony_ci    }
99cabdff1aSopenharmony_ci    if (!infile) {
100cabdff1aSopenharmony_ci        fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
101cabdff1aSopenharmony_ci        return 1;
102cabdff1aSopenharmony_ci    }
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_ci    if (!outfilename || !strcmp(outfilename, "-")) {
105cabdff1aSopenharmony_ci        outfilename = "stdout";
106cabdff1aSopenharmony_ci        outfile = stdout;
107cabdff1aSopenharmony_ci    } else {
108cabdff1aSopenharmony_ci        outfile = fopen(outfilename, "w");
109cabdff1aSopenharmony_ci    }
110cabdff1aSopenharmony_ci    if (!outfile) {
111cabdff1aSopenharmony_ci        fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
112cabdff1aSopenharmony_ci        return 1;
113cabdff1aSopenharmony_ci    }
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ci    while ((c = fgetc(infile)) != EOF) {
116cabdff1aSopenharmony_ci        if (c == '\n') {
117cabdff1aSopenharmony_ci            double d;
118cabdff1aSopenharmony_ci
119cabdff1aSopenharmony_ci            buf[count] = 0;
120cabdff1aSopenharmony_ci            if (buf[0] != '#') {
121cabdff1aSopenharmony_ci                int ret = av_expr_parse_and_eval(&d, buf,
122cabdff1aSopenharmony_ci                                                 NULL, NULL,
123cabdff1aSopenharmony_ci                                                 NULL, NULL, NULL, NULL, NULL, 0, NULL);
124cabdff1aSopenharmony_ci                if (echo)
125cabdff1aSopenharmony_ci                    fprintf(outfile, "%s ", buf);
126cabdff1aSopenharmony_ci                if (ret >= 0) fprintf(outfile, "%s%f\n", prompt, d);
127cabdff1aSopenharmony_ci                else          fprintf(outfile, "%s%f (%s)\n", prompt, d, av_err2str(ret));
128cabdff1aSopenharmony_ci            }
129cabdff1aSopenharmony_ci            count = 0;
130cabdff1aSopenharmony_ci        } else {
131cabdff1aSopenharmony_ci            if (count >= buf_size-1)
132cabdff1aSopenharmony_ci                GROW_ARRAY();
133cabdff1aSopenharmony_ci            buf[count++] = c;
134cabdff1aSopenharmony_ci        }
135cabdff1aSopenharmony_ci    }
136cabdff1aSopenharmony_ci
137cabdff1aSopenharmony_ci    av_free(buf);
138cabdff1aSopenharmony_ci    return 0;
139cabdff1aSopenharmony_ci}
140