Skip to content

Commit

Permalink
[TOOS-4434] Add CUBRID exclusive SQL grammer to Free SQL Formatter
Browse files Browse the repository at this point in the history
**Purpose**
- Modify to support CUBRID exclusive grammars.
- Modify the makefile so that fsqlf only builds the CLI.

**Changes**
Add SQL statement
- LIMIT
- DIFFERENCE
- USING INDEX
- USING INDEX NONE
- USE | FORCE | IGNORE INDEX

Modify makefile
- GUI, test, build archive, installation, CMake remove
  • Loading branch information
Srltas authored Mar 8, 2023
2 parents 6ab8ec2 + 0c4b07f commit e1dd6b9
Show file tree
Hide file tree
Showing 37 changed files with 4,339 additions and 1,016 deletions.
82 changes: 48 additions & 34 deletions cli/cli.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#include <ctype.h> // isdigit
#include <stdlib.h> // exit
#include <stdio.h> // fprintf, stderr
#include <lib_fsqlf.h>
#include "../utils/string/read_int.h" // FSQLF_read_int
#include "cli.h"
#include "../lib_fsqlf/conf_file/conf_file_read.h"
#include "../lib_fsqlf/conf_file/conf_file_create.h"
#include "../lib_fsqlf/conf_file/conf_file_constants.h"
#include "../lib_fsqlf/kw/kwall_init.h" // set_case, set_text_original
#include "../lib_fsqlf/formatter/lex.yy.h"
#include "debuging.h"
#include "../utils/string/read_int.h" // read_int



Expand All @@ -27,9 +31,9 @@ static void usage_info(int argc, char **argv)
fprintf(stderr, "usage:\n" );
PRINT_OPTION_INFO( "fsqlf [<input_file>] [<output_file>] [options]",
"Read from <input_file> and write formatted output to <output_file> (use std I/O if missing)\n"
" If there are overlaping options set, then the last one (overlapping setting) wins.\n"
" If there are overlaping options set, then the last one (overflapping setting) wins.\n"
" e.g. If config file is set 2 times, then from 1st file use only configs that don't exist in the 2nd file.");
PRINT_OPTION_INFO( "fsqlf --create-config-file <conf_file>", "Create config file. (file is overwritten if already exists)");
PRINT_OPTION_INFO( "fsqlf --create-config-file", "(Re)create '" FSQLF_CONFFILE_NAME "' config file.");
fprintf(stderr, "options:\n");
PRINT_OPTION_INFO( "-i <input_file>" , "Use <input_file> as input");
PRINT_OPTION_INFO( "-o <output_file>" , "Use <output_file> as output");
Expand All @@ -43,6 +47,7 @@ static void usage_info(int argc, char **argv)
PRINT_OPTION_INFO( "--newline-major-sections <digit>" , "Put <digit> new lines before major sections (FROM, JOIN, WHERE)");
PRINT_OPTION_INFO( "--keyword-case (upper|lower|initcap|none)" , "Convert all keywords to UPPER, lower, or Initcap case, or not to convert case at all");
PRINT_OPTION_INFO( "--keyword-text (original|default)" , "Use original or programs default text for the keyword, when there are several alternatives");
PRINT_OPTION_INFO( "--debug (none|state|match|paranthesis)" , "Print info for debuging. To have different kinds of debug output, use more than once");
PRINT_OPTION_INFO( "--help, -h" , "Show this help.");
}

Expand All @@ -51,28 +56,24 @@ static void usage_info(int argc, char **argv)
static int get_int_arg(int i, int argc, char **argv)
{
int r;
if (!FSQLF_read_int(argv[i], 1000, &r)) {
if (!read_int(argv[i], 1000, &r)) {
FAIL_WITH_ERROR(1, "Missing or invalid value for option : %s", argv[i-1]);
}
return r;
}


void read_cli_options(struct fsqlf_kw_conf *kwall, int argc, char **argv,
FILE **fin, FILE **fout)
void read_cli_options(int argc, char **argv,
struct kw_conf * (*kw)(const char *), FILE ** fin, FILE ** fout)
{
int i;
if (argc == 1) return; // use stdin and stdout

if (argc == 2 && strcmp(argv[1], "--create-config-file") == 0) {
FAIL_WITH_ERROR(1, "Missing value for option : %s", argv[1]);
}
if (argc == 3 && strcmp(argv[1], "--create-config-file") == 0) {
if (fsqlf_kwmap_conffile_create(argv[2]) != FSQLF_OK) {
fprintf(stderr, "Problem occurred during creation of config file '%s'.\n", argv[2]);
if (create_conf_file(FSQLF_CONFFILE_NAME) != 0) {
exit(1);
} else {
fprintf(stderr, "Configuration was written to file '%s'.\n", argv[2]);
fprintf(stderr, "File '%s' (re)created.\n", FSQLF_CONFFILE_NAME);
exit(0);
}
}
Expand Down Expand Up @@ -100,52 +101,65 @@ void read_cli_options(struct fsqlf_kw_conf *kwall, int argc, char **argv,
if (!(*fout)) FAIL_WITH_ERROR(1, "Error opening output file: %s", argv[i]);
} else if (ARGV_MATCH(i, "--config-file")) {
if (++i >= argc) FAIL_WITH_ERROR(1, "Missing value for option : %s", argv[i-1]);
if (fsqlf_kwmap_conffile_read(kwall, argv[i]) == FSQLF_FAIL) {
FAIL_WITH_ERROR(1, "Error reading configuration file: %s", argv[i]);
if (read_conf_file(argv[i], kw) == READ_FAILED) {
FAIL_WITH_ERROR(1, "Error reading configureation file: %s", argv[i]);
}
} else if (ARGV_MATCH(i, "--select-comma-newline")) {
if (++i >= argc) FAIL_WITH_ERROR(1, "Missing value for option : %s", argv[i-1]);
if (strcmp(argv[i], "after") == 0) {
fsqlf_kw_get(kwall, "kw_comma")->before.new_line = 0;
fsqlf_kw_get(kwall, "kw_comma")->after.new_line = 1;
kw("kw_comma")->before.new_line = 0;
kw("kw_comma")->after.new_line = 1;
} else if (strcmp(argv[i], "before") == 0) {
fsqlf_kw_get(kwall, "kw_comma")->before.new_line = 1;
fsqlf_kw_get(kwall, "kw_comma")->after.new_line = 0;
kw("kw_comma")->before.new_line = 1;
kw("kw_comma")->after.new_line = 0;
} else if (strcmp(argv[i], "none") == 0) {
fsqlf_kw_get(kwall, "kw_comma")->before.new_line = 0;
fsqlf_kw_get(kwall, "kw_comma")->after.new_line = 0;
kw("kw_comma")->before.new_line = 0;
kw("kw_comma")->after.new_line = 0;
}
} else if (ARGV_MATCH(i, "--keyword-case")) {
if (++i >= argc) FAIL_WITH_ERROR(1, "Missing value for option : %s", argv[i-1]);
if (strcmp(argv[i], "none") == 0) {
fsqlf_kwmap_set_case(kwall, FSQLF_KWCASE_ORIGINAL);
set_case(CASE_none);
} else if (strcmp(argv[i], "upper") == 0) {
fsqlf_kwmap_set_case(kwall, FSQLF_KWCASE_UPPER);
set_case(CASE_UPPER);
} else if (strcmp(argv[i], "lower") == 0) {
fsqlf_kwmap_set_case(kwall, FSQLF_KWCASE_LOWER);
set_case(CASE_lower);
} else if (strcmp(argv[i], "initcap") == 0) {
fsqlf_kwmap_set_case(kwall, FSQLF_KWCASE_INITCAP);
set_case(CASE_Initcap);
}
} else if (ARGV_MATCH(i, "--keyword-text")) {
if (++i >= argc) FAIL_WITH_ERROR(1, "Missing value for option : %s", argv[i-1]);
if (strcmp(argv[i], "original") == 0) {
fsqlf_kwmap_set_spelling(kwall, FSQLF_KWSPELLING_USE_ORIGINAL);
set_text_original(1);
} else if (strcmp(argv[i], "default") == 0) {
fsqlf_kwmap_set_spelling(kwall, FSQLF_KWSPELLING_USE_HARDCODED_DEFAULT);
set_text_original(0);
}
} else if (ARGV_MATCH(i, "--select-newline-after")) {
fsqlf_kw_get(kwall, "kw_select")->after.new_line = get_int_arg(++i, argc, argv);
kw("kw_select")->after.new_line = get_int_arg(++i, argc, argv);
} else if (ARGV_MATCH(i, "--newline-or-before")) {
fsqlf_kw_get(kwall, "kw_or")->before.new_line = get_int_arg(++i, argc, argv);
kw("kw_or")->before.new_line = get_int_arg(++i, argc, argv);
} else if (ARGV_MATCH(i, "--newline-or-after")) {
fsqlf_kw_get(kwall, "kw_or")->after.new_line = get_int_arg(++i, argc, argv);
kw("kw_or")->after.new_line = get_int_arg(++i, argc, argv);
} else if (ARGV_MATCH(i, "--newline-and-before")) {
fsqlf_kw_get(kwall, "kw_and")->before.new_line = get_int_arg(++i, argc, argv);
kw("kw_and")->before.new_line = get_int_arg(++i, argc, argv);
} else if (ARGV_MATCH(i, "--newline-and-after")) {
fsqlf_kw_get(kwall, "kw_and")->after.new_line = get_int_arg(++i, argc, argv);
kw("kw_and")->after.new_line = get_int_arg(++i, argc, argv);
} else if (ARGV_MATCH(i, "--newline-major-sections")) {
int new_line_count = get_int_arg(++i, argc, argv);
fsqlf_kwmap_set_major_clause_nl(kwall, new_line_count);
kw("kw_from")->before.new_line = new_line_count;
kw("kw_where")->before.new_line = new_line_count;
kw("kw_inner_join")->before.new_line = new_line_count;
kw("kw_left_join")->before.new_line = new_line_count;
kw("kw_right_join")->before.new_line = new_line_count;
kw("kw_full_join")->before.new_line = new_line_count;
kw("kw_cross_join")->before.new_line = new_line_count;
} else if (ARGV_MATCH(i, "--debug")) {
if (++i >= argc ) FAIL_WITH_ERROR(1, "Missing or invalid value for option : %s", argv[i-1]);
if (ARGV_MATCH(i, "none")) debug_level |= DEBUGNONE;
else if (ARGV_MATCH(i, "state")) debug_level |= DEBUGSTATES;
else if (ARGV_MATCH(i, "match")) debug_level |= DEBUGMATCHES;
else if (ARGV_MATCH(i, "paranthesis")) debug_level |= DEBUGPARCOUNTS;
else FAIL_WITH_ERROR(1, "Missing or invalid value for option : %s", argv[i-1]);
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
usage_info(argc, argv);
exit(0);
Expand Down
6 changes: 3 additions & 3 deletions cli/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@


#include <stdio.h> // fprintf, FILE
#include <lib_fsqlf.h>
#include "../lib_fsqlf/kw/kw.h"


void read_cli_options(struct fsqlf_kw_conf *kwall, int argc, char **argv,
FILE **fin, FILE **fout);
void read_cli_options(int argc, char **argv,
struct kw_conf * (*kw)(const char *), FILE ** fin, FILE ** fout);


#endif
62 changes: 62 additions & 0 deletions cli/debuging.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "debuging.h"
#include "../lib_fsqlf/kw/kw.h"
#define YY_HEADER_EXPORT_START_CONDITIONS
#include "../lib_fsqlf/formatter/lex.yy.h"


int debug_level = DEBUGNONE ;//| DEBUGSTATES | DEBUGMATCHES;


void debug_p()
{
if (debug_level & DEBUGPARCOUNTS) {
printf("\n\t*** %s ***\n", dump_paranthesis_counts());
}
}


void debug_match(char * debugstring)
{
if (debug_level & DEBUGMATCHES) {
printf("\n\t** %s **\n", debugstring);
}
}


char *state_to_char(int state)
{
char* state_str;
switch (state) {
case INITIAL: state_str="INITIAL" ; break;
case stSELECT: state_str="stSELECT" ; break;
case stFROM: state_str="stFROM" ; break;
case stWHERE: state_str="stWHERE" ; break;
case stON: state_str="stON" ; break;
case stEXISTS: state_str="stEXISTS" ; break;
case stLEFTP: state_str="stLEFTP" ; break;
case stJOIN: state_str="stJOIN" ; break;
case stCOMMA: state_str="stCOMMA" ; break;
case stIN: state_str="stIN" ; break;
case stINLIST: state_str="stINLIST" ; break;
case stP_SUB: state_str="stP_SUB" ; break;
case stCOMMENTML: state_str="stCOMMENTML" ; break;
case stSTRING: state_str="stSTRING" ; break;
case stFROM_LEFTP: state_str="stFROM_LEFTP" ; break;
default: state_str="STATE NOT AVAILABLE";
}
return state_str;
}


void debug_stchange(int newstate_int)
{
char* currentstate = 0;
char* newstate;

// currentstate = state_to_char(YY_START); // FIXME: take YY_START param.
newstate = state_to_char(newstate_int);

if (debug_level & DEBUGSTATES) {
printf("\n\t* %s->%s *\n", currentstate,newstate);
}
}
23 changes: 23 additions & 0 deletions cli/debuging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef debuging_h
#define debuging_h


#define DEBUGNONE (0)
#define DEBUGSTATES (1)
#define DEBUGMATCHES (2)
#define DEBUGPARCOUNTS (4)


extern int debug_level;


void debug_p();

void debug_match(char * debugstring);

char *state_to_char(int state);

void debug_stchange(int newstate_int);


#endif
21 changes: 10 additions & 11 deletions cli/main.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
#include <lib_fsqlf.h>
#include "../lib_fsqlf/conf_file/conf_file_read.h" // read_default_conf_file
#include "../lib_fsqlf/kw/kwall_init.h" // init_all_settings
#include "../lib_fsqlf/kw/kw.h" // init_all_settings
#include "cli.h" // read_cli_options
#include "../lib_fsqlf/formatter/lex.yy.h" // yyin, yyout


int main(int argc, char **argv)
{
// Initialise with STD I/O (later can be changed by command line options).
FILE *fin, *fout;
fin = stdin;
fout = stdout;
fsqlf_kwmap_t kwmap;
yyin = stdin;
yyout = stdout;

fsqlf_kwmap_init(&kwmap); // Init default configs.
fsqlf_kwmap_conffile_read_default(kwmap); // Read configs from file.
read_cli_options(kwmap, argc, argv, &fin, &fout); // Read configs from command line.
init_all_settings(&kw); // Init default configs.
read_default_conf_file(&kw); // Read configs from file.
read_cli_options(argc, argv, &kw, &yyin, &yyout); // Read configs from command line.

fsqlf_format_file(kwmap, fin, fout);

fsqlf_kwmap_destroy(kwmap);
while (yylex() != 0) ;

return 0;
}
14 changes: 14 additions & 0 deletions lib_fsqlf/conf_file/conf_file_constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef CONF_FILE_CONSTANTS_H
#define CONF_FILE_CONSTANTS_H


#ifndef FSQLF_CONFFILE_NAME
#define FSQLF_CONFFILE_NAME "formatting.conf"
#endif

#ifndef FSQLF_CONFFILE_LINELENGTH
#define FSQLF_CONFFILE_LINELENGTH (100)
#endif


#endif
51 changes: 26 additions & 25 deletions lib_fsqlf/conf_file/conf_file_create.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
#include <stdio.h> // FILE, fprintf, fputs, fclose
#include <lib_fsqlf.h>
#include "conf_file_read.h"
#include "conf_file_constants.h"


// Create formatting configuration file with default content.
// TODO: write from kwmap instead of stuff from "../kw/kwmap_defaults.def"
enum fsqlf_status fsqlf_kwmap_conffile_create(char *config_file_name)
// Return values:
// 0 on success
// 1 on failure to open
// 2 on failure to close
int create_conf_file(char *config_file_name)
{
FILE *config_file;
config_file = fopen(config_file_name, "w");

if (!config_file) {
fprintf(stderr, "Failed to create '%s' file!\n", config_file_name);
return FSQLF_FAIL;
return 1;
}

fputs("# This file contains formatting (spacing) settings,\n", config_file);
Expand All @@ -36,42 +40,39 @@ enum fsqlf_status fsqlf_kwmap_conffile_create(char *config_file_name)
fputs("\n", config_file);
fputs("\n", config_file);

fputs("# space_after ------------------------------------------------------------+\n",config_file);
fputs("# tab_after -------------------------------------------------------+ |\n",config_file);
fputs("# new_line_after -------------------------------------------+ | |\n",config_file);
fputs("# global_indent_change_after-------------------------+ | | |\n",config_file);
fputs("# | | | |\n",config_file);
fputs("# space_before -------------------------------+ | | | |\n",config_file);
fputs("# tab_before --------------------------+ | | | | |\n",config_file);
fputs("# new_line_before --------------+ | | | | | |\n",config_file);
fputs("# global_indent_ | | | | | | |\n",config_file);
fputs("# _change_before --------+ | | | | | | |\n",config_file);
fputs("# | | | | | | | |\n",config_file);
fputs("# setting_name | | | | | | | |\n",config_file);
fputs("# space_after ----------------------------------------------+\n", config_file);
fputs("# tab_after -----------------------------------------+ |\n", config_file);
fputs("# new_line_after -----------------------------+ | |\n", config_file);
fputs("# space_before ------------------------+ | | |\n", config_file);
fputs("# tab_before -------------------+ | | | |\n", config_file);
fputs("# new_line_before -------+ | | | | |\n", config_file);
fputs("# | | | | | |\n", config_file);
fputs("# setting_name\n", config_file);
fputs("\n", config_file);

// Define macro to print one line containing config of single keyword
// and run it (via #include) for each keyword.
#define XMACRO(NAME, gib, nlb, tb, sb, gia, nla, ta, sa, ... ) \
fprintf(config_file, "%-24s %s %6s %6s %6s %6s %6s %6s %6s\n", \
#NAME, #gib, #nlb, #tb, #sb, #gia, #nla, #ta, #sa);
#include "../kw/kwmap_defaults.def"
#define XMACRO(NAME, nlb, tb, sb, nla, ta, sa, ... ) \
fprintf(config_file, "%-24s %s %6s %6s %6s %6s %6s\n", \
#NAME, #nlb, #tb, #sb, #nla, #ta, #sa);
#include "../kw/kw_defaults.def"
#undef XMACRO

fputs("\n\n", config_file);
fputs("# Some explanations regarding names (shortenings) used above:\n", config_file);
fputs("# - left_p = left parenthesis\n", config_file);
fputs("# - right_p = right parenthesis\n", config_file);
fputs("# - left_p = left paranthesis\n", config_file);
fputs("# - right_p = right paranthesis\n", config_file);
fputs("# - ins = insert\n", config_file);
fputs("# - sub = subquery\n", config_file);
fputs("# - grpby = group by\n", config_file);
fputs("# - ordby = order by\n", config_file);
fputs("# - fsqlf_kw_get = keyword (though for some reason it's used also for punctuation character..)\n", config_file);
fputs("# - kw = keyword (though for some reason it's used also for puntuantion character..)\n", config_file);
fputs("\n\n", config_file);

if (fclose(config_file) == 0) {
return FSQLF_OK;
return 0;
} else {
fprintf(stderr, "Failed to close '%s' file!\n", config_file_name);
return FSQLF_FAIL;
return 2;
}
}
Loading

0 comments on commit e1dd6b9

Please sign in to comment.