winlin

fix the conf_line bug of parse config directive.

@@ -154,8 +154,8 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire @@ -154,8 +154,8 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire
154 154
155 while (true) { 155 while (true) {
156 std::vector<string> args; 156 std::vector<string> args;
157 -  
158 - ret = read_token(buffer, args); 157 + int line_start = 0;
  158 + ret = read_token(buffer, args, line_start);
159 159
160 /** 160 /**
161 * ret maybe: 161 * ret maybe:
@@ -170,14 +170,14 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire @@ -170,14 +170,14 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire
170 } 170 }
171 if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) { 171 if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {
172 if (type != parse_block) { 172 if (type != parse_block) {
173 - srs_error("line %d: unexpected \"}\", ret=%d", buffer->line + 1, ret); 173 + srs_error("line %d: unexpected \"}\", ret=%d", buffer->line, ret);
174 return ret; 174 return ret;
175 } 175 }
176 return ERROR_SUCCESS; 176 return ERROR_SUCCESS;
177 } 177 }
178 if (ret == ERROR_SYSTEM_CONFIG_EOF) { 178 if (ret == ERROR_SYSTEM_CONFIG_EOF) {
179 if (type == parse_block) { 179 if (type == parse_block) {
180 - srs_error("line %d: unexpected end of file, expecting \"}\", ret=%d", conf_line + 1, ret); 180 + srs_error("line %d: unexpected end of file, expecting \"}\", ret=%d", conf_line, ret);
181 return ret; 181 return ret;
182 } 182 }
183 return ERROR_SUCCESS; 183 return ERROR_SUCCESS;
@@ -185,14 +185,14 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire @@ -185,14 +185,14 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire
185 185
186 if (args.empty()) { 186 if (args.empty()) {
187 ret = ERROR_SYSTEM_CONFIG_INVALID; 187 ret = ERROR_SYSTEM_CONFIG_INVALID;
188 - srs_error("line %d: empty directive. ret=%d", conf_line + 1, ret); 188 + srs_error("line %d: empty directive. ret=%d", conf_line, ret);
189 return ret; 189 return ret;
190 } 190 }
191 191
192 // build directive tree. 192 // build directive tree.
193 SrsConfDirective* directive = new SrsConfDirective(); 193 SrsConfDirective* directive = new SrsConfDirective();
194 194
195 - directive->conf_line = buffer->line; 195 + directive->conf_line = line_start;
196 directive->name = args[0]; 196 directive->name = args[0];
197 args.erase(args.begin()); 197 args.erase(args.begin());
198 directive->args.swap(args); 198 directive->args.swap(args);
@@ -210,7 +210,7 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire @@ -210,7 +210,7 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire
210 } 210 }
211 211
212 // see: ngx_conf_read_token 212 // see: ngx_conf_read_token
213 -int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector<string>& args) 213 +int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector<string>& args, int& line_start)
214 { 214 {
215 int ret = ERROR_SUCCESS; 215 int ret = ERROR_SUCCESS;
216 216
@@ -260,7 +260,7 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector< @@ -260,7 +260,7 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector<
260 if (ch == '{') { 260 if (ch == '{') {
261 return ERROR_SYSTEM_CONFIG_BLOCK_START; 261 return ERROR_SYSTEM_CONFIG_BLOCK_START;
262 } 262 }
263 - srs_error("line %d: unexpected '%c'", buffer->line + 1, ch); 263 + srs_error("line %d: unexpected '%c'", buffer->line, ch);
264 return ERROR_SYSTEM_CONFIG_INVALID; 264 return ERROR_SYSTEM_CONFIG_INVALID;
265 } 265 }
266 266
@@ -273,19 +273,19 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector< @@ -273,19 +273,19 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector<
273 switch (ch) { 273 switch (ch) {
274 case ';': 274 case ';':
275 if (args.size() == 0) { 275 if (args.size() == 0) {
276 - srs_error("line %d: unexpected ';'", buffer->line + 1); 276 + srs_error("line %d: unexpected ';'", buffer->line);
277 return ERROR_SYSTEM_CONFIG_INVALID; 277 return ERROR_SYSTEM_CONFIG_INVALID;
278 } 278 }
279 return ERROR_SYSTEM_CONFIG_DIRECTIVE; 279 return ERROR_SYSTEM_CONFIG_DIRECTIVE;
280 case '{': 280 case '{':
281 if (args.size() == 0) { 281 if (args.size() == 0) {
282 - srs_error("line %d: unexpected '{'", buffer->line + 1); 282 + srs_error("line %d: unexpected '{'", buffer->line);
283 return ERROR_SYSTEM_CONFIG_INVALID; 283 return ERROR_SYSTEM_CONFIG_INVALID;
284 } 284 }
285 return ERROR_SYSTEM_CONFIG_BLOCK_START; 285 return ERROR_SYSTEM_CONFIG_BLOCK_START;
286 case '}': 286 case '}':
287 if (args.size() != 0) { 287 if (args.size() != 0) {
288 - srs_error("line %d: unexpected '}'", buffer->line + 1); 288 + srs_error("line %d: unexpected '}'", buffer->line);
289 return ERROR_SYSTEM_CONFIG_INVALID; 289 return ERROR_SYSTEM_CONFIG_INVALID;
290 } 290 }
291 return ERROR_SYSTEM_CONFIG_BLOCK_END; 291 return ERROR_SYSTEM_CONFIG_BLOCK_END;
@@ -308,6 +308,10 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector< @@ -308,6 +308,10 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector<
308 } 308 }
309 } else { 309 } else {
310 // last charecter is not space 310 // last charecter is not space
  311 + if (line_start == 0) {
  312 + line_start = buffer->line;
  313 + }
  314 +
311 bool found = false; 315 bool found = false;
312 if (d_quoted) { 316 if (d_quoted) {
313 if (ch == '"') { 317 if (ch == '"') {
@@ -2847,7 +2851,7 @@ namespace _srs_internal @@ -2847,7 +2851,7 @@ namespace _srs_internal
2847 { 2851 {
2848 SrsConfigBuffer::SrsConfigBuffer() 2852 SrsConfigBuffer::SrsConfigBuffer()
2849 { 2853 {
2850 - line = 0; 2854 + line = 1;
2851 2855
2852 pos = last = start = NULL; 2856 pos = last = start = NULL;
2853 end = start; 2857 end = start;
@@ -215,9 +215,10 @@ private: @@ -215,9 +215,10 @@ private:
215 * read a token from buffer. 215 * read a token from buffer.
216 * a token, is the directive args and a flag indicates whether has child-directives. 216 * a token, is the directive args and a flag indicates whether has child-directives.
217 * @param args, the output directive args, the first is the directive name, left is the args. 217 * @param args, the output directive args, the first is the directive name, left is the args.
  218 + * @param line_start, the actual start line of directive.
218 * @return, an error code indicates error or has child-directives. 219 * @return, an error code indicates error or has child-directives.
219 */ 220 */
220 - virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector<std::string>& args); 221 + virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector<std::string>& args, int& line_start);
221 }; 222 };
222 223
223 /** 224 /**
@@ -663,3 +663,117 @@ VOID TEST(ConfigDirectiveTest, ParseInvalidEmptyDirective) @@ -663,3 +663,117 @@ VOID TEST(ConfigDirectiveTest, ParseInvalidEmptyDirective)
663 EXPECT_EQ(0, (int)dir0.args.size()); 663 EXPECT_EQ(0, (int)dir0.args.size());
664 EXPECT_EQ(0, (int)dir0.directives.size()); 664 EXPECT_EQ(0, (int)dir0.directives.size());
665 } 665 }
  666 +
  667 +VOID TEST(ConfigDirectiveTest, ParseLine)
  668 +{
  669 + MockSrsConfigBuffer buf("dir0 {}");
  670 + SrsConfDirective conf;
  671 + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf));
  672 + EXPECT_EQ(0, (int)conf.name.length());
  673 + EXPECT_EQ(0, (int)conf.args.size());
  674 + EXPECT_EQ(1, (int)conf.directives.size());
  675 +
  676 + SrsConfDirective& dir0 = *conf.directives.at(0);
  677 + EXPECT_STREQ("dir0", dir0.name.c_str());
  678 + EXPECT_EQ(0, (int)dir0.args.size());
  679 + EXPECT_EQ(0, (int)dir0.directives.size());
  680 + EXPECT_EQ(1, (int)dir0.conf_line);
  681 +}
  682 +
  683 +VOID TEST(ConfigDirectiveTest, ParseLine2)
  684 +{
  685 + MockSrsConfigBuffer buf("\n\ndir0 {}");
  686 + SrsConfDirective conf;
  687 + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf));
  688 + EXPECT_EQ(0, (int)conf.name.length());
  689 + EXPECT_EQ(0, (int)conf.args.size());
  690 + EXPECT_EQ(1, (int)conf.directives.size());
  691 +
  692 + SrsConfDirective& dir0 = *conf.directives.at(0);
  693 + EXPECT_STREQ("dir0", dir0.name.c_str());
  694 + EXPECT_EQ(0, (int)dir0.args.size());
  695 + EXPECT_EQ(0, (int)dir0.directives.size());
  696 + EXPECT_EQ(3, (int)dir0.conf_line);
  697 +}
  698 +
  699 +VOID TEST(ConfigDirectiveTest, ParseLine3)
  700 +{
  701 + MockSrsConfigBuffer buf("dir0 {\n\ndir1 arg0;}");
  702 + SrsConfDirective conf;
  703 + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf));
  704 + EXPECT_EQ(0, (int)conf.name.length());
  705 + EXPECT_EQ(0, (int)conf.args.size());
  706 + EXPECT_EQ(1, (int)conf.directives.size());
  707 +
  708 + SrsConfDirective& dir0 = *conf.directives.at(0);
  709 + EXPECT_STREQ("dir0", dir0.name.c_str());
  710 + EXPECT_EQ(0, (int)dir0.args.size());
  711 + EXPECT_EQ(1, (int)dir0.directives.size());
  712 + EXPECT_EQ(1, (int)dir0.conf_line);
  713 +
  714 + SrsConfDirective& dir1 = *dir0.directives.at(0);
  715 + EXPECT_STREQ("dir1", dir1.name.c_str());
  716 + EXPECT_EQ(1, (int)dir1.args.size());
  717 + EXPECT_STREQ("arg0", dir1.arg0().c_str());
  718 + EXPECT_EQ(0, (int)dir1.directives.size());
  719 + EXPECT_EQ(3, (int)dir1.conf_line);
  720 +}
  721 +
  722 +VOID TEST(ConfigDirectiveTest, ParseLine4)
  723 +{
  724 + MockSrsConfigBuffer buf("dir0 {\n\ndir1 \n\narg0;dir2 arg1;}");
  725 + SrsConfDirective conf;
  726 + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf));
  727 + EXPECT_EQ(0, (int)conf.name.length());
  728 + EXPECT_EQ(0, (int)conf.args.size());
  729 + EXPECT_EQ(1, (int)conf.directives.size());
  730 +
  731 + SrsConfDirective& dir0 = *conf.directives.at(0);
  732 + EXPECT_STREQ("dir0", dir0.name.c_str());
  733 + EXPECT_EQ(0, (int)dir0.args.size());
  734 + EXPECT_EQ(2, (int)dir0.directives.size());
  735 + EXPECT_EQ(1, (int)dir0.conf_line);
  736 +
  737 + SrsConfDirective& dir1 = *dir0.directives.at(0);
  738 + EXPECT_STREQ("dir1", dir1.name.c_str());
  739 + EXPECT_EQ(1, (int)dir1.args.size());
  740 + EXPECT_STREQ("arg0", dir1.arg0().c_str());
  741 + EXPECT_EQ(0, (int)dir1.directives.size());
  742 + EXPECT_EQ(3, (int)dir1.conf_line);
  743 +
  744 + SrsConfDirective& dir2 = *dir0.directives.at(1);
  745 + EXPECT_STREQ("dir2", dir2.name.c_str());
  746 + EXPECT_EQ(1, (int)dir2.args.size());
  747 + EXPECT_STREQ("arg1", dir2.arg0().c_str());
  748 + EXPECT_EQ(0, (int)dir2.directives.size());
  749 + EXPECT_EQ(5, (int)dir2.conf_line);
  750 +}
  751 +
  752 +VOID TEST(ConfigDirectiveTest, ParseLineNormal)
  753 +{
  754 + MockSrsConfigBuffer buf("dir0 {\ndir1 {\ndir2 arg2;\n}\n}");
  755 + SrsConfDirective conf;
  756 + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf));
  757 + EXPECT_EQ(0, (int)conf.name.length());
  758 + EXPECT_EQ(0, (int)conf.args.size());
  759 + EXPECT_EQ(1, (int)conf.directives.size());
  760 +
  761 + SrsConfDirective& dir0 = *conf.directives.at(0);
  762 + EXPECT_STREQ("dir0", dir0.name.c_str());
  763 + EXPECT_EQ(0, (int)dir0.args.size());
  764 + EXPECT_EQ(1, (int)dir0.directives.size());
  765 + EXPECT_EQ(1, (int)dir0.conf_line);
  766 +
  767 + SrsConfDirective& dir1 = *dir0.directives.at(0);
  768 + EXPECT_STREQ("dir1", dir1.name.c_str());
  769 + EXPECT_EQ(0, (int)dir1.args.size());
  770 + EXPECT_EQ(1, (int)dir1.directives.size());
  771 + EXPECT_EQ(2, (int)dir1.conf_line);
  772 +
  773 + SrsConfDirective& dir2 = *dir1.directives.at(0);
  774 + EXPECT_STREQ("dir2", dir2.name.c_str());
  775 + EXPECT_EQ(1, (int)dir2.args.size());
  776 + EXPECT_STREQ("arg2", dir2.arg0().c_str());
  777 + EXPECT_EQ(0, (int)dir2.directives.size());
  778 + EXPECT_EQ(3, (int)dir2.conf_line);
  779 +}