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 if (!strcmp(optarg, "xml_single_quotes")) escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES;
84  else if (!strcmp(optarg, "xml_double_quotes")) escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES;
85  else {
87  "Invalid value '%s' for option -f, "
88  "valid arguments are 'whitespace', and 'strict'\n", optarg);
89  return 1;
90  }
91  break;
92  case 'l':
93  {
94  char *tail;
95  long int li = strtol(optarg, &tail, 10);
96  if (*tail || li > INT_MAX || li < 0) {
98  "Invalid value '%s' for option -l, argument must be a non negative integer\n",
99  optarg);
100  return 1;
101  }
102  level = li;
103  break;
104  }
105  case 'm':
106  if (!strcmp(optarg, "auto")) escape_mode = AV_ESCAPE_MODE_AUTO;
107  else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH;
108  else if (!strcmp(optarg, "quote")) escape_mode = AV_ESCAPE_MODE_QUOTE;
109  else if (!strcmp(optarg, "xml")) escape_mode = AV_ESCAPE_MODE_XML;
110  else {
112  "Invalid value '%s' for option -m, "
113  "valid arguments are 'backslash', and 'quote'\n", optarg);
114  return 1;
115  }
116  break;
117  case 'o':
118  outfilename = optarg;
119  break;
120  case 'p':
121  prompt = optarg;
122  break;
123  case 's':
124  special_chars = optarg;
125  break;
126  case '?':
127  return 1;
128  }
129  }
130 
131  if (!infilename || !strcmp(infilename, "-")) {
132  infilename = "stdin";
133  infile = stdin;
134  } else {
135  infile = fopen(infilename, "r");
136  }
137  if (!infile) {
138  av_log(NULL, AV_LOG_ERROR, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
139  return 1;
140  }
141 
142  if (!outfilename || !strcmp(outfilename, "-")) {
143  outfilename = "stdout";
144  outfile = stdout;
145  } else {
146  outfile = fopen(outfilename, "w");
147  }
148  if (!outfile) {
149  av_log(NULL, AV_LOG_ERROR, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
150  return 1;
151  }
152 
153  /* grab the input and store it in src */
155  while ((c = fgetc(infile)) != EOF)
156  av_bprint_chars(&src, c, 1);
157  av_bprint_chars(&src, 0, 1);
158 
159  if (!av_bprint_is_complete(&src)) {
160  av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
162  return 1;
163  }
164  av_bprint_finalize(&src, &src_buf);
165 
166  if (echo)
167  fprintf(outfile, "%s", src_buf);
168 
169  /* escape */
170  dst_buf = src_buf;
171  while (level--) {
172  if (av_escape(&dst_buf, src_buf, special_chars, escape_mode, escape_flags) < 0) {
173  av_log(NULL, AV_LOG_ERROR, "Could not escape string\n");
174  return 1;
175  }
176  av_free(src_buf);
177  src_buf = dst_buf;
178  }
179 
180  fprintf(outfile, "%s%s", prompt, dst_buf);
181  av_free(dst_buf);
182  return 0;
183 }
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
level
uint8_t level
Definition: svq3.c:206
usage
static void usage(void)
Definition: ffescape.c:38
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
main
int main(int argc, char **argv)
Definition: ffescape.c:55
AV_ESCAPE_FLAG_XML_SINGLE_QUOTES
#define AV_ESCAPE_FLAG_XML_SINGLE_QUOTES
Within AV_ESCAPE_MODE_XML, additionally escape single quotes for single quoted attributes.
Definition: avstring.h:351
outfile
FILE * outfile
Definition: audiogen.c:96
av_escape
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:335
AV_ESCAPE_FLAG_STRICT
#define AV_ESCAPE_FLAG_STRICT
Escape only specified special characters.
Definition: avstring.h:345
AV_ESCAPE_FLAG_WHITESPACE
#define AV_ESCAPE_FLAG_WHITESPACE
Consider spaces special and escape them even in the middle of the string.
Definition: avstring.h:338
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES
#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES
Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double quoted attributes.
Definition: avstring.h:357
getopt
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
AV_ESCAPE_MODE_QUOTE
@ AV_ESCAPE_MODE_QUOTE
Use single-quote escaping.
Definition: avstring.h:326
NULL
#define NULL
Definition: coverity.c:32
src
#define src
Definition: vp8dsp.c:255
AV_ESCAPE_MODE_AUTO
@ AV_ESCAPE_MODE_AUTO
Use auto-selected escaping mode.
Definition: avstring.h:324
c
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
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
AV_ESCAPE_MODE_XML
@ AV_ESCAPE_MODE_XML
Use XML non-markup character data escaping.
Definition: avstring.h:327
printf
printf("static const uint8_t my_array[100] = {\n")
bprint.h
log.h
getopt.c
optarg
static char * optarg
Definition: getopt.c:39
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AV_ESCAPE_MODE_BACKSLASH
@ AV_ESCAPE_MODE_BACKSLASH
Use backslash escaping.
Definition: avstring.h:325
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVEscapeMode
AVEscapeMode
Definition: avstring.h:323
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140