Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cobj/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -4622,6 +4622,7 @@ static void joutput_internal_function(struct cb_program *prog,

joutput_line("/* Push module stack */");
joutput_line("CobolModule.push (module);");
joutput_line("CobolResolve.pushCallStackList (\"%s\");", prog->program_id);
joutput_newline();

/* Initialization */
Expand Down Expand Up @@ -4891,6 +4892,7 @@ static void joutput_internal_function(struct cb_program *prog,
// output_newline ();
// }
joutput_line("/* Pop module stack */");
joutput_line("CobolResolve.popCallStackList();");
joutput_line("CobolModule.pop();");
joutput_newline();
if (cb_flag_traceall) {
Expand Down
4 changes: 3 additions & 1 deletion cobj/typeck.c
Original file line number Diff line number Diff line change
Expand Up @@ -3161,7 +3161,9 @@ void cb_emit_cancel(cb_tree prog) {
cb_emit(cb_build_funcall_1("CobolResolve.fieldCancel", prog));
}

void cb_emit_cancel_all() { cb_emit(cb_build_funcall_0("cob_cancel_all")); }
void cb_emit_cancel_all() {
cb_emit(cb_build_funcall_0("CobolResolve.cancelAll"));
}

/*
* CLOSE statement
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package jp.osscons.opensourcecobol.libcobj.call;

/** CALLしたプログラムを階層構造で管理するためのクラス */
public class CobolCallStackList {
private CobolCallStackList parent;
private CobolCallStackList children;
private CobolCallStackList sister;
private String name;

/** コンストラクタ */
protected CobolCallStackList() {
this.parent = null;
this.children = null;
this.sister = null;
this.name = null;
}

/**
* コンストラクタ
*
* @param name プログラム名
*/
protected CobolCallStackList(String name) {
this.parent = null;
this.children = null;
this.sister = null;
this.name = name;
}

/**
* 親ノードを取得する
*
* @return parent 親ノード
*/
protected CobolCallStackList getParent() {
return parent;
}

/**
* 親ノードを設定する
*
* @param parent 親ノード
*/
protected void setParent(CobolCallStackList parent) {
this.parent = parent;
}

/**
* 子ノードを取得する
*
* @return children 子ノード
*/
protected CobolCallStackList getChildren() {
return children;
}

/**
* 子ノードを設定する
*
* @param children 子ノード
*/
protected void setChildren(CobolCallStackList children) {
this.children = children;
}

/**
* 兄弟ノードを取得する
*
* @return sister 兄弟ノード
*/
protected CobolCallStackList getSister() {
return sister;
}

/**
* 兄弟ノードを設定する
*
* @param sister 兄弟ノード
*/
protected void setSister(CobolCallStackList sister) {
this.sister = sister;
}

/**
* プログラム名を取得する
*
* @return name プログラム名
*/
protected String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ public class CobolResolve {
cobException.put(0x1609, "EC-XML-RANGE");
}

/** コールスタックリストのヘッド */
private static CobolCallStackList callStackListHead = null;

/** 現在のコールスタックリスト */
private static CobolCallStackList currentCallStackList = null;

/**
* 下記の環境変数を読み込み、CobolResolve内で定義されたメソッドの動作が変わる。<br>
* 環境変数COB_LOAD_CASEにLOWERが指定されているときは、resolveメソッドに渡された引数を小文字に変換してから処理を開始する。<br>
Expand Down Expand Up @@ -509,4 +515,125 @@ public static void cobCancel(String name) throws CobolStopRunException {
runner.cancel();
}
}

/**
* コールスタックリストを初期化する
*/
private static void initCallStackList() {
if (callStackListHead == null) {
callStackListHead = new CobolCallStackList();
}
currentCallStackList = callStackListHead;
}

/**
* 新しいコールスタックリストを作成する
*
* @param name プログラム名
* @return 作成したコールスタックリスト
*/
private static CobolCallStackList createCallStackList(String name) {
CobolCallStackList newList = new CobolCallStackList(name);
newList.setParent(currentCallStackList);
currentCallStackList = newList;
return newList;
}

/**
* 指定されたコールスタックリストとその子プログラムをすべてキャンセルする
*
* @param p キャンセル対象のコールスタックリスト
*/
private static void cancelCallStackList(CobolCallStackList p) {
if (p == null) {
return;
}

// プログラムをキャンセル
String programName = p.getName();
if (programName != null) {
try {
CobolResolve.cobCancel(programName);
} catch (CobolStopRunException e) {
return;
}
}

// 子プログラムを再帰的にキャンセル
if (p.getChildren() != null) {
cancelCallStackList(p.getChildren());
p.setChildren(null);
}

// 兄弟要素を再帰的にキャンセル
if (p.getSister() != null) {
cancelCallStackList(p.getSister());
p.setSister(null);
}
}

/**
* コールスタックにプログラムをプッシュする
*
* @param name プログラム名
*/
public static void pushCallStackList(String name) {
if (currentCallStackList == null) {
initCallStackList();
}

CobolCallStackList p = currentCallStackList.getChildren();
if (p == null) {
currentCallStackList.setChildren(createCallStackList(name));
return;
}

if (p.getName().equals(name)) {
currentCallStackList = p;
return;
}

if (p.getSister() == null) {
p.setSister(createCallStackList(name));
return;
}

p = p.getSister();
while (true) {
if (p.getName().equals(name)) {
currentCallStackList = p;
return;
}
if (p.getSister() == null) {
break;
}
p = p.getSister();
}

p.setSister(createCallStackList(name));
}

/**
* コールスタックから一つ取り出す
*/
public static void popCallStackList() {
if (currentCallStackList != null) {
currentCallStackList = currentCallStackList.getParent();
}
}

/**
* 現在のコールスタックの子プログラムをすべてキャンセルする
*
* @throws CobolRuntimeException 現在のスタックがnullの場合
*/
public static void cancelAll() throws CobolRuntimeException {
if (currentCallStackList == null) {
throw new CobolRuntimeException(
CobolRuntimeException.COBOL_FATAL_ERROR,
"Call to 'cancelAll' current stack is NULL");
}
cancelCallStackList(currentCallStackList.getChildren());
currentCallStackList.setChildren(null);
}
}
Loading