Repository: ossrs/srs
File: trunk/src/app/srs_app_config.cpp (C++)

Code before:
            
            srs_freep(err);
            return srs_success;
        }
        
        if (args.empty()) {
            return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: empty directive", conf_line);
        }
        
        // build directive tree.
        if (args.at(0) == "include") {
            if (args.size() < 2) {
                return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: include is empty directive", buffer->line);
            }

            for (int i = 1; i < (int)args.size(); i++) {
                std::string file = args.at(i);

                srs_trace("config parse include %s", file.c_str());
                srs_freep(err);
                if (type != parse_block) {
                    if ((err = conf->parse_include_file(file.c_str())) != srs_success) {
                        return srs_error_wrap(err, "parse file");
                    }
                } else {
                    if (file.empty()) {
                        return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "empty include config");
                    }

                    SrsConfigBuffer* config_buffer = conf->get_buffer_from_include_file(file.c_str());

                    if(config_buffer == NULL) {
                        return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "empty include config");
                    } else {
                        if ((err = parse_conf(config_buffer, parse_file, conf)) != srs_success) {
                            srs_freep(config_buffer);

                            return srs_error_wrap(err, "parse include buffer");
                        }
                    }
                    srs_freep(config_buffer);
                }
            }
        } else {
            SrsConfDirective* directive = new SrsConfDirective();

            directive->conf_line = line_start;
            directive->name = args[0];
            args.erase(args.begin());
            directive->args.swap(args);


Review comment (suggestion):
This error check should be moved up a bit, this is how you are currently doing it: 

```c++
    if (args.at(0) == "include") {
            for (int i = 1; i < (int)args.size(); i++) {
                std::string file = args.at(i);
                if (type != parse_block) {
                    if ((err = conf->parse_include_file(file.c_str())) != srs_success) {
                } else {
                    if (file.empty()) {
                        // error
```

And in `parse_include_file`, you checked the `file` parameter again, returning an error if it is empty. It should have been checked together earlier.

```c++
    if (args.at(0) == "include") {
            for (int i = 1; i < (int)args.size(); i++) {
                std::string file = args.at(i);
                if (file.empty()) {
                    // error
                }

                if (type != parse_block) {
                    if ((err = conf->parse_include_file(file.c_str())) != srs_success) {
                } else {
```

Not only is it repetitive, but it also leads to an additional level of nesting.

`TRANS_BY_GPT3`

Code after:

            if (state == SrsDirectiveStateBlockStart) {
                if ((err = directive->parse_conf(buffer, SrsDirectiveContextBlock, conf)) != srs_success) {
                    return srs_error_wrap(err, "parse dir");
                }
            }
            continue;
        }

        // Parse including, allow multiple files.
        vector<string> files(args.begin() + 1, args.end());
        if (files.empty()) {
            return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: include is empty directive", buffer->line);
        }
        if (!conf) {
            return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: no config", buffer->line);
        }

        for (int i = 0; i < (int)files.size(); i++) {
            std::string file = files.at(i);
            srs_assert(!file.empty());
            srs_trace("config parse include %s", file.c_str());

            SrsConfigBuffer* include_file_buffer = NULL;
            SrsAutoFree(SrsConfigBuffer, include_file_buffer);
            if ((err = conf->build_buffer(file, &include_file_buffer)) != srs_success) {
                return srs_error_wrap(err, "buffer fullfill %s", file.c_str());
            }

            if ((err = parse_conf(include_file_buffer, SrsDirectiveContextFile, conf)) != srs_success) {
                return srs_error_wrap(err, "parse include buffer");
            }
        }
    }
    
    return err;
}

// see: ngx_conf_read_token
srs_error_t SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector<string>& args, int& line_start, SrsDirectiveState& state)
{
    srs_error_t err = srs_success;
    
    char* pstart = buffer->pos;
    
    bool sharp_comment = false;
    
    bool d_quoted = false;
    bool s_quoted = false;
    
    bool need_space = false;