yading@11
|
1 /*
|
yading@11
|
2 * Copyright (c) 2012 Stefano Sabatini
|
yading@11
|
3 *
|
yading@11
|
4 * This file is part of FFmpeg.
|
yading@11
|
5 *
|
yading@11
|
6 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
7 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
8 * License as published by the Free Software Foundation; either
|
yading@11
|
9 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
10 *
|
yading@11
|
11 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
14 * Lesser General Public License for more details.
|
yading@11
|
15 *
|
yading@11
|
16 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
17 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
19 */
|
yading@11
|
20
|
yading@11
|
21 #include "config.h"
|
yading@11
|
22 #if HAVE_UNISTD_H
|
yading@11
|
23 #include <unistd.h> /* getopt */
|
yading@11
|
24 #endif
|
yading@11
|
25
|
yading@11
|
26 #include "libavutil/log.h"
|
yading@11
|
27 #include "libavutil/bprint.h"
|
yading@11
|
28
|
yading@11
|
29 #if !HAVE_GETOPT
|
yading@11
|
30 #include "compat/getopt.c"
|
yading@11
|
31 #endif
|
yading@11
|
32
|
yading@11
|
33 /**
|
yading@11
|
34 * @file
|
yading@11
|
35 * escaping utility
|
yading@11
|
36 */
|
yading@11
|
37
|
yading@11
|
38 static void usage(void)
|
yading@11
|
39 {
|
yading@11
|
40 printf("Escape an input string, adopting the av_get_token() escaping logic\n");
|
yading@11
|
41 printf("usage: ffescape [OPTIONS]\n");
|
yading@11
|
42 printf("\n"
|
yading@11
|
43 "Options:\n"
|
yading@11
|
44 "-e echo each input line on output\n"
|
yading@11
|
45 "-f flag select an escape flag, can assume the values 'whitespace' and 'strict'\n"
|
yading@11
|
46 "-h print this help\n"
|
yading@11
|
47 "-i INFILE set INFILE as input file, stdin if omitted\n"
|
yading@11
|
48 "-l LEVEL set the number of escaping levels, 1 if omitted\n"
|
yading@11
|
49 "-m ESCAPE_MODE select escape mode between 'auto', 'backslash', 'quote'\n"
|
yading@11
|
50 "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
|
yading@11
|
51 "-p PROMPT set output prompt, is '=> ' by default\n"
|
yading@11
|
52 "-s SPECIAL_CHARS set the list of special characters\n");
|
yading@11
|
53 }
|
yading@11
|
54
|
yading@11
|
55 int main(int argc, char **argv)
|
yading@11
|
56 {
|
yading@11
|
57 AVBPrint src;
|
yading@11
|
58 char *src_buf, *dst_buf;
|
yading@11
|
59 const char *outfilename = NULL, *infilename = NULL;
|
yading@11
|
60 FILE *outfile = NULL, *infile = NULL;
|
yading@11
|
61 const char *prompt = "=> ";
|
yading@11
|
62 enum AVEscapeMode escape_mode = AV_ESCAPE_MODE_AUTO;
|
yading@11
|
63 int escape_flags = 0;
|
yading@11
|
64 int level = 1;
|
yading@11
|
65 int echo = 0;
|
yading@11
|
66 char *special_chars = NULL;
|
yading@11
|
67 int c;
|
yading@11
|
68
|
yading@11
|
69 while ((c = getopt(argc, argv, "ef:hi:l:o:m:p:s:")) != -1) {
|
yading@11
|
70 switch (c) {
|
yading@11
|
71 case 'e':
|
yading@11
|
72 echo = 1;
|
yading@11
|
73 break;
|
yading@11
|
74 case 'h':
|
yading@11
|
75 usage();
|
yading@11
|
76 return 0;
|
yading@11
|
77 case 'i':
|
yading@11
|
78 infilename = optarg;
|
yading@11
|
79 break;
|
yading@11
|
80 case 'f':
|
yading@11
|
81 if (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE;
|
yading@11
|
82 else if (!strcmp(optarg, "strict")) escape_flags |= AV_ESCAPE_FLAG_STRICT;
|
yading@11
|
83 else {
|
yading@11
|
84 av_log(NULL, AV_LOG_ERROR,
|
yading@11
|
85 "Invalid value '%s' for option -f, "
|
yading@11
|
86 "valid arguments are 'whitespace', and 'strict'\n", optarg);
|
yading@11
|
87 return 1;
|
yading@11
|
88 }
|
yading@11
|
89 break;
|
yading@11
|
90 case 'l':
|
yading@11
|
91 {
|
yading@11
|
92 char *tail;
|
yading@11
|
93 long int li = strtol(optarg, &tail, 10);
|
yading@11
|
94 if (*tail || li > INT_MAX || li < 0) {
|
yading@11
|
95 av_log(NULL, AV_LOG_ERROR,
|
yading@11
|
96 "Invalid value '%s' for option -l, argument must be a non negative integer\n",
|
yading@11
|
97 optarg);
|
yading@11
|
98 return 1;
|
yading@11
|
99 }
|
yading@11
|
100 level = li;
|
yading@11
|
101 break;
|
yading@11
|
102 }
|
yading@11
|
103 case 'm':
|
yading@11
|
104 if (!strcmp(optarg, "auto")) escape_mode = AV_ESCAPE_MODE_AUTO;
|
yading@11
|
105 else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH;
|
yading@11
|
106 else if (!strcmp(optarg, "quote")) escape_mode = AV_ESCAPE_MODE_QUOTE;
|
yading@11
|
107 else {
|
yading@11
|
108 av_log(NULL, AV_LOG_ERROR,
|
yading@11
|
109 "Invalid value '%s' for option -m, "
|
yading@11
|
110 "valid arguments are 'backslash', and 'quote'\n", optarg);
|
yading@11
|
111 return 1;
|
yading@11
|
112 }
|
yading@11
|
113 break;
|
yading@11
|
114 case 'o':
|
yading@11
|
115 outfilename = optarg;
|
yading@11
|
116 break;
|
yading@11
|
117 case 'p':
|
yading@11
|
118 prompt = optarg;
|
yading@11
|
119 break;
|
yading@11
|
120 case 's':
|
yading@11
|
121 special_chars = optarg;
|
yading@11
|
122 break;
|
yading@11
|
123 case '?':
|
yading@11
|
124 return 1;
|
yading@11
|
125 }
|
yading@11
|
126 }
|
yading@11
|
127
|
yading@11
|
128 if (!infilename || !strcmp(infilename, "-")) {
|
yading@11
|
129 infilename = "stdin";
|
yading@11
|
130 infile = stdin;
|
yading@11
|
131 } else {
|
yading@11
|
132 infile = fopen(infilename, "r");
|
yading@11
|
133 }
|
yading@11
|
134 if (!infile) {
|
yading@11
|
135 av_log(NULL, AV_LOG_ERROR, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
|
yading@11
|
136 return 1;
|
yading@11
|
137 }
|
yading@11
|
138
|
yading@11
|
139 if (!outfilename || !strcmp(outfilename, "-")) {
|
yading@11
|
140 outfilename = "stdout";
|
yading@11
|
141 outfile = stdout;
|
yading@11
|
142 } else {
|
yading@11
|
143 outfile = fopen(outfilename, "w");
|
yading@11
|
144 }
|
yading@11
|
145 if (!outfile) {
|
yading@11
|
146 av_log(NULL, AV_LOG_ERROR, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
|
yading@11
|
147 return 1;
|
yading@11
|
148 }
|
yading@11
|
149
|
yading@11
|
150 /* grab the input and store it in src */
|
yading@11
|
151 av_bprint_init(&src, 1, AV_BPRINT_SIZE_UNLIMITED);
|
yading@11
|
152 while ((c = fgetc(infile)) != EOF)
|
yading@11
|
153 av_bprint_chars(&src, c, 1);
|
yading@11
|
154 av_bprint_chars(&src, 0, 1);
|
yading@11
|
155
|
yading@11
|
156 if (!av_bprint_is_complete(&src)) {
|
yading@11
|
157 av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
|
yading@11
|
158 av_bprint_finalize(&src, NULL);
|
yading@11
|
159 return 1;
|
yading@11
|
160 }
|
yading@11
|
161 av_bprint_finalize(&src, &src_buf);
|
yading@11
|
162
|
yading@11
|
163 if (echo)
|
yading@11
|
164 fprintf(outfile, "%s", src_buf);
|
yading@11
|
165
|
yading@11
|
166 /* escape */
|
yading@11
|
167 dst_buf = src_buf;
|
yading@11
|
168 while (level--) {
|
yading@11
|
169 if (av_escape(&dst_buf, src_buf, special_chars, escape_mode, escape_flags) < 0) {
|
yading@11
|
170 av_log(NULL, AV_LOG_ERROR, "Could not escape string\n");
|
yading@11
|
171 return 1;
|
yading@11
|
172 }
|
yading@11
|
173 av_free(src_buf);
|
yading@11
|
174 src_buf = dst_buf;
|
yading@11
|
175 }
|
yading@11
|
176
|
yading@11
|
177 fprintf(outfile, "%s%s", prompt, dst_buf);
|
yading@11
|
178 av_free(dst_buf);
|
yading@11
|
179 return 0;
|
yading@11
|
180 }
|