ffeval.c 4.1 KB

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