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");
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 }
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
level
uint8_t level
Definition: svq3.c:210
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
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:333
AV_ESCAPE_FLAG_STRICT
#define AV_ESCAPE_FLAG_STRICT
Escape only specified special characters.
Definition: avstring.h:339
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:332
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:321
NULL
#define NULL
Definition: coverity.c:32
src
#define src
Definition: vp8dsp.c:254
AV_ESCAPE_MODE_AUTO
@ AV_ESCAPE_MODE_AUTO
Use auto-selected escaping mode.
Definition: avstring.h:319
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
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:320
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVEscapeMode
AVEscapeMode
Definition: avstring.h:318
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