Mercurial > mplayer.hg
annotate parser-mpcmd.c @ 30017:7119354805e7
Use on-stack subtitle struct for temporary storage for passing subtitles on
for rendering by libass.
This avoids mangling the static subtitle struct that is supposed to contain
the subtitles that will actually be displayed and it also minimally reduces
memory usage by freeing the subtitle lines again as early as possible.
author | reimar |
---|---|
date | Fri, 18 Dec 2009 19:29:33 +0000 |
parents | 93947ce0e2cb |
children | c1a3f1bbba26 |
rev | line source |
---|---|
18265 | 1 |
2 /// \file | |
3 /// \ingroup ConfigParsers Playtree | |
4 | |
8164 | 5 #include "config.h" |
6 | |
7 #include <stdio.h> | |
8 #include <stdlib.h> | |
9 #include <string.h> | |
10 #include <errno.h> | |
11 | |
12 #ifdef MP_DEBUG | |
13 #include <assert.h> | |
14 #endif | |
15 | |
16 #include "mp_msg.h" | |
21312 | 17 #include "help_mp.h" |
8164 | 18 #include "m_option.h" |
19 #include "m_config.h" | |
20 #include "playtree.h" | |
26263 | 21 #include "parser-mpcmd.h" |
8164 | 22 |
23 static int recursion_depth = 0; | |
24 static int mode = 0; | |
25 | |
26 #define GLOBAL 0 | |
27 #define LOCAL 1 | |
28 #define DROP_LOCAL 2 | |
29 | |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
30 #define dvd_range(a) (a>0 && a<256) |
8164 | 31 #define UNSET_GLOBAL (mode = LOCAL) |
32 // Use this 1 if you want to have only global option (no per file option) | |
33 // #define UNSET_GLOBAL (mode = GLOBAL) | |
34 | |
35 | |
36 static int is_entry_option(char *opt, char *param, play_tree_t** ret) { | |
37 play_tree_t* entry = NULL; | |
38 | |
39 *ret = NULL; | |
40 | |
41 if(strcasecmp(opt,"playlist") == 0) { // We handle playlist here | |
42 if(!param) | |
43 return M_OPT_MISSING_PARAM; | |
12267 | 44 |
8164 | 45 entry = parse_playlist_file(param); |
46 if(!entry) | |
12267 | 47 return -1; |
48 else { | |
49 *ret=entry; | |
50 return 1; | |
51 } | |
8164 | 52 } |
53 return 0; | |
54 } | |
55 | |
10542
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
56 static inline void add_entry(play_tree_t **last_parentp, |
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
57 play_tree_t **last_entryp, play_tree_t *entry) { |
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
58 if(*last_entryp == NULL) |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
59 play_tree_set_child(*last_parentp,entry); |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
60 else |
10542
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
61 play_tree_append_entry(*last_entryp,entry); |
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
62 *last_entryp = entry; |
10513 | 63 } |
64 | |
18265 | 65 /// Setup the \ref Config from command line arguments and build a playtree. |
66 /** \ingroup ConfigParsers | |
67 */ | |
8164 | 68 play_tree_t* |
69 m_config_parse_mp_command_line(m_config_t *config, int argc, char **argv) | |
70 { | |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
71 int i,j,start_title=-1,end_title=-1; |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
72 char *opt,*splitpos=NULL; |
29850
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
73 char entbuf[15]; |
8164 | 74 int no_more_opts = 0; |
16345
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
75 int opt_exit = 0; // flag indicating whether mplayer should exit without playing anything |
8164 | 76 play_tree_t *last_parent, *last_entry = NULL, *root; |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27394
diff
changeset
|
77 #ifdef CONFIG_MACOSX_FINDER |
28051 | 78 play_tree_t *macosx_finder_args(m_config_t *, int , char **); |
13909
07dadc3066f3
add support for macosx finder argument support (let you bundle mplayer to be a finder compliant .app) patch by Chris Roccati <roccati@pobox.com>
nplourde
parents:
12816
diff
changeset
|
79 #endif |
8164 | 80 |
81 #ifdef MP_DEBUG | |
82 assert(config != NULL); | |
83 assert(argv != NULL); | |
84 assert(argc >= 1); | |
85 #endif | |
86 | |
87 config->mode = M_COMMAND_LINE; | |
88 mode = GLOBAL; | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27394
diff
changeset
|
89 #ifdef CONFIG_MACOSX_FINDER |
13909
07dadc3066f3
add support for macosx finder argument support (let you bundle mplayer to be a finder compliant .app) patch by Chris Roccati <roccati@pobox.com>
nplourde
parents:
12816
diff
changeset
|
90 root=macosx_finder_args(config, argc, argv); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
91 if(root) |
13909
07dadc3066f3
add support for macosx finder argument support (let you bundle mplayer to be a finder compliant .app) patch by Chris Roccati <roccati@pobox.com>
nplourde
parents:
12816
diff
changeset
|
92 return root; |
07dadc3066f3
add support for macosx finder argument support (let you bundle mplayer to be a finder compliant .app) patch by Chris Roccati <roccati@pobox.com>
nplourde
parents:
12816
diff
changeset
|
93 #endif |
07dadc3066f3
add support for macosx finder argument support (let you bundle mplayer to be a finder compliant .app) patch by Chris Roccati <roccati@pobox.com>
nplourde
parents:
12816
diff
changeset
|
94 |
8164 | 95 last_parent = root = play_tree_new(); |
96 /* in order to work recursion detection properly in parse_config_file */ | |
97 ++recursion_depth; | |
98 | |
99 for (i = 1; i < argc; i++) { | |
100 //next: | |
101 opt = argv[i]; | |
102 /* check for -- (no more options id.) except --help! */ | |
15245
4fdfe0860cc5
Make "mplayer -- --a" play the file --a instead of bailing out with a useless
reimar
parents:
14541
diff
changeset
|
103 if ((*opt == '-') && (*(opt+1) == '-') && (*(opt+2) == 0)) |
8164 | 104 { |
105 no_more_opts = 1; | |
106 if (i+1 >= argc) | |
107 { | |
21312 | 108 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_NoFileGivenOnCommandLine); |
8164 | 109 goto err_out; |
110 } | |
111 continue; | |
112 } | |
113 if((opt[0] == '{') && (opt[1] == '\0')) | |
114 { | |
115 play_tree_t* entry = play_tree_new(); | |
116 UNSET_GLOBAL; | |
8175 | 117 if(last_parent->flags & PLAY_TREE_RND) |
118 entry->flags |= PLAY_TREE_RND; | |
8164 | 119 if(last_entry == NULL) { |
120 play_tree_set_child(last_parent,entry); | |
121 } else { | |
122 play_tree_append_entry(last_entry,entry); | |
123 last_entry = NULL; | |
124 } | |
125 last_parent = entry; | |
126 continue; | |
127 } | |
128 | |
129 if((opt[0] == '}') && (opt[1] == '\0')) | |
130 { | |
131 if( ! last_parent || ! last_parent->parent) { | |
132 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "too much }-\n"); | |
133 goto err_out; | |
134 } | |
135 last_entry = last_parent; | |
136 last_parent = last_entry->parent; | |
137 continue; | |
138 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
139 |
8164 | 140 if ((no_more_opts == 0) && (*opt == '-') && (*(opt+1) != 0)) /* option */ |
141 { | |
13932
f845791e2823
fix: when doing -loop 0 -shuffle, the arg after shuffle was skipped
reimar
parents:
13909
diff
changeset
|
142 int tmp = 0; |
8164 | 143 /* remove trailing '-' */ |
144 opt++; | |
145 | |
146 mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "this_opt = option: %s\n", opt); | |
147 // We handle here some specific option | |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
16345
diff
changeset
|
148 // Loop option when it apply to a group |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
16345
diff
changeset
|
149 if(strcasecmp(opt,"loop") == 0 && |
8164 | 150 (! last_entry || last_entry->child) ) { |
151 int l; | |
18097
df9633d451dc
avoid crash when running "mplayer -loop" (dereferencing uninitialize pointer).
reimar
parents:
17472
diff
changeset
|
152 char* end = NULL; |
8400 | 153 l = (i+1<argc) ? strtol(argv[i+1],&end,0) : 0; |
18097
df9633d451dc
avoid crash when running "mplayer -loop" (dereferencing uninitialize pointer).
reimar
parents:
17472
diff
changeset
|
154 if(!end || *end != '\0') { |
21312 | 155 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_TheLoopOptionMustBeAnInteger, argv[i+1]); |
8164 | 156 tmp = ERR_OUT_OF_RANGE; |
9106 | 157 } else { |
8164 | 158 play_tree_t* pt = last_entry ? last_entry : last_parent; |
159 l = l <= 0 ? -1 : l; | |
160 pt->loop = l; | |
161 tmp = 1; | |
162 } | |
8452 | 163 } else if(strcasecmp(opt,"shuffle") == 0) { |
8175 | 164 if(last_entry && last_entry->child) |
165 last_entry->flags |= PLAY_TREE_RND; | |
166 else | |
167 last_parent->flags |= PLAY_TREE_RND; | |
8452 | 168 } else if(strcasecmp(opt,"noshuffle") == 0) { |
8175 | 169 if(last_entry && last_entry->child) |
170 last_entry->flags &= ~PLAY_TREE_RND; | |
171 else | |
172 last_parent->flags &= ~PLAY_TREE_RND; | |
8164 | 173 } else { |
25227 | 174 const m_option_t* mp_opt = NULL; |
8164 | 175 play_tree_t* entry = NULL; |
176 | |
8458 | 177 tmp = is_entry_option(opt,(i+1<argc) ? argv[i + 1] : NULL,&entry); |
8164 | 178 if(tmp > 0) { // It's an entry |
179 if(entry) { | |
10542
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
180 add_entry(&last_parent,&last_entry,entry); |
8175 | 181 if((last_parent->flags & PLAY_TREE_RND) && entry->child) |
182 entry->flags |= PLAY_TREE_RND; | |
8164 | 183 UNSET_GLOBAL; |
184 } else if(mode == LOCAL) // Entry is empty we have to drop his params | |
185 mode = DROP_LOCAL; | |
186 } else if(tmp == 0) { // 'normal' options | |
187 mp_opt = m_config_get_option(config,opt); | |
188 if (mp_opt != NULL) { // Option exist | |
189 if(mode == GLOBAL || (mp_opt->flags & M_OPT_GLOBAL)) | |
8426 | 190 tmp = (i+1<argc) ? m_config_set_option(config, opt, argv[i + 1]) |
191 : m_config_set_option(config, opt, NULL); | |
8164 | 192 else { |
8458 | 193 tmp = m_config_check_option(config, opt, (i+1<argc) ? argv[i + 1] : NULL); |
8164 | 194 if(tmp >= 0 && mode != DROP_LOCAL) { |
195 play_tree_t* pt = last_entry ? last_entry : last_parent; | |
196 play_tree_set_param(pt,opt, argv[i + 1]); | |
197 } | |
198 } | |
199 } else { | |
10595
522afd56703c
100l to albeu for his english grammar, and 10l to me becouse I noticed that lately (my backward compatibilty macro uses M_OPT_UNKNOWN)
alex
parents:
10594
diff
changeset
|
200 tmp = M_OPT_UNKNOWN; |
21312 | 201 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_UnknownOptionOnCommandLine, opt); |
8164 | 202 } |
203 } | |
204 } | |
205 | |
16345
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
206 if (tmp <= M_OPT_EXIT) { |
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
207 opt_exit = 1; |
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
208 tmp = M_OPT_EXIT - tmp; |
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
209 } else |
9792 | 210 if (tmp < 0) { |
21312 | 211 mp_msg(MSGT_CFGPARSER, MSGL_FATAL, MSGTR_ErrorParsingOptionOnCommandLine, opt); |
8164 | 212 goto err_out; |
9792 | 213 } |
8164 | 214 i += tmp; |
215 } | |
216 else /* filename */ | |
217 { | |
29850
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
218 int is_dvdnav = strstr(argv[i],"dvdnav://") != NULL; |
8164 | 219 play_tree_t* entry = play_tree_new(); |
220 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Adding file %s\n",argv[i]); | |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
221 // if required expand DVD filename entries like dvd://1-3 into component titles |
29850
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
222 if ( strstr(argv[i],"dvd://") != NULL || is_dvdnav) |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
223 { |
29850
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
224 int offset = is_dvdnav ? 9 : 6; |
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
225 splitpos=strstr(argv[i]+offset,"-"); |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
226 if(splitpos != NULL) |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
227 { |
29850
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
228 start_title=strtol(argv[i]+offset,NULL,10); |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
229 if (start_title<0) { //entries like dvd://-2 start title implied 1 |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
230 end_title=abs(start_title); |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
231 start_title=1; |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
232 } else { |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
233 end_title=strtol(splitpos+1,NULL,10); |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
234 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
235 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
236 if (dvd_range(start_title) && dvd_range(end_title) && (start_title<end_title)) |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
237 { |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
238 for (j=start_title;j<=end_title;j++) |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
239 { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
240 if (j!=start_title) |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
241 entry=play_tree_new(); |
29850
93947ce0e2cb
Support the range syntax (like dvd://2-5) also for dvdnav.
reimar
parents:
29263
diff
changeset
|
242 snprintf(entbuf,sizeof(entbuf),is_dvdnav ? "dvdnav://%d" : "dvd://%d",j); |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
243 play_tree_add_file(entry,entbuf); |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
244 add_entry(&last_parent,&last_entry,entry); |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
245 last_entry = entry; |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
246 } |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
247 } else { |
21312 | 248 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_InvalidPlayEntry, argv[i]); |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
249 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
250 |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
251 } else { // dvd:// or dvd://x entry |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
252 play_tree_add_file(entry,argv[i]); |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
253 } |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
254 } else { |
8164 | 255 play_tree_add_file(entry,argv[i]); |
12543
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
256 } |
2cbc9f1f728f
Support dvd://start_title-end_title as requested on wishlist
rtognimp
parents:
12267
diff
changeset
|
257 |
8164 | 258 // Lock stdin if it will be used as input |
259 if(strcasecmp(argv[i],"-") == 0) | |
12816 | 260 m_config_set_option(config,"noconsolecontrols",NULL); |
10542
928c02fa9949
fix the bug where only the last file of the command line is found
pl
parents:
10513
diff
changeset
|
261 add_entry(&last_parent,&last_entry,entry); |
8164 | 262 UNSET_GLOBAL; // We start entry specific options |
263 | |
264 } | |
265 } | |
266 | |
16345
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
267 if (opt_exit) |
feb16d0117c8
allow multiple help clauses on the command line, Patch by kiriuja " mplayer-patches AH en-directo POUM net "
gpoirier
parents:
15742
diff
changeset
|
268 goto err_out; |
8164 | 269 --recursion_depth; |
270 if(last_parent != root) | |
271 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Missing }- ?\n"); | |
272 return root; | |
273 | |
274 err_out: | |
275 --recursion_depth; | |
276 play_tree_free(root,1); | |
277 return NULL; | |
278 } |