FFmpeg
ffescape.c
Go to the documentation of this file.
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 
21 #include "config.h"
22 #if HAVE_UNISTD_H
23 #include <unistd.h> /* getopt */
24 #endif
25 
26 #include "libavutil/log.h"
27 #include "libavutil/bprint.h"
28 
29 #if !HAVE_GETOPT
30 #include "compat/getopt.c"
31 #endif
32 
33 /**
34  * @file
35  * escaping utility
36  */
37 
38 static void usage(void)
39 {
40  printf("Escape an input string, adopting the av_get_token() escaping logic\n");
41  printf("usage: ffescape [OPTIONS]\n");
42  printf("\n"
43  "Options:\n"
44  "-e echo each input line on output\n"
45  "-f flag select an escape flag, can assume the values 'whitespace' and 'strict'\n"
46  "-h print this help\n"
47  "-i INFILE set INFILE as input file, stdin if omitted\n"
48  "-l LEVEL set the number of escaping levels, 1 if omitted\n"
49  "-m ESCAPE_MODE select escape mode between 'auto', 'backslash', 'quote'\n"
50  "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
51  "-p PROMPT set output prompt, is '=> ' by default\n"
52  "-s SPECIAL_CHARS set the list of special characters\n");
53 }
54 
55 int main(int argc, char **argv)
56 {
57  AVBPrint src;
58  char *src_buf, *dst_buf;
59  const char *outfilename = NULL, *infilename = NULL;
60  FILE *outfile = NULL, *infile = NULL;
61  const char *prompt = "=> ";
62  enum AVEscapeMode escape_mode = AV_ESCAPE_MODE_AUTO;
63  int escape_flags = 0;
64  int level = 1;
65  int echo = 0;
66  char *special_chars = NULL;
67  int c;
68 
69  while ((c = getopt(argc, argv, "ef:hi:l:o:m:p:s:")) != -1) {
70  switch (c) {
71  case 'e':
72  echo = 1;
73  break;
74  case 'h':
75  usage();
76  return 0;
77  case 'i':
78  infilename = optarg;
79  break;
80  case 'f':
81  if (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
82  else if (!strcmp(optarg, "strict")) escape_flags |= AV_ESCAPE_FLAG_STRICT;
83  else {
85  "Invalid value '%s' for option -f, "
86  "valid arguments are 'whitespace', and 'strict'\n", optarg);
87  return 1;
88  }
89  break;
90  case 'l':
91  {
92  char *tail;
93  long int li = strtol(optarg, &tail, 10);
94  if (*tail || li > INT_MAX || li < 0) {
96  "Invalid value '%s' for option -l, argument must be a non negative integer\n",
97  optarg);
98  return 1;
99  }
100  level = li;
101  break;
102  }
103  case 'm':
104  if (!strcmp(optarg, "auto")) escape_mode = AV_ESCAPE_MODE_AUTO;
105  else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH;
106  else if (!strcmp(optarg, "quote")) escape_mode = AV_ESCAPE_MODE_QUOTE;
107  else {
109  "Invalid value '%s' for option -m, "
110  "valid arguments are 'backslash', and 'quote'\n", optarg);
111  return 1;
112  }
113  break;
114  case 'o':
115  outfilename = optarg;
116  break;
117  case 'p':
118  prompt = optarg;
119  break;
120  case 's':
121  special_chars = optarg;
122  break;
123  case '?':
124  return 1;
125  }
126  }
127 
128  if (!infilename || !strcmp(infilename, "-")) {
129  infilename = "stdin";
130  infile = stdin;
131  } else {
132  infile = fopen(infilename, "r");
133  }
134  if (!infile) {
135  av_log(NULL, AV_LOG_ERROR, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
136  return 1;
137  }
138 
139  if (!outfilename || !strcmp(outfilename, "-")) {
140  outfilename = "stdout";
141  outfile = stdout;
142  } else {
143  outfile = fopen(outfilename, "w");
144  }
145  if (!outfile) {
146  av_log(NULL, AV_LOG_ERROR, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
147  return 1;
148  }
149 
150  /* grab the input and store it in src */
152  while ((c = fgetc(infile)) != EOF)
153  av_bprint_chars(&src, c, 1);
154  av_bprint_chars(&src, 0, 1);
155 
156  if (!av_bprint_is_complete(&src)) {
157  av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
158  av_bprint_finalize(&src, NULL);
159  return 1;
160  }
161  av_bprint_finalize(&src, &src_buf);
162 
163  if (echo)
164  fprintf(outfile, "%s", src_buf);
165 
166  /* escape */
167  dst_buf = src_buf;
168  while (level--) {
169  if (av_escape(&dst_buf, src_buf, special_chars, escape_mode, escape_flags) < 0) {
170  av_log(NULL, AV_LOG_ERROR, "Could not escape string\n");
171  return 1;
172  }
173  av_free(src_buf);
174  src_buf = dst_buf;
175  }
176 
177  fprintf(outfile, "%s%s", prompt, dst_buf);
178  av_free(dst_buf);
179  return 0;
180 }
#define NULL
Definition: coverity.c:32
int av_escape(char **dst, const char *src, const char *special_chars, enum AVEscapeMode mode, int flags)
Escape string in src, and put the escaped string in an allocated string in *dst, which must be freed ...
Definition: avstring.c:331
Use backslash escaping.
Definition: avstring.h:320
#define src
Definition: vp8dsp.c:254
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
Use single-quote escaping.
Definition: avstring.h:321
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AV_BPRINT_SIZE_UNLIMITED
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
#define AV_ESCAPE_FLAG_STRICT
Escape only specified special characters.
Definition: avstring.h:339
Use auto-selected escaping mode.
Definition: avstring.h:319
static void usage(void)
Definition: ffescape.c:38
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
uint8_t level
Definition: svq3.c:207
static char * optarg
Definition: getopt.c:39
#define av_free(p)
printf("static const uint8_t my_array[100] = {\n")
#define AV_ESCAPE_FLAG_WHITESPACE
Consider spaces special and escape them even in the middle of the string.
Definition: avstring.h:332
AVEscapeMode
Definition: avstring.h:318
int main(int argc, char **argv)
Definition: ffescape.c:55
FILE * outfile
Definition: audiogen.c:96
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140