Skip to content

Commit 7b27ad5

Browse files
Improve Java interface (#69)
1 parent 4dc2311 commit 7b27ad5

23 files changed

+853
-83
lines changed

cobj/codegen.c

Lines changed: 174 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4150,6 +4150,113 @@ joutput_initial_values (struct cb_field *p)
41504150
}
41514151
}
41524152

4153+
struct call_parameter_list {
4154+
struct call_paramter_list* next;
4155+
struct cb_field* field;
4156+
cb_tree x;
4157+
};
4158+
struct call_parameter_list* call_parameter_cache = NULL;
4159+
4160+
static void
4161+
joutput_java_entrypoint (struct cb_program *prog, cb_tree parameter_list)
4162+
{
4163+
cb_tree l;
4164+
struct cb_field *f;
4165+
char arg_field_name[COB_SMALL_BUFF];
4166+
4167+
joutput_prefix();
4168+
joutput ("CobolResultSet execute (");
4169+
4170+
int k;
4171+
for (l = parameter_list; l; l = CB_CHAIN (l)) {
4172+
struct cb_field* arg_field = cb_field (CB_VALUE (l));
4173+
int type = cb_tree_type(CB_TREE(arg_field));
4174+
char* field_name = get_java_identifier_field(arg_field);
4175+
get_java_identifier_helper(arg_field, arg_field_name);
4176+
if(type & COB_TYPE_NUMERIC) {
4177+
if(arg_field->pic->scale > 0) {
4178+
joutput("double");
4179+
} else {
4180+
joutput("int");
4181+
}
4182+
} else {
4183+
joutput("String");
4184+
}
4185+
joutput(" %s", arg_field_name);
4186+
if(CB_CHAIN(l)) {
4187+
joutput(", ");
4188+
}
4189+
4190+
struct call_parameter_list* call_parameter = malloc(sizeof(struct call_parameter_list));
4191+
call_parameter->next = call_parameter_cache;
4192+
call_parameter->field = arg_field;
4193+
call_parameter->x = CB_VALUE (l);
4194+
call_parameter_cache = call_parameter;
4195+
}
4196+
4197+
joutput(") {\n");
4198+
joutput_indent_level += 2;
4199+
4200+
for (l = parameter_list; l; l = CB_CHAIN (l)) {
4201+
struct cb_field* arg_field = cb_field (CB_VALUE (l));
4202+
char* field_name = get_java_identifier_field(arg_field);
4203+
char* base_name = get_java_identifier_base(arg_field);
4204+
get_java_identifier_helper(arg_field, arg_field_name);
4205+
joutput_line("this.%s.setDataStorage(new CobolDataStorage(%d));",
4206+
field_name,
4207+
arg_field->size
4208+
);
4209+
joutput_line("this.%s.moveFrom(%s);",
4210+
field_name,
4211+
arg_field_name);
4212+
joutput_line("this.%s = this.%s.getDataStorage();", base_name, field_name);
4213+
free(field_name);
4214+
free(base_name);
4215+
}
4216+
4217+
joutput_line("int returnCode = run_module(0);", prog->program_id);
4218+
4219+
joutput_prefix();
4220+
joutput("return new CobolResultSet(returnCode");
4221+
if(parameter_list) {
4222+
joutput(",\n");
4223+
joutput_indent_level += 2;
4224+
for (l = parameter_list; l; l = CB_CHAIN (l)) {
4225+
struct cb_field* arg_field = cb_field (CB_VALUE (l));
4226+
char* field_name = get_java_identifier_field(arg_field);
4227+
int type = cb_tree_type(CB_TREE(arg_field));
4228+
joutput_prefix();
4229+
const char* constructor;
4230+
const char* getter;
4231+
if(type & COB_TYPE_NUMERIC) {
4232+
if(arg_field->pic->scale > 0) {
4233+
constructor = "CobolResultDouble";
4234+
getter = "getDouble";
4235+
} else {
4236+
constructor = "CobolResultInt";
4237+
getter = "getInt";
4238+
}
4239+
} else {
4240+
constructor = "CobolResultString";
4241+
getter = "getString";
4242+
}
4243+
joutput("new %s(%s.%s())",
4244+
constructor,
4245+
field_name,
4246+
getter
4247+
);
4248+
joutput(CB_CHAIN(l) ? ",\n" : "\n");
4249+
free(field_name);
4250+
}
4251+
joutput_indent_level -= 2;
4252+
joutput_prefix();
4253+
}
4254+
4255+
joutput(");\n");
4256+
joutput_indent_level -= 2;
4257+
joutput_line("}\n");
4258+
}
4259+
41534260
static void
41544261
joutput_internal_function (struct cb_program *prog, cb_tree parameter_list)
41554262
{
@@ -4193,9 +4300,13 @@ joutput_internal_function (struct cb_program *prog, cb_tree parameter_list)
41934300
parmnum++;
41944301
}
41954302
}
4196-
4303+
joutput_line("return this.run_module(entry);");
4304+
joutput_indent_level -=2;
4305+
joutput_line("}");
41974306
joutput("\n");
41984307

4308+
joutput_line ("int run_module (int entry) {");
4309+
joutput_indent_level += 2;
41994310
//if (!prog->flag_chained) {
42004311
// for (l = parameter_list; l; l = CB_CHAIN (l)) {
42014312
// joutput_line ("if (fields.length > %d) {", parmnum);
@@ -4939,23 +5050,54 @@ void joutput_init_method(struct cb_program *prog) {
49395050

49405051
joutput_prefix();
49415052
char* field_name = get_java_identifier_field(k->f);
4942-
joutput ("%s\t= ", field_name);
4943-
free(field_name);
5053+
49445054
if (!k->f->flag_local && !k->f->flag_item_external) {
5055+
joutput ("%s\t= ", field_name);
49455056
joutput_field (k->x);
49465057
} else {
5058+
joutput ("%s\t= ", field_name);
49475059
joutput ("CobolFieldFactory.makeCobolField(");
49485060
joutput_size (k->x);
4949-
joutput (", (CobolDataStorage)null, ");
5061+
joutput(", (CobolDataStorage)null, ");
49505062
joutput_attr (k->x);
49515063
joutput (")");
49525064
}
5065+
5066+
free(field_name);
49535067
joutput (";\t/* %s */\n", k->f->name);
49545068
}
49555069
joutput("\n");
49565070
joutput_line ("/* End of fields */\n\n");
49575071
}
49585072

5073+
if(call_parameter_cache) {
5074+
joutput_line("/* Call parameters */");
5075+
struct call_parameter_list* l;
5076+
for(l = call_parameter_cache; l; l=l->next) {
5077+
int cached = 0;
5078+
char* call_parameter_field_name = get_java_identifier_field(l->field);
5079+
if(field_cache) {
5080+
struct field_list* f;
5081+
for(f = field_cache; f; f=f->next) {
5082+
char* field_name = get_java_identifier_field(f->f);
5083+
if(f->f == l->field && strcmp(call_parameter_field_name, field_name) == 0) {
5084+
cached = 1;
5085+
free(field_name);
5086+
break;
5087+
}
5088+
free(field_name);
5089+
}
5090+
}
5091+
if(!cached) {
5092+
joutput_prefix();
5093+
joutput("%s = CobolFieldFactory.makeCobolField(", call_parameter_field_name);
5094+
joutput("%d, (CobolDataStorage)null, ", l->field->size);
5095+
joutput_attr (l->x);
5096+
joutput (");\n");
5097+
}
5098+
free(call_parameter_field_name);
5099+
}
5100+
}
49595101

49605102
/* AbstractCobolField型変数の初期化(定数) */
49615103
if (literal_cache) {
@@ -5308,13 +5450,6 @@ void joutput_declare_member_variables(struct cb_program *prog, cb_tree parameter
53085450
joutput_line ("/* End of data storage */\n\n");
53095451
}
53105452

5311-
joutput_line("/* Call parameters */");
5312-
for (l = parameter_list; l; l = CB_CHAIN (l)) {
5313-
char* base_name = get_java_identifier_base(cb_field (CB_VALUE (l)));
5314-
joutput_line("private CobolDataStorage %s;", base_name);
5315-
free(base_name);
5316-
}
5317-
53185453
/* Dangling linkage section items */
53195454
int seen = 0;
53205455
for (f = prog->linkage_storage; f; f = f->sister) {
@@ -5408,6 +5543,32 @@ void joutput_declare_member_variables(struct cb_program *prog, cb_tree parameter
54085543
joutput_line ("private CobolFieldAttribute %s%d;",
54095544
CB_PREFIX_ATTR, j->id);
54105545
}
5546+
joutput("\n");
5547+
}
5548+
5549+
if(call_parameter_cache) {
5550+
joutput_line("/* Call parameters */");
5551+
struct call_parameter_list* l;
5552+
for(l = call_parameter_cache; l; l=l->next) {
5553+
int cached = 0;
5554+
if(field_cache) {
5555+
struct field_list* f;
5556+
for(f = field_cache; f; f=f->next) {
5557+
if(f->f == l->field) {
5558+
cached = 1;
5559+
break;
5560+
}
5561+
}
5562+
}
5563+
if(!cached) {
5564+
char* field_name = get_java_identifier_field(l->field);
5565+
joutput_line("private AbstractCobolField %s;", field_name);
5566+
free(field_name);
5567+
}
5568+
char* base_name = get_java_identifier_base(l->field);
5569+
joutput_line("private CobolDataStorage %s;", base_name);
5570+
free(base_name);
5571+
}
54115572
}
54125573

54135574
joutput("\n");
@@ -5770,6 +5931,7 @@ codegen (struct cb_program *prog, const int nested, char** program_id_list)
57705931
joutput_line("import jp.osscons.opensourcecobol.libcobj.termio.*;");
57715932
joutput_line("import jp.osscons.opensourcecobol.libcobj.call.*;");
57725933
joutput_line("import jp.osscons.opensourcecobol.libcobj.file.*;");
5934+
joutput_line("import jp.osscons.opensourcecobol.libcobj.ui.*;");
57735935
joutput_line("import java.util.Optional;");
57745936
joutput("\n");
57755937

@@ -5830,6 +5992,7 @@ codegen (struct cb_program *prog, const int nested, char** program_id_list)
58305992
//}
58315993

58325994
create_label_id_map(prog);
5995+
joutput_java_entrypoint(prog, prog->parameter_list);
58335996
joutput_internal_function (prog, prog->parameter_list);
58345997

58355998
joutput_execution_list(prog);

libcobj/Makefile.am

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ SRC_FILES = \
6161
./src/jp/osscons/opensourcecobol/libcobj/file/CobolSequentialFile.java \
6262
./src/jp/osscons/opensourcecobol/libcobj/file/FileStruct.java \
6363
./src/jp/osscons/opensourcecobol/libcobj/file/KeyComponent.java \
64-
./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java
64+
./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java \
65+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java \
66+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java \
67+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java \
68+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java \
69+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java \
70+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java
6571

6672
all: libcobj.jar
6773

libcobj/Makefile.in

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,13 @@ SRC_FILES = \
339339
./src/jp/osscons/opensourcecobol/libcobj/file/CobolSequentialFile.java \
340340
./src/jp/osscons/opensourcecobol/libcobj/file/FileStruct.java \
341341
./src/jp/osscons/opensourcecobol/libcobj/file/KeyComponent.java \
342-
./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java
342+
./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java \
343+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java \
344+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java \
345+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java \
346+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java \
347+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java \
348+
./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java
343349

344350
all: all-am
345351

libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.math.BigDecimal;
2222
import java.nio.ByteBuffer;
23+
import java.nio.charset.Charset;
2324
import jp.osscons.opensourcecobol.libcobj.common.CobolConstant;
2425
import jp.osscons.opensourcecobol.libcobj.common.CobolModule;
2526
import jp.osscons.opensourcecobol.libcobj.common.CobolUtil;
@@ -163,7 +164,13 @@ public int getInt() {
163164
/**
164165
* @return
165166
*/
166-
public abstract double getDouble();
167+
public double getDouble() {
168+
try {
169+
return Double.parseDouble(this.getString());
170+
} catch (Exception e) {
171+
return 0;
172+
}
173+
}
167174

168175
/**
169176
* 数値を表すデータが実装すべきメソッド. 保持する数値データをCobolDecimal型に変換する.
@@ -585,19 +592,87 @@ protected void moveFromAll(AbstractCobolField src) {
585592
*
586593
* @param field 代入元のデータ(String型)
587594
*/
588-
public abstract void moveFrom(String string);
595+
public void moveFrom(String s) {
596+
// The maximum number of digits of int type in decimal is 10
597+
598+
byte[] bytes = s.getBytes(Charset.forName("SJIS"));
599+
600+
CobolDataStorage storage = new CobolDataStorage(bytes.length);
601+
storage.memcpy(bytes);
602+
603+
CobolFieldAttribute attr =
604+
new CobolFieldAttribute(
605+
CobolFieldAttribute.COB_TYPE_ALPHANUMERIC,
606+
bytes.length,
607+
0,
608+
0,
609+
String.format("X(%d)", bytes.length));
610+
611+
AbstractCobolField tmp = CobolFieldFactory.makeCobolField(bytes.length, storage, attr);
612+
this.moveFrom(tmp);
613+
}
589614
/**
590615
* 引数で与えらえられたデータからthisへの代入を行う
591616
*
592617
* @param field 代入元のデータ(int型)
593618
*/
594-
public abstract void moveFrom(int number);
619+
public void moveFrom(int number) {
620+
// The maximum number of digits of int type in decimal is 10
621+
final int length = 10;
622+
623+
CobolDataStorage storage = new CobolDataStorage(length);
624+
String formatted_number_string = String.format("%10d", Math.abs(number));
625+
storage.memcpy(formatted_number_string, length);
626+
if (number < 0) {
627+
storage.setByte(length - 1, (byte) (storage.getByte(length - 1) + 0x40));
628+
}
629+
630+
CobolFieldAttribute attr =
631+
new CobolFieldAttribute(
632+
CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY,
633+
length,
634+
0,
635+
CobolFieldAttribute.COB_FLAG_HAVE_SIGN,
636+
"S9(10)");
637+
638+
AbstractCobolField tmp = CobolFieldFactory.makeCobolField(length, storage, attr);
639+
this.moveFrom(tmp);
640+
}
595641
/**
596642
* 引数で与えらえられたデータからthisへの代入を行う
597643
*
598644
* @param field 代入元のデータ(double型)
599645
*/
600-
public abstract void moveFrom(double number);
646+
public void moveFrom(double number) {
647+
String s = Double.toString(Math.abs(number));
648+
String ss;
649+
int scale;
650+
ss = s.replace("+", "").replace("-", "");
651+
int pointIndex = ss.indexOf('.');
652+
if (pointIndex < 0) {
653+
scale = 0;
654+
} else {
655+
scale = ss.length() - 1 - pointIndex;
656+
ss = ss.replace(".", "");
657+
}
658+
659+
CobolDataStorage storage = new CobolDataStorage(ss.length());
660+
storage.memcpy(ss, ss.length());
661+
662+
CobolFieldAttribute attr =
663+
new CobolFieldAttribute(
664+
CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY,
665+
ss.length(),
666+
scale,
667+
CobolFieldAttribute.COB_FLAG_HAVE_SIGN,
668+
"");
669+
670+
AbstractCobolField tmp = CobolFieldFactory.makeCobolField(ss.length(), storage, attr);
671+
if (number < 0) {
672+
tmp.putSign(-1);
673+
}
674+
this.moveFrom(tmp);
675+
}
601676
/**
602677
* 引数で与えらえられたデータからthisへの代入を行う
603678
*

0 commit comments

Comments
 (0)