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 #include <errno.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #if HAVE_UNISTD_H
28 #include <unistd.h> /* getopt */
29 #endif
30 
31 #include "libavutil/log.h"
32 #include "libavutil/bprint.h"
33 #include "libavutil/mem.h"
34 
35 #if !HAVE_GETOPT
36 #include "compat/getopt.c"
37 #endif
38 
39 /**
40  * @file
41  * escaping utility
42  */
43 
44 static void usage(void)
45 {
46  printf("Escape an input string, adopting the av_get_token() escaping logic\n");
47  printf("usage: ffescape [OPTIONS]\n");
48  printf("\n"
49  "Options:\n"
50  "-e echo each input line on output\n"
51  "-f flag select an escape flag, can assume the values 'whitespace' and 'strict'\n"
52  "-h print this help\n"
53  "-i INFILE set INFILE as input file, stdin if omitted\n"
54  "-l LEVEL set the number of escaping levels, 1 if omitted\n"
55  "-m ESCAPE_MODE select escape mode between 'auto', 'backslash', 'quote'\n"
56  "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
57  "-p PROMPT set output prompt, is '=> ' by default\n"
58  "-s SPECIAL_CHARS set the list of special characters\n");
59 }
60 
61 int main(int argc, char **argv)
62 {
63  AVBPrint src;
64  char *src_buf, *dst_buf;
65  const char *outfilename = NULL, *infilename = NULL;
66  FILE *outfile = NULL, *infile = NULL;
67  const char *prompt = "=> ";
68  enum AVEscapeMode escape_mode = AV_ESCAPE_MODE_AUTO;
69  int escape_flags = 0;
70  int level = 1;
71  int echo = 0;
72  char *special_chars = NULL;
73  int c;
74 
75  while ((c = getopt(argc, argv, "ef:hi:l:o:m:p:s:")) != -1) {
76  switch (c) {
77  case 'e':
78  echo = 1;
79  break;
80  case 'h':
81  usage();
82  return 0;
83  case 'i':
84  infilename = optarg;
85  break;
86  case 'f':
87  if (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
88  else if (!strcmp(optarg, "strict")) escape_flags |= AV_ESCAPE_FLAG_STRICT;
89  else if (!strcmp(optarg, "xml_single_quotes")) escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES;
90  else if (!strcmp(optarg, "xml_double_quotes")) escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES;
91  else {
93  "Invalid value '%s' for option -f, "
94  "valid arguments are 'whitespace', and 'strict'\n", optarg);
95  return 1;
96  }
97  break;
98  case 'l':
99  {
100  char *tail;
101  long int li = strtol(optarg, &tail, 10);
102  if (*tail || li > INT_MAX || li < 0) {
104  "Invalid value '%s' for option -l, argument must be a non negative integer\n",
105  optarg);
106  return 1;
107  }
108  level = li;
109  break;
110  }
111  case 'm':
112  if (!strcmp(optarg, "auto")) escape_mode = AV_ESCAPE_MODE_AUTO;
113  else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH;
114  else if (!strcmp(optarg, "quote")) escape_mode = AV_ESCAPE_MODE_QUOTE;
115  else if (!strcmp(optarg, "xml")) escape_mode = AV_ESCAPE_MODE_XML;
116  else {
118  "Invalid value '%s' for option -m, "
119  "valid arguments are 'backslash', and 'quote'\n", optarg);
120  return 1;
121  }
122  break;
123  case 'o':
124  outfilename = optarg;
125  break;
126  case 'p':
127  prompt = optarg;
128  break;
129  case 's':
130  special_chars = optarg;
131  break;
132  case '?':
133  return 1;
134  }
135  }
136 
137  if (!infilename || !strcmp(infilename, "-")) {
138  infilename = "stdin";
139  infile = stdin;
140  } else {
141  infile = fopen(infilename, "r");
142  }
143  if (!infile) {
144  av_log(NULL, AV_LOG_ERROR, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
145  return 1;
146  }
147 
148  if (!outfilename || !strcmp(outfilename, "-")) {
149  outfilename = "stdout";
150  outfile = stdout;
151  } else {
152  outfile = fopen(outfilename, "w");
153  }
154  if (!outfile) {
155  av_log(NULL, AV_LOG_ERROR, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
156  return 1;
157  }
158 
159  /* grab the input and store it in src */
161  while ((c = fgetc(infile)) != EOF)
162  av_bprint_chars(&src, c, 1);
163  av_bprint_chars(&src, 0, 1);
164 
165  if (!av_bprint_is_complete(&src)) {
166  av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
168  return 1;
169  }
170  av_bprint_finalize(&src, &src_buf);
171 
172  if (echo)
173  fprintf(outfile, "%s", src_buf);
174 
175  /* escape */
176  dst_buf = src_buf;
177  while (level--) {
178  if (av_escape(&dst_buf, src_buf, special_chars, escape_mode, escape_flags) < 0) {
179  av_log(NULL, AV_LOG_ERROR, "Could not escape string\n");
180  return 1;
181  }
182  av_free(src_buf);
183  src_buf = dst_buf;
184  }
185 
186  fprintf(outfile, "%s%s", prompt, dst_buf);
187  av_free(dst_buf);
188  return 0;
189 }
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:44
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:61
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:338
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:180
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
limits.h
AV_ESCAPE_MODE_QUOTE
@ AV_ESCAPE_MODE_QUOTE
Use single-quote escaping.
Definition: avstring.h:326
NULL
#define NULL
Definition: coverity.c:32
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
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
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:27
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