diff --git a/Makefile b/Makefile index 573f8fa..2eb527b 100644 --- a/Makefile +++ b/Makefile @@ -24,16 +24,19 @@ include config.mk include oapi-cli.mk -main.c: osc-api.json call_list arguments-list.json config.sh main_tpl.c cognac_gen.sh mk_args.c.sh +bin/line_check: bin/line_check.c + $(CC) -O3 bin/line_check.c -o bin/line_check + +main.c: bin/line_check osc-api.json call_list arguments-list.json config.sh main_tpl.c cognac_gen.sh mk_args.c.sh ./cognac_gen.sh main_tpl.c main.c c -osc_sdk.c: osc-api.json call_list arguments-list.json config.sh lib.c cognac_gen.sh construct_data.c.sh mk_args.c.sh +osc_sdk.c: bin/line_check osc-api.json call_list arguments-list.json config.sh lib.c cognac_gen.sh construct_data.c.sh mk_args.c.sh ./cognac_gen.sh lib.c osc_sdk.c c -osc_sdk.h: osc-api.json call_list arguments-list.json config.sh lib.h cognac_gen.sh mk_args.c.sh +osc_sdk.h: bin/line_check osc-api.json call_list arguments-list.json config.sh lib.h cognac_gen.sh mk_args.c.sh ./cognac_gen.sh lib.h osc_sdk.h c -oapi-cli-completion.bash: osc-api.json call_list arguments-list.json config.sh oapi-cli-completion-tpl.bash cognac_gen.sh +oapi-cli-completion.bash: bin/line_check osc-api.json call_list arguments-list.json config.sh oapi-cli-completion-tpl.bash cognac_gen.sh ./cognac_gen.sh oapi-cli-completion-tpl.bash oapi-cli-completion.bash bash config.sh: @@ -55,7 +58,7 @@ call_list: osc-api.json clean: - rm -vf osc-api.json call_list osc_sdk.c arguments-list.json osc_sdk.h main.c oapi-cli config.sh oapi-cli-completion.bash + rm -vf osc-api.json call_list osc_sdk.c arguments-list.json osc_sdk.h main.c oapi-cli config.sh oapi-cli-completion.bash bin/line_check .PHONY: clean list_api_version help diff --git a/bin/line_check.c b/bin/line_check.c new file mode 100644 index 0000000..997f88c --- /dev/null +++ b/bin/line_check.c @@ -0,0 +1,34 @@ +#include +#include +#include + +#define BUF_SIZE 2048 + +int main(int ac, char **av) { + + char buf[BUF_SIZE]; + size_t s; + static int bufs_cnt[256]; + int i, j; + + if (ac > 254) { + return -1; + } + + while ((s = read(0, buf, BUF_SIZE)) > 0) { + for (i = 0; i < s; ++i) { + for (j = 1; j < ac; ++j) { + if (!av[j][bufs_cnt[j]]) { + printf("%s\n", av[j]); + return 0; + } + if (av[j][bufs_cnt[j]] == buf[i]) + ++bufs_cnt[j]; + else + bufs_cnt[j] = 0; + } + } + } + + return -1; +} diff --git a/cognac_gen.sh b/cognac_gen.sh index 4725368..342372d 100755 --- a/cognac_gen.sh +++ b/cognac_gen.sh @@ -23,7 +23,7 @@ dash_this_arg() cur="$cur.$arg" if [ "ref" == $( echo "$t" | cut -d ' ' -f 1) ]; then local st=$( echo $t | cut -f 2 -d ' ' ) - local st_info=$(jq .components.schemas.$st <<< $OSC_API_JSON) + local st_info=$(jq .components.schemas.$st < osc-api.json) local st_args=$(json-search -K properties <<< "$st_info"- | tr -d '"[],') for st_arg in $st_args; do @@ -43,7 +43,7 @@ dash_this() if [ "ref" == $( echo "$t" | cut -d ' ' -f 1) ]; then local st=$( echo $t | cut -f 2 -d ' ' ) - local st_info=$(jq .components.schemas.$st <<< $OSC_API_JSON) + local st_info=$(jq .components.schemas.$st < osc-api.json) local st_args=$(json-search -K properties <<< "$st_info"- | tr -d '"[],') for st_arg in $st_args; do @@ -95,15 +95,39 @@ EOF elif [ 'array integer' == "$type" -o 'array string' == "$type" -o 'array double' == "$type" ]; then - convertor="" + local convertor="" + local null_val='""' if [ 'array integer' == "$type" ]; then convertor=atoi + null_val=0 elif [ 'array double' == "$type" ]; then convertor=atof + null_val=0.0 fi cat <${snake_a}_str = aa; +${indent_plus} if (aret == '.') { +${indent_plus} int pos; +${indent_plus} char *endptr; +${indent_plus} int last = 0; +${indent_plus} char *dot_pos = strchr(str, '.'); + +${indent_plus} TRY(!(dot_pos++), "$a argument missing\n"); +${indent_plus} pos = strtoul(dot_pos, &endptr, 0); +${indent_plus} TRY(endptr == dot_pos, "$a require an index\n"); +${indent_plus} if (s->${snake_a}) { +${indent_plus} for (; s->${snake_a}[last]; ++last); +${indent_plus} } +${indent_plus} if (pos < last) { +${indent_plus} s->${snake_a}[pos] = ${convertor}(aa); +${indent_plus} } else { +${indent_plus} for (int i = last; i < pos; ++i) +${indent_plus} SET_NEXT(s->${snake_a}, $null_val, pa); +${indent_plus} SET_NEXT(s->${snake_a}, ${convertor}(aa), pa); +${indent_plus} } +${indent_plus} } else { +${indent_plus} TRY(!aa, "$a argument missing\n"); +${indent_plus} s->${snake_a}_str = aa; +${indent_plus} } $indent_base } else if (!(aret = strcmp(str, "$a[]")) || aret == '=') { ${indent_plus} TRY(!aa, "$a[] argument missing\n"); ${indent_plus} SET_NEXT(s->${snake_a}, ${convertor}(aa), pa); @@ -174,55 +198,39 @@ EOF replace_args() { - API_VERSION=$(json-search -R version <<< $OSC_API_JSON) + API_VERSION=$(json-search -R version < osc-api.json) SDK_VERSION=$(cat sdk-version) while IFS= read -r line do #check ____args____ here - grep ____args____ <<< "$line" > /dev/null - have_args=$? - grep ____func_code____ <<< "$line" > /dev/null - have_func_code=$? - grep ____functions_proto____ <<< "$line" > /dev/null - have_func_protos=$? - grep ____cli_parser____ <<< "$line" > /dev/null - have_cli_parser=$? - grep ____complex_struct_func_parser____ <<< "$line" > /dev/null - have_complex_struct_func_parser=$? - grep ____complex_struct_to_string_func____ <<< "$line" > /dev/null - have_complex_struct_to_string_func=$? - grep ____call_list_dec____ <<< "$line" > /dev/null - have_call_list_dec=$? - grep ____call_list_descriptions____ <<< "$line" > /dev/null - have_call_list_descr=$? - grep ____call_list_args_descriptions____ <<< "$line" > /dev/null - have_call_list_arg_descr=$? - - if [ $have_args == 0 ]; then + + arg_check=$(bin/line_check ____args____ ____func_code____ ____functions_proto____ ____cli_parser____ ____complex_struct_func_parser____ ____complex_struct_to_string_func____ ____call_list_dec____ ____call_list_descriptions____ ____call_list_args_descriptions____ <<< "$line") + + if [ "$arg_check" == "____args____" ]; then ./mk_args.${lang}.sh - elif [ $have_call_list_descr == 0 ]; then + elif [ "$arg_check" == "____call_list_descriptions____" ]; then DELIMES=$(cut -d '(' -f 2 <<< $line | tr -d ')') D1=$(cut -d ';' -f 1 <<< $DELIMES | tr -d "'") D2=$(cut -d ';' -f 2 <<< $DELIMES | tr -d "'") D3=$(cut -d ';' -f 3 <<< $DELIMES | tr -d "'") for x in $CALL_LIST ; do echo -en $D1 - local required=$(echo $OSC_API_JSON | json-search ${x}Request | json-search required 2>&1 | tr -d '[]\n"' | tr -s ' ' | sed 's/nothing found//g') + local required=$(json-search ${x}Request < osc-api.json | json-search required 2>&1 | tr -d '[]\n"' | tr -s ' ' | sed 's/nothing found//g') local usage_required=$( for a in $(echo $required | tr -d ','); do echo -n " --${a}=${a,,}"; done ) local usage="\"Usage: oapi-cli $x ${usage_required} [OPTIONS]\n\"" - local call_desc=$(echo $OSC_API_JSON | jq .paths.\""/$x"\".description | sed 's/
//g' | tr -d '"' | fold -s | sed 's/^/"/;s/$/\\n"/') + local call_desc=$(jq .paths.\""/$x"\".description < osc-api.json | sed 's/
//g' | tr -d '"' | fold -s | sed 's/^/"/;s/$/\\n"/') echo $usage $call_desc \""\nRequired Argument:" $required "\n\"" echo -en $D2 done echo -ne $D3 - elif [ $have_call_list_arg_descr == 0 ]; then + elif [ "$arg_check" == "____call_list_args_descriptions____" ]; then DELIMES=$(cut -d '(' -f 2 <<< $line | tr -d ')') D1=$(cut -d ';' -f 1 <<< $DELIMES | tr -d "'") D2=$(cut -d ';' -f 2 <<< $DELIMES | tr -d "'") D3=$(cut -d ';' -f 3 <<< $DELIMES | tr -d "'") for x in $CALL_LIST ; do - st_info=$(json-search -s ${x}Request ./osc-api.json) + st_info=$(json-search -s ${x}Request < osc-api.json) A_LST=$(json-search -K properties <<< $st_info | tr -d '",[]') echo -en $D1 @@ -235,7 +243,7 @@ replace_args() echo -en $D2 done echo -ne $D3 - elif [ $have_call_list_dec == 0 ]; then + elif [ "$arg_check" == "____call_list_dec____" ]; then DELIMES=$(cut -d '(' -f 2 <<< $line | tr -d ')') D1=$(cut -d ';' -f 1 <<< $DELIMES | tr -d "'") D2=$(cut -d ';' -f 2 <<< $DELIMES | tr -d "'") @@ -246,36 +254,45 @@ replace_args() echo -en $D2 done echo -ne $D3 - elif [ $have_complex_struct_to_string_func == 0 ]; then - COMPLEX_STRUCT=$(jq .components <<< $OSC_API_JSON | json-search -KR schemas | tr -d '"' | sed 's/,/\n/g' | grep -v Response | grep -v Request) + elif [ "$arg_check" == "____complex_struct_to_string_func____" ]; then + COMPLEX_STRUCT=$(jq .components < osc-api.json | json-search -KR schemas | tr -d '"' | sed 's/,/\n/g' | grep -v Response | grep -v Request) for s in $COMPLEX_STRUCT; do struct_name=$(to_snakecase <<< $s) - echo "static int ${struct_name}_setter(struct ${struct_name} *args, struct osc_str *data);" + A_LST=$(jq .components.schemas.$s < osc-api.json | json-search -Kn properties | tr -d '",[]') + if [ "$A_LST" != "null" ]; then + echo "static int ${struct_name}_setter(struct ${struct_name} *args, struct osc_str *data);" + fi done for s in $COMPLEX_STRUCT; do struct_name=$(to_snakecase <<< $s) - cat < /dev/null <<< $arg_info) + local have_direct_ref=$? + if [ $have_direct_ref == 0 -a "$direct_ref" != 'null' ]; then + ref_path=$(cut -c 2- <<< $direct_ref | sed 's|/|.|g') + local direct_ref_properties=$(jq $ref_path.properties < osc-api.json 2> /dev/null) + if [ "$direct_ref_properties" == 'null' ]; then + arg_info="$(jq $ref_path < osc-api.json)" + fi + fi local types=$(jq -r .type 2> /dev/null <<< $arg_info) local have_type=$? local one_of=$(jq -r .oneOf 2> /dev/null <<< $arg_info) @@ -36,7 +45,17 @@ get_type_direct() { elif [ "$sub_type" == 'number' ]; then types="array double" elif [ "$sub_type" == 'null' ]; then - types="array ref $(json-search -R '$ref' <<< ${arg_info} | cut -d '/' -f 4)" + local osub_ref=$(json-search -R '$ref' <<< ${arg_info}) + local sub_ref=$(cut -d '/' -f 4 <<< $osub_ref 2> /dev/null) + local sub_ref_properties=$(jq $osub_ref.properties < osc-api.json 2> /dev/null) + osub_ref=$(cut -c 2- <<< $osub_ref | sed 's|/|.|g') + if [ "$sub_ref_properties" == '' ]; then + local arg_info="$(jq $osub_ref < osc-api.json)" + local dtypes=$(json-search $limit -R type 2> /dev/null <<< $arg_info) + types="array $dtypes" + else + types="array ref $sub_ref" + fi else types="array ${sub_type}" fi @@ -62,23 +81,26 @@ get_type3() { get_type2() { struct="$1" arg="$2" - st_info=$(jq .components.schemas.$struct <<< $OSC_API_JSON) + st_info=$(jq .components.schemas.$struct < osc-api.json) get_type3 "$st_info" "$arg" } get_type_description_() { - echo "$1" | jq .properties.$2.description + jq .properties.$2.description <<< "$1" } get_sub_type_description() { - local st_info=$(jq .components.schemas.$1 <<< $OSC_API_JSON) - echo $st_info | jq .description | fold -s -w64 | sed "s/^/${2}/" - local properties=$(json-search -K properties <<< $st_info | tr -d '"[],') + local st_info=$(jq .components.schemas.$1 < osc-api.json) + jq .description <<< $st_info | fold -s -w74 | sed "s/^/${2}/" + local properties=$(json-search -Kn properties <<< $st_info | tr -d '"[],') local o_type="$4" - #echo $properties + if [ "$properties" == "null" ]; then + return + fi for p in $properties; do local properties=$(json-search $p <<< $st_info) + local desc=$(jq .description <<< $properties) local type=$(get_type_direct "$properties") local show_idx="" @@ -88,7 +110,7 @@ get_sub_type_description() { fi echo "${2}--${3}.${show_idx}$p: $type" if [ "$desc" != "null" ]; then - echo $desc | fold -s -w74 | sed "s/^/${2} /" + fold -s -w74 <<< $desc | sed "s/^/${2} /" fi local sub=$(json-search -R '$ref' <<< $properties 2>&1 ) if [ "$sub" != 'null' -a "$sub" != "nothing found" ]; then @@ -108,7 +130,7 @@ get_type_description() { echo $desc fi if [ "$ref" != "null" -a "$ref" != "nothing found" ]; then - local sub_type=$(echo "$1" | jq .properties.$2 | json-search -R '$ref' | cut -d '/' -f 4) + local sub_type=$(jq .properties.$2 <<< "$1" | json-search -R '$ref' | cut -d '/' -f 4) local o_type=$(get_type3 "$1" "$2") get_sub_type_description "$sub_type" " " "$2" "$o_type" fi @@ -117,7 +139,18 @@ get_type_description() { get_type() { x=$2 func=$1 - local arg_info=$(json-search ${func}Request <<< $OSC_API_JSON | json-search $x) + local arg_info=$(json-search ${func}Request < osc-api.json | json-search $x) + local direct_ref=$(jq -r '.["$ref"]' 2> /dev/null <<< $arg_info) + local have_direct_ref=$? + if [ $have_direct_ref == 0 -a "$direct_ref" != 'null' ]; then + ref_path=$(cut -c 2- <<< $direct_ref | sed 's|/|.|g') + local direct_ref_properties=$(jq $ref_path.properties < osc-api.json 2> /dev/null) + if [ "$direct_ref_properties" == 'null' ]; then + arg_info="$(jq $ref_path < osc-api.json)" + fi + fi + + local one_of=$(jq -r .oneOf 2> /dev/null <<< $arg_info) local have_one_of=$? local limit="" @@ -137,11 +170,20 @@ get_type() { echo bool return 0 elif [ "$types" == 'array' ]; then - sub_ref=$(json-search -R '$ref' <<< ${arg_info} | cut -d '/' -f 4 2> /dev/null) - have_sref=$? + local osub_ref=$(json-search -R '$ref' <<< ${arg_info}) + local have_sref=$? + local sub_ref=$(cut -d '/' -f 4 <<< $osub_ref 2> /dev/null) + osub_ref=$(cut -c 2- <<< $osub_ref | sed 's|/|.|g') if [ $have_sref == 0 ]; then - types="array ref $sub_ref" + local sub_ref_properties=$(jq $osub_ref.properties < osc-api.json 2> /dev/null) + if [ "$sub_ref_properties" == '' ]; then + local arg_info="$(jq $osub_ref < osc-api.json)" + local dtypes=$(json-search $limit -R type 2> /dev/null <<< $arg_info) + types="array $dtypes" + else + types="array ref $sub_ref" + fi fi fi echo $types diff --git a/main-helper.h b/main-helper.h index d1f1ddb..52662a1 100644 --- a/main-helper.h +++ b/main-helper.h @@ -34,10 +34,18 @@ struct ptr_array { } \ } while (0) +/* + * use to be sizeof v, but if I pass "" to SET_NEXT, sizeof v is 1, and I expect + * char *, + * because the array can contain int and double too, I'll gowith allocated the + * biggerst size for all + */ +#define OBJ_SIZE 8 + #define SET_NEXT(a,v,pa) do { \ int cnt; \ if (!a) { \ - a = calloc(64, sizeof(v)); \ + a = calloc(64, OBJ_SIZE); \ if (!a) break; \ if (ptr_array_append(pa, a) < 0) \ break; \ @@ -45,10 +53,10 @@ struct ptr_array { for (cnt = 0; a[cnt]; ++cnt); \ if (cnt && (cnt % 63) == 0) { \ int idx = ptr_array_get_idx(pa, a); \ - pa->ptrs[idx] = realloc(a, (cnt + 1 + 64) * sizeof(v)); \ + pa->ptrs[idx] = realloc(a, (cnt + 1 + 64) * OBJ_SIZE); \ if (!pa->ptrs[idx]) { free(a); break; } \ a = pa->ptrs[idx]; \ - memset(a + cnt + 1, 0, 64 * sizeof(v)); \ + memset(a + cnt + 1, 0, 64 * OBJ_SIZE); \ } \ a[cnt] = v; \ } while (0) diff --git a/mk_args.c.sh b/mk_args.c.sh index 46ad031..611b7d2 100755 --- a/mk_args.c.sh +++ b/mk_args.c.sh @@ -7,13 +7,12 @@ source "./helper.sh" CALL_LIST_FILE=./call_list CALL_LIST=$(cat $CALL_LIST_FILE) -COMPLEX_STRUCT=$(jq .components <<< $OSC_API_JSON | json-search -KR schemas | tr -d '"' | sed 's/,/\n/g' | grep -v Response | grep -v Request) +COMPLEX_STRUCT=$(jq .components < osc-api.json | json-search -KR schemas | tr -d '"' | sed 's/,/\n/g' | grep -v Response | grep -v Request) type_to_ctype() { local t="$1" local snake_name="$2" local c_type="char *" - local oref="$t" if [ "$t" == 'int' -o "$t" == 'bool' -o "$t" == 'double' ]; then snake_name=$( if [ "default" == "$snake_name" ] ; then echo default_arg; else echo $snake_name; fi ) @@ -32,20 +31,24 @@ type_to_ctype() { elif [ "$t" == 'array string' ]; then echo " char *${snake_name}_str;" c_type="char **" - elif [ "ref" == $( echo "$t" | cut -d ' ' -f 1) ]; then - echo " char *${snake_name}_str;" - echo " int is_set_${snake_name};" - t=$( echo $t | cut -f 2 -d ' ' ) + elif [ "ref" == $( cut -d ' ' -f 1 <<< "$t") ]; then + cat << EOF + char *${snake_name}_str; + int is_set_${snake_name}; +EOF + t=$( cut -f 2 -d ' ' <<< $t ) c_type="struct $(to_snakecase <<< $t) " - elif [ "array" == $( echo "$t" | cut -d ' ' -f 1) ]; then - if [ "ref" == $( echo "$t" | cut -d ' ' -f 2) ]; then - t=$( echo $t | cut -f 3 -d ' ' ) - echo " char *${snake_name}_str;" - echo " int nb_${snake_name};" + elif [ "array" == $( cut -d ' ' -f 1 <<< $t) ]; then + if [ "ref" == $( cut -d ' ' -f 2 <<< $t) ]; then + t=$( cut -f 3 -d ' ' <<< $t ) + cat << EOF + char *${snake_name}_str; + int nb_${snake_name}; +EOF c_type="struct $(to_snakecase <<< $t) *" fi fi - echo " ${c_type}${snake_name}; /* $oref */" + echo " ${c_type}${snake_name};" } write_struct() { @@ -54,7 +57,7 @@ write_struct() { local A_LST="$3" if [ "$st_info" == "" ]; then - st_info=$(jq .components.schemas.$s0 <<< $OSC_API_JSON) + st_info=$(jq .components.schemas.$s0 < osc-api.json) A_LST=$(json-search -K properties <<< $st_info | tr -d '",[]') fi @@ -76,18 +79,23 @@ write_struct() { create_struct() { #for s in "skip"; do local s="$1" - local st0_info=$(jq .components.schemas.$s <<< $OSC_API_JSON) - local A0_LST=$(json-search -K properties <<< $st0_info | tr -d '",[]') + local st0_info=$(jq .components.schemas.$s < osc-api.json) + local A0_LST=$(json-search -Kn properties <<< $st0_info | tr -d '",[]') if [ "${structs[$s]}" != "" ]; then return fi + + if [ "$A0_LST" == "null" ]; then + return + fi structs["$s"]="is_set" + for a in $A0_LST; do local t=$(get_type3 "$st0_info" "$a") - if [ "ref" == "$( echo $t | cut -d ' ' -f 1)" ]; then - local sst=$( echo $t | cut -f 2 -d ' ' ) + if [ "ref" == "$( cut -d ' ' -f 1 <<< $t)" ]; then + local sst=$( cut -f 2 -d ' ' <<< $t ) local check="${structs[$sst]}" if [ "$check" == "" ]; then @@ -106,14 +114,13 @@ for s in $COMPLEX_STRUCT; do done for l in $CALL_LIST ;do -#for l in UpdateImage; do snake_l=$(to_snakecase <<< $l) - request=$(json-search -s ${l}Request ./osc-api.json) - ARGS_LIST=$(echo $request | json-search -KR "properties" | tr -d '"' | sed 's/,/\n/g') + request=$(json-search -s ${l}Request < osc-api.json) + ARGS_LIST=$(json-search -KR "properties" <<< $request | tr -d '"' | sed 's/,/\n/g') echo "struct osc_${snake_l}_arg {" echo -n " /* Required:" - echo $request | json-search required 2>&1 | tr -d "[]\"\n" | tr -s ' ' | sed 's/nothing found/none/g' | to_snakecase + json-search required 2>&1 <<< $request | tr -d "[]\"\n" | tr -s ' ' | sed 's/nothing found/none/g' | to_snakecase echo " */" for x in $ARGS_LIST ;do