ffeval.c 3.9 KB

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