ffeval.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #if HAVE_UNISTD_H
  22. #include <unistd.h> /* getopt */
  23. #endif
  24. #include "libavutil/eval.h"
  25. #include "libavutil/mem.h"
  26. #if !HAVE_GETOPT
  27. #include "compat/getopt.c"
  28. #endif
  29. /**
  30. * @file
  31. * simple arithmetic expression evaluator
  32. */
  33. static void usage(void)
  34. {
  35. printf("Simple expression evalutor, please *don't* turn me to a feature-complete language interpreter\n");
  36. printf("usage: ffeval [OPTIONS]\n");
  37. printf("\n"
  38. "Options:\n"
  39. "-e echo each input line on output\n"
  40. "-h print this help\n"
  41. "-i INFILE set INFILE as input file, stdin if omitted\n"
  42. "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
  43. "-p PROMPT set output prompt\n");
  44. }
  45. int main(int argc, char **argv)
  46. {
  47. int buf_size = 0;
  48. char *buf = NULL;
  49. const char *outfilename = NULL, *infilename = NULL;
  50. FILE *outfile = NULL, *infile = NULL;
  51. const char *prompt = "=> ";
  52. int count = 0, echo = 0;
  53. int c;
  54. #define GROW_ARRAY() \
  55. do { \
  56. if (!av_dynarray2_add((void **)&buf, &buf_size, 1, NULL)) { \
  57. av_log(NULL, AV_LOG_ERROR, \
  58. "Memory allocation problem occurred\n"); \
  59. return 1; \
  60. } \
  61. } while (0)
  62. GROW_ARRAY();
  63. while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
  64. switch (c) {
  65. case 'e':
  66. echo = 1;
  67. break;
  68. case 'h':
  69. usage();
  70. return 0;
  71. case 'i':
  72. infilename = optarg;
  73. break;
  74. case 'o':
  75. outfilename = optarg;
  76. break;
  77. case 'p':
  78. prompt = optarg;
  79. break;
  80. case '?':
  81. return 1;
  82. }
  83. }
  84. if (!infilename || !strcmp(infilename, "-")) {
  85. infilename = "stdin";
  86. infile = stdin;
  87. } else {
  88. infile = fopen(infilename, "r");
  89. }
  90. if (!infile) {
  91. fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
  92. return 1;
  93. }
  94. if (!outfilename || !strcmp(outfilename, "-")) {
  95. outfilename = "stdout";
  96. outfile = stdout;
  97. } else {
  98. outfile = fopen(outfilename, "w");
  99. }
  100. if (!outfile) {
  101. fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
  102. return 1;
  103. }
  104. while ((c = fgetc(infile)) != EOF) {
  105. if (c == '\n') {
  106. double d;
  107. buf[count] = 0;
  108. if (buf[0] != '#') {
  109. int ret = av_expr_parse_and_eval(&d, buf,
  110. NULL, NULL,
  111. NULL, NULL, NULL, NULL, NULL, 0, NULL);
  112. if (echo)
  113. fprintf(outfile, "%s ", buf);
  114. if (ret >= 0) fprintf(outfile, "%s%f\n", prompt, d);
  115. else fprintf(outfile, "%s%f (%s)\n", prompt, d, av_err2str(ret));
  116. }
  117. count = 0;
  118. } else {
  119. if (count >= buf_size-1)
  120. GROW_ARRAY();
  121. buf[count++] = c;
  122. }
  123. }
  124. av_free(buf);
  125. return 0;
  126. }