FFmpeg  4.4.5
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 }
FILE * outfile
Definition: audiogen.c:96
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140
#define AV_BPRINT_SIZE_UNLIMITED
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
#define NULL
Definition: coverity.c:32
int main(int argc, char **argv)
Definition: ffescape.c:55
static void usage(void)
Definition: ffescape.c:38
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
static char * optarg
Definition: getopt.c:39
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
#define AV_ESCAPE_FLAG_STRICT
Escape only specified special characters.
Definition: avstring.h:345
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
#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES
Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double quoted attributes.
Definition: avstring.h:357
#define AV_ESCAPE_FLAG_WHITESPACE
Consider spaces special and escape them even in the middle of the string.
Definition: avstring.h:338
#define AV_ESCAPE_FLAG_XML_SINGLE_QUOTES
Within AV_ESCAPE_MODE_XML, additionally escape single quotes for single quoted attributes.
Definition: avstring.h:351
AVEscapeMode
Definition: avstring.h:323
@ AV_ESCAPE_MODE_AUTO
Use auto-selected escaping mode.
Definition: avstring.h:324
@ AV_ESCAPE_MODE_XML
Use XML non-markup character data escaping.
Definition: avstring.h:327
@ AV_ESCAPE_MODE_QUOTE
Use single-quote escaping.
Definition: avstring.h:326
@ AV_ESCAPE_MODE_BACKSLASH
Use backslash escaping.
Definition: avstring.h:325
uint8_t level
Definition: svq3.c:206
#define av_free(p)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
static double c[64]