-
Notifications
You must be signed in to change notification settings - Fork 110
Added parse_ini_string, parse_ini_file functions #690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2cddd23
cc4451d
7bacc62
077bee1
4e12b32
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| #include "ini.h" | ||
|
|
||
| /* | ||
| * INI parsing functions | ||
| */ | ||
|
|
||
| const int64_t SINGLE_QOUTES = 0; | ||
| const int64_t DOUBLE_QUOTES = 1; | ||
| const int64_t ALL_QUOTES = 2; | ||
|
|
||
| string clear_quotes(const string &str, int64_t flag) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The variable named Then the function declaration will look like this: string clear_quotes(const string &str, qoutes_type_t quotes_type); |
||
| if (str.empty()) { | ||
| return {}; | ||
| } | ||
|
|
||
| Optional<string> clear_str; | ||
|
|
||
| switch (flag) { | ||
| case SINGLE_QOUTES: | ||
| clear_str = f$preg_replace(string("/'+/"), string(""), str); | ||
| break; | ||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| case DOUBLE_QUOTES: | ||
| clear_str = f$preg_replace(string("/\"+/"), string(""), str); | ||
| break; | ||
| case ALL_QUOTES: | ||
| clear_str = f$preg_replace(string("/['|\"]+/"), string(""), str); | ||
| break; | ||
| } | ||
|
|
||
| if (clear_str.is_null()) { | ||
| return string(""); | ||
| } | ||
|
|
||
| return clear_str.ref(); | ||
| } | ||
|
|
||
| string clear_extra_spaces(const string &str) { | ||
| if (str.empty()) { | ||
| return {}; | ||
| } | ||
|
|
||
| Optional<string> clear_str; | ||
|
|
||
| clear_str = f$preg_replace(string("/ +/"), string(" "), str); | ||
|
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case, it's better to take advantage of the opportunities that auto clear_str = f$preg_replace(string("/ +/"), string(" "), str); |
||
|
|
||
| if (clear_str.is_null()) { | ||
| return string(""); | ||
| } | ||
|
|
||
| return clear_str.ref(); | ||
| } | ||
|
|
||
| /* | ||
| * INI parsing functions | ||
| */ | ||
|
|
||
| bool is_ini_section(const string &ini_section) { | ||
| return f$preg_match(string("/^\\[.+\\]$/"), ini_section).val(); | ||
| } | ||
|
|
||
| bool is_ini_var(const string &ini_var) { | ||
| return f$preg_match(string("/^.+/"), ini_var).val(); | ||
| } | ||
|
|
||
| bool is_ini_val(const string &ini_val) { | ||
| return f$preg_match(string("/(.*\n(?=[A-Z])|.*$)/"), ini_val).val(); | ||
| } | ||
|
|
||
| bool is_ini_bool_val(const string &ini_val) { | ||
| return f$preg_match(string("/^(false|true|0|1|off|on)$/i"), ini_val).val(); | ||
| } | ||
|
|
||
| bool is_ini_float_val(const string &ini_val) { | ||
| return f$preg_match(string(R"(/^\d+\.\d*$/)"), ini_val).val(); | ||
| } | ||
|
|
||
| bool is_ini_str_val(const string &ini_val) { | ||
| return f$preg_match(string("/^.*$/i"), ini_val).val(); | ||
| } | ||
|
|
||
| string get_ini_section(const string &ini_entry) { | ||
| if (ini_entry.empty()) { | ||
| return {}; | ||
| } | ||
|
|
||
| return ini_entry.substr(1, ini_entry.size()-2); | ||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| array<string> split_ini_entry(const string &ini_entry) { | ||
| if (ini_entry.empty()) { | ||
| return {}; | ||
| } | ||
|
|
||
| array<string> res = f$explode(string("="), ini_entry, 2); | ||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (res.size().int_size != 2) { | ||
| php_warning("Error"); | ||
| return {}; | ||
| } | ||
|
|
||
| return res; | ||
| } | ||
|
|
||
| bool cast_str_to_bool(const string &ini_var) { | ||
| if (ini_var.empty()) { | ||
| return false; | ||
| } | ||
|
|
||
| string ini_bool_var = f$strtolower(ini_var); | ||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (ini_bool_var == string("on") || ini_bool_var == string("1") || ini_bool_var == string("true")) { | ||
| return true; | ||
| } | ||
|
|
||
| if (ini_bool_var == string("off") || ini_bool_var == string("0") || ini_bool_var == string("false")) { | ||
| return false; | ||
| } | ||
|
|
||
| return false; | ||
|
Comment on lines
+115
to
+119
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant condition. |
||
| } | ||
|
|
||
| array<mixed> f$parse_ini_string(const string &ini_string, bool process_sections, int scanner_mode) { | ||
| if (ini_string.empty()) { | ||
| return {}; | ||
| } | ||
|
|
||
| string ini_string_copy = f$trim(ini_string); | ||
| ini_string_copy = clear_extra_spaces(ini_string_copy); | ||
|
|
||
| array<mixed> res(array_size(0, 0, true)); | ||
| array<mixed> section(array_size(0, 0, true)); | ||
| string ini_entry; | ||
| string ini_section; | ||
|
|
||
| for (string::size_type i = 0; i <= ini_string_copy.size(); ++i) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Firstly, also it's better to use for (string::size_type i = 0; i < ini_string_copy.size(); ++i) {
...
}
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Thanks, you're right. |
||
| if (ini_string_copy[i] == '[') { | ||
| while (ini_string_copy[i] != ']') { | ||
| ini_entry.push_back(ini_string_copy[i]); | ||
| ++i; | ||
| } | ||
| } | ||
|
|
||
| if (ini_string_copy[i] == '\"' || ini_string_copy[i] == '\'') { | ||
| ini_entry.push_back(ini_string_copy[i]); | ||
|
|
||
| ++i; | ||
| while (ini_string_copy[i] != '\"' && ini_string_copy[i] != '\'') { | ||
| ini_entry.push_back(ini_string_copy[i]); | ||
| ++i; | ||
| } | ||
| } | ||
|
|
||
| if (ini_string_copy[i] == ' ' || ini_string_copy[i] == '\n' || ini_string_copy[i] == '\0') { | ||
| if (is_ini_section(ini_entry)) { | ||
| if (process_sections && !ini_section.empty()) { | ||
| res.set_value(ini_section, section); | ||
| section.clear(); | ||
| } | ||
|
|
||
| ini_section = get_ini_section(ini_entry); | ||
| } else if (!ini_entry.empty()){ | ||
| array<string> ini = split_ini_entry(ini_entry); | ||
|
|
||
| if (ini.size().int_size != 2) { | ||
| php_warning("Invalid ini string format %s", ini_entry.c_str()); | ||
| return {}; | ||
| } | ||
|
|
||
| string ini_var = ini[0]; | ||
| string ini_val = ini[1]; | ||
|
|
||
| if (!is_ini_var(ini_var) && !is_ini_val(ini_val)) { | ||
| php_warning("Invalid ini string format %s", ini_entry.c_str()); | ||
| return {}; | ||
| } | ||
|
|
||
| if (!ini_var.empty()) { | ||
| switch (scanner_mode) { | ||
| case INI_SCANNER_NORMAL: | ||
| if (is_ini_bool_val(ini_val)) { | ||
| section.set_value(ini_var, cast_str_to_bool(ini_val) ? string("1") : string("")); | ||
| } else if (is_ini_str_val(ini_val)) { | ||
| section.set_value(ini_var, clear_quotes(ini_val, ALL_QUOTES)); | ||
| } | ||
| break; | ||
| case INI_SCANNER_RAW: | ||
| if (is_ini_str_val(ini_val)) { | ||
| section.set_value(ini_var, clear_quotes(ini_val, DOUBLE_QUOTES)); | ||
| } else { | ||
| section.set_value(ini_var, ini_val); | ||
| } | ||
| break; | ||
| case INI_SCANNER_TYPED: | ||
| if (ini_val.is_int()) { | ||
| section.set_value(ini_var, ini_val.to_int()); | ||
| } else if (is_ini_float_val(ini_val)) { | ||
| section.set_value(ini_var, ini_val.to_float()); | ||
| } else if (is_ini_bool_val(ini_val)) { | ||
| section.set_value(ini_var, cast_str_to_bool(ini_val)); | ||
| } else if (is_ini_str_val(ini_val)) { | ||
| section.set_value(ini_var, clear_quotes(ini_val, ALL_QUOTES)); | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| ini_entry = {}; | ||
| } else { | ||
| ini_entry.push_back(ini_string_copy[i]); | ||
| } | ||
| } | ||
|
|
||
| if (process_sections) { | ||
| if (!ini_section.empty()) { | ||
| res.set_value(ini_section, section); | ||
| } | ||
| } else { | ||
| return section; | ||
| } | ||
|
|
||
| return res; | ||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
|
|
||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| array<mixed> f$parse_ini_file(const string &filename, bool process_sections, int scanner_mode) { | ||
| if (filename.empty()) { | ||
| php_warning("Filename cannot be empty"); | ||
| return {}; | ||
| } | ||
|
|
||
| Optional<string> ini_string = f$file_get_contents(filename); | ||
pmswga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (ini_string.is_null()) { | ||
| return {}; | ||
| } | ||
|
|
||
| return f$parse_ini_string(ini_string.ref(), process_sections, scanner_mode); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| #pragma once | ||
|
|
||
| #include "runtime/kphp_core.h" | ||
| #include "runtime/string_functions.h" | ||
| #include "runtime/array_functions.h" | ||
| #include "runtime/streams.h" | ||
| #include "runtime/regexp.h" | ||
|
|
||
| const int INI_SCANNER_NORMAL = 0; | ||
| const int INI_SCANNER_RAW = 1; | ||
| const int INI_SCANNER_TYPED = 2; | ||
|
|
||
| array<mixed> f$parse_ini_string(const string &ini_string, bool process_sections = false, int scanner_mode = 0); | ||
|
|
||
| array<mixed> f$parse_ini_file(const string &filename, bool process_sections = false, int scanner_mode = 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, it's better to use
enum.