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

Code before:
        
        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);

            directives.push_back(directive);

            if (srs_error_code(err) == ERROR_SYSTEM_CONFIG_BLOCK_START) {
                srs_freep(err);

Review comment (performance):
This place, do not use this kind of release method that is prone to problems, but should be changed to:

```c++
SrsConfigBuffer* config_buffer = conf->get_buffer_from_include_file(file.c_str());
SrsAutoFree(SrsConfigBuffer, config_buffer);

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) {
        return srs_error_wrap(err, "parse include buffer");
    }
}
```

Take a look and see if it's super simple, it won't release repeatedly, and it won't cause memory leaks.

`TRANS_BY_GPT3`

Code after:
                }
            }
            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;
    bool last_space = true;
    
    while (true) {
        if (buffer->empty()) {