Mercurial > mplayer.hg
annotate parser-cfg.c @ 11619:179138947307
This patch contains bugfixes for the esd audio output driver that I
uncovered while trying to send sound to a remote esd server over a
wireless (11 mbs, just enough to handle to sound) link.
First, the sound was full "ticking" sounds. I found a bug that
prevented the "send the remainder of this block" code from ever being
called - so large chunks of audio were simply being ignored. Fixing
this bug removed the "ticking" from audio streams.
Fixing this bug, however, uncovered another problem - when the socket
buffer was full, doing a blocking write to finish the buffer would take
far too long and would turn video into a chunky mess. I'd imagine this
blocking write would be fine for an audio-only stream, but it turns out
to hold up the video far too much.
The solution in this patch is to write as much data as possible to the
socket, and then return as soon as possible, reporting the number of
bytes actually written accurately back to mplayer. I've tested it on
both local and remote esd servers, and it works well.
Patch by Benjamin Osheroff <ben@gimbo.net>
author | attila |
---|---|
date | Wed, 10 Dec 2003 12:19:13 +0000 |
parents | 522afd56703c |
children | e632b43f0598 |
rev | line source |
---|---|
8164 | 1 #include "config.h" |
2 | |
3 #include <stdio.h> | |
4 #include <stdlib.h> | |
5 #include <string.h> | |
6 #include <errno.h> | |
7 #include <ctype.h> | |
8 | |
9 #ifdef MP_DEBUG | |
10 #include <assert.h> | |
11 #endif | |
12 | |
13 #include "mp_msg.h" | |
14 #include "m_option.h" | |
15 #include "m_config.h" | |
16 | |
17 #define MAX_RECURSION_DEPTH 8 | |
18 | |
19 static int recursion_depth = 0; | |
20 | |
21 int m_config_parse_config_file(m_config_t* config, char *conffile) | |
22 { | |
23 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num) | |
9813 | 24 #define MAX_LINE_LEN 10000 |
25 #define MAX_OPT_LEN 1000 | |
26 #define MAX_PARAM_LEN 1000 | |
8164 | 27 FILE *fp; |
28 char *line; | |
29 char opt[MAX_OPT_LEN + 1]; | |
30 char param[MAX_PARAM_LEN + 1]; | |
31 char c; /* for the "" and '' check */ | |
32 int tmp; | |
33 int line_num = 0; | |
34 int line_pos; /* line pos */ | |
35 int opt_pos; /* opt pos */ | |
36 int param_pos; /* param pos */ | |
37 int ret = 1; | |
38 int errors = 0; | |
39 int prev_mode = config->mode; | |
40 | |
41 #ifdef MP_DEBUG | |
42 assert(config != NULL); | |
43 // assert(conf_list != NULL); | |
44 #endif | |
45 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"Reading config file %s", conffile); | |
46 | |
47 if (recursion_depth > MAX_RECURSION_DEPTH) { | |
48 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); | |
49 ret = -1; | |
50 goto out; | |
51 } else | |
52 | |
53 config->mode = M_CONFIG_FILE; | |
54 | |
55 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { | |
56 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); | |
57 ret = -1; | |
58 goto out; | |
59 } | |
60 | |
61 if ((fp = fopen(conffile, "r")) == NULL) { | |
62 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": %s\n", strerror(errno)); | |
63 free(line); | |
64 ret = 0; | |
65 goto out; | |
66 } | |
67 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"\n"); | |
68 | |
69 while (fgets(line, MAX_LINE_LEN, fp)) { | |
70 if (errors >= 16) { | |
71 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
72 goto out; | |
73 } | |
74 | |
75 line_num++; | |
76 line_pos = 0; | |
77 | |
78 /* skip whitespaces */ | |
79 while (isspace(line[line_pos])) | |
80 ++line_pos; | |
81 | |
82 /* EOL / comment */ | |
83 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
84 continue; | |
85 | |
86 /* read option. */ | |
87 for (opt_pos = 0; isprint(line[line_pos]) && | |
88 line[line_pos] != ' ' && | |
89 line[line_pos] != '#' && | |
90 line[line_pos] != '='; /* NOTHING */) { | |
91 opt[opt_pos++] = line[line_pos++]; | |
92 if (opt_pos >= MAX_OPT_LEN) { | |
93 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
94 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 95 errors++; |
96 ret = -1; | |
97 goto nextline; | |
98 } | |
99 } | |
100 if (opt_pos == 0) { | |
101 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
102 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 103 ret = -1; |
104 errors++; | |
105 continue; | |
106 } | |
107 opt[opt_pos] = '\0'; | |
108 | |
109 #ifdef MP_DEBUG | |
110 PRINT_LINENUM; | |
111 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
112 #endif | |
113 | |
114 /* skip whitespaces */ | |
115 while (isspace(line[line_pos])) | |
116 ++line_pos; | |
117 | |
118 /* check '=' */ | |
119 if (line[line_pos++] != '=') { | |
120 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
121 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 122 ret = -1; |
123 errors++; | |
124 continue; | |
125 } | |
126 | |
127 /* whitespaces... */ | |
128 while (isspace(line[line_pos])) | |
129 ++line_pos; | |
130 | |
131 /* read the parameter */ | |
132 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
133 c = line[line_pos]; | |
134 ++line_pos; | |
135 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
136 param[param_pos++] = line[line_pos++]; | |
137 if (param_pos >= MAX_PARAM_LEN) { | |
138 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
139 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 140 ret = -1; |
141 errors++; | |
142 goto nextline; | |
143 } | |
144 } | |
145 line_pos++; /* skip the closing " or ' */ | |
146 } else { | |
147 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
148 && line[line_pos] != '#'; /* NOTHING */) { | |
149 param[param_pos++] = line[line_pos++]; | |
150 if (param_pos >= MAX_PARAM_LEN) { | |
151 PRINT_LINENUM; | |
152 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
153 ret = -1; | |
154 errors++; | |
155 goto nextline; | |
156 } | |
157 } | |
158 } | |
159 param[param_pos] = '\0'; | |
160 | |
161 /* did we read a parameter? */ | |
162 if (param_pos == 0) { | |
163 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
164 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 165 ret = -1; |
166 errors++; | |
167 continue; | |
168 } | |
169 | |
170 #ifdef MP_DEBUG | |
171 PRINT_LINENUM; | |
172 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
173 #endif | |
174 | |
175 /* now, check if we have some more chars on the line */ | |
176 /* whitespace... */ | |
177 while (isspace(line[line_pos])) | |
178 ++line_pos; | |
179 | |
180 /* EOL / comment */ | |
181 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
182 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
183 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 184 ret = -1; |
185 } | |
186 | |
187 tmp = m_config_set_option(config, opt, param); | |
188 if (tmp < 0) { | |
189 PRINT_LINENUM; | |
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
|
190 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
191 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"Warning unknown option %s at line %d\n", opt,line_num); |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
192 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
193 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
194 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 195 ret = -1; |
196 errors++; | |
197 continue; | |
198 /* break */ | |
199 } | |
200 nextline: | |
201 ; | |
202 } | |
203 | |
204 free(line); | |
205 fclose(fp); | |
206 out: | |
207 config->mode = prev_mode; | |
208 --recursion_depth; | |
209 return ret; | |
210 } |