ffeval.c 4.3 KB

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