Skip to content
Merged
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
4 changes: 2 additions & 2 deletions buildapp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
name="Structorizer"
displayname="Structorizer"
identifier="lu.fisch.Structorizer"
shortversion="3.32-33"
version="3.32-33"
shortversion="3.32-34"
version="3.32-34"
icon="icons/Structorizer.icns"
mainclassname="Structorizer"
copyright="Bob Fisch"
Expand Down
15 changes: 8 additions & 7 deletions freedesktop/applications/structorizer.desktop
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[Desktop Entry]
Type=Application
Version=1.4
Name=Structorizer
GenericName=Diagram creator
Comment=Create Nassi-Shneiderman diagrams (NSD)
Icon=structorizer
Exec=structorizer
Comment=Create, edit and run Nassi-Shneiderman diagrams (NSD).
Icon=000_structorizer.png
Exec="/usr/bin/structorizer" %U
TryExec=/usr/bin/structorizer
StartupNotify=false
Terminal=false
MimeType=application/nsd
Categories=Development;Graphics;VectorGraphics;RasterGraphics;ComputerScience
Keywords=nsd;diagrams
MimeType=application/nsd;application/arrz;
Categories=Development;Education;Utility;Graphics;VectorGraphics;ComputerScience;Java;
Keywords=nsd;diagrams;arrz;
4 changes: 2 additions & 2 deletions src/lu/fisch/structorizer/elements/Element.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ public String toString()
// START KGU#791 2020-01-20: Enh. #801 - support for offline help
public static final String E_HELP_FILE = "structorizer_user_guide.pdf";
/** Estimated size of the User Guide PDF file (to be adapted when User Guide significantly grows) */
public static final long E_HELP_FILE_SIZE = 12300000;
public static final long E_HELP_FILE_SIZE = 12900000;
public static final String E_DOWNLOAD_PAGE = "https://www.fisch.lu/Php/download.php";
// END KGU#791 2020-01-20
public static final String E_VERSION = "3.32-33";
public static final String E_VERSION = "3.32-34";
public static final String E_THANKS =
"Developed and maintained by\n"+
" - Robert Fisch <robert.fisch@education.lu>\n"+
Expand Down
106 changes: 92 additions & 14 deletions src/lu/fisch/structorizer/elements/Root.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
* Kay Gürtzig 2025-08-04 Partial indentation revision (blanks -> tabs)
* Kay Gürtzig 2025-08-08 Issue #1205: Refinement of check 2 (method analyse_2) to avoid false
* complaining endless loops on fileEOF or Turtleizer conditions
* Kay Gürtzig 2025-10-17/18 Bugfix #1226: #1193 flaws mended, more thourough argument/result inference
*
******************************************************************************************************
*
Expand Down Expand Up @@ -3272,7 +3273,7 @@ public StringList getVarNames() {

/**
* Extracts the names of all variables assigned or introduced within passed-in element
* {@code _ele} and its possible substructure.
* {@code _ele} without its possible substructure.
* @param _ele - the element to be scanned for introduced variables
* @return list of variable names
* @see #getVarNames(Element, boolean)
Expand Down Expand Up @@ -7774,11 +7775,15 @@ public Root outsourceToSubroutine(IElementSequence elements, String name, String
// Identify uninitialized variables before the outsourcing (for comparison)
StringList uninitializedVars0 = new StringList();
this.getUninitializedVars(this.children, new StringList(), uninitializedVars0);
if (Element.getRoot(elements.getSubqueue()) != this) {
Subqueue owningSq = elements.getSubqueue();
if (Element.getRoot(owningSq) != this) {
return null;
}
// START KGU#1209 2025-10-15: Bugfix #1226
int ixSub = owningSq.getIndexOf(elements.getElement(0));
// END KGU#1209 2025-10-15
// Create the new subroutine and move the elements to it
subroutine = new Root();
subroutine = new Root();
subroutine.setProgram(false);
for (int i = 0; i < nElements; i++) {
subroutine.children.addElement(elements.getElement(0));
Expand All @@ -7805,15 +7810,68 @@ public Root outsourceToSubroutine(IElementSequence elements, String name, String
for (int i = args.count() - 1; i >= 0; i--) {
String argName = args.get(i);
if (!vars.contains(argName)) {
// It is unlikely that the outer context is responsible to provide the value
args.remove(i);
}
}
// If a subroutine variable still occurs in the outer diagram it may be be needed as result
// START KGU#1209 2025-10-17: Bugfix #1226 This produced too many false results
//for (int i = 0; i < subVars.count(); i++) {
// String varName = subVars.get(i);
// if (vars.contains(varName) || uninitializedVars1.contains(varName)) {
// results.addIfNew(varName);
// }
//}
StringList uninitializedVars2 = new StringList();
// This is scanning up the tree
StringList assignedVars = new StringList();
Element sqParent = owningSq.parent;
int ixDiff = 0;
do {
StringList assignedVars0 = assignedVars.copy();
if (ixSub+ixDiff < owningSq.getSize()) {
IElementSequence subsequentEls = new SelectedSequence(owningSq, ixSub+ixDiff, owningSq.getSize()-1);
this.getUninitializedVars(subsequentEls, assignedVars, uninitializedVars2);
}
if (sqParent instanceof Loop) {
if (!(sqParent instanceof Forever)) {
// get all set variables from loop header (no substructure)
StringList loopVars = getVarNames(sqParent); // Should be empty for non-FOR loops
assignedVars0.addIfNew(loopVars);
// Find uninitialized variables in the condition
StringList loopUsedVars = getUsedVarNames(sqParent, true, true);
for (int i = 0; i < loopUsedVars.count(); i++) {
String varName = loopUsedVars.get(i);
if (!assignedVars0.contains(varName)) {
uninitializedVars2.addIfNew(varName);
}
}
}
if (ixSub > 0) {
IElementSequence precedingEls = new SelectedSequence(owningSq, 0, ixSub-1);
this.getUninitializedVars(precedingEls, assignedVars0, uninitializedVars2);
}
}
owningSq = null;
// Now get uninitialized variables from the subsequent parent elements
if (sqParent != this && sqParent.parent instanceof Subqueue) {
owningSq = (Subqueue)sqParent.parent;
ixSub = owningSq.getIndexOf(sqParent);
sqParent = owningSq.parent;
}
ixDiff = 1;
} while (owningSq != null);
// Modified subroutine variables should be returned if they are still used in outer without being overridden
for (int i = 0; i < subVars.count(); i++) {
String varName = subVars.get(i);
if (vars.contains(varName) || uninitializedVars1.contains(varName)) {
TypeMapEntry varType = types.get(varName);
if (uninitializedVars2.contains(varName) &&
// Passed-in array variables may usually be excluded (as their modification is transparent).
!(args.contains(varName) && varType != null && varType.isArray())) {
results.addIfNew(varName);
}
}
// END KGU#1209 2025-10-17
// END KGU#987 2025-02-27
if (results.isEmpty() && result != null) {
results.add(result);
Expand Down Expand Up @@ -7916,16 +7974,23 @@ private String makeTypeDeclaration(String varName, HashMap<String, TypeMapEntry>
return typeDecl;
}
/**
* This is practically a very lean version of the {@link #analyse(StringList)} method. We simply don't create
* Analyser warnings but collect variable names which are somewhere used without (unconditioned)
* initialization. These are candidates for parameters.
* This is practically a very lean version of the {@link #analyse(StringList)}
* method. We simply don't create Analyser warnings but collect variable names
* which are somewhere used without (unconditioned) initialization. These are
* candidates for parameters.
* @param _node - The Subqueue recursively to be scrutinized for variables
* @param _vars - Names of variables, which had been introduced before (will be enhanced here)
* @param _args - collects the names of not always initialized variables (potential arguments)
* @param _vars - Names of variables, which had been introduced before (will
* be enhanced here)
* @param _args - collects the names of not always initialized variables
* (potential arguments)
*/
private void getUninitializedVars(Subqueue _node, StringList _vars, StringList _args) {
// START KGU#1209 2025-10-15 Bugfix #1226 We need to analyse partial subqueues
//private void getUninitializedVars(Subqueue _node, StringList _vars, StringList _args)
private void getUninitializedVars(IElementSequence _node, StringList _vars, StringList _args)
// END KGU#1209 2025-10-15
{

for (int i=0; i<_node.getSize(); i++)
for (int i = 0; i < _node.getSize(); i++)
{
Element ele = _node.getElement(i);
if (ele.isDisabled(true)) continue;
Expand All @@ -7935,11 +8000,11 @@ private void getUninitializedVars(Subqueue _node, StringList _vars, StringList _
// get all set variables from actual instruction (just this level, no substructure)
StringList myVars = getVarNames(ele);
// Find uninitialized variables (except REPEAT)
StringList myUsedVars = getUsedVarNames(_node.getElement(i),true,true);
StringList myUsedVars = getUsedVarNames(ele, true, true);

if (!eleClassName.equals("Repeat"))
{
for (int j=0; j<myUsedVars.count(); j++)
for (int j = 0; j < myUsedVars.count(); j++)
{
String myUsed = myUsedVars.get(j);
// START KGU#343 2017-02-07: Ignore pseudo-variables (markers)
Expand All @@ -7961,6 +8026,19 @@ private void getUninitializedVars(Subqueue _node, StringList _vars, StringList _
if (ele instanceof Loop)
{
getUninitializedVars(((Loop) ele).getBody(), _vars, _args);
// START KGU#1209 2025-10-18: Bugfix #1226 Defective subroutine result retrieval
if (eleClassName.equals("Repeat"))
{
for (int j = 0; j < myUsedVars.count(); j++)
{
String myUsed = myUsedVars.get(j);
if (!myUsed.startsWith("§ANALYSER§") && !_vars.contains(myUsed))
{
_args.addIfNew(myUsed);
}
}
}
// END KGU#1209 2025-10-18
}
else if (eleClassName.equals("Parallel"))
{
Expand Down Expand Up @@ -7989,7 +8067,7 @@ else if(eleClassName.equals("Alternative"))
if (fVars.contains(varName)) { _vars.addIfNew(varName); }
}
}
else if(eleClassName.equals("Case"))
else if (eleClassName.equals("Case"))
{
Case caseEle = ((Case) ele);
int nBranches = caseEle.qs.size(); // Number of branches
Expand Down
18 changes: 15 additions & 3 deletions src/lu/fisch/structorizer/generators/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1620,7 +1620,10 @@ else if (indexList.get(0).trim().startsWith("]")) {
}
} // if (!this.suppressTransformation && (isDecl || exprTokens != null))
// START KGU#388 2017-09-25: Enh. #423
else if (!this.suppressTransformation && Instruction.isTypeDefinition(_line, typeMap)) {
// START KGU#1208 2025-09-29: Issue #1210 Revision for case suppressTransformation
//else if (!this.suppressTransformation && Instruction.isTypeDefinition(_line, typeMap)) {
else if (Instruction.isTypeDefinition(_line, typeMap)) {
// END KGU#1208 2025-09-25
// Attention! The following condition must not be combined with the above one!
if (this.isInternalDeclarationAllowed()) {
tokens.removeAll(" ");
Expand All @@ -1635,8 +1638,17 @@ else if (!this.suppressTransformation && Instruction.isTypeDefinition(_line, typ
TypeMapEntry type = this.typeMap.get(":" + typeName);
Root root = Element.getRoot(_inst);
if (type != null) {
this.generateTypeDef(root, typeName, type, _indent, isDisabled);
_commentInserted = true;
// START KGU#1208-2025-09-29: Issue #1210
//this.generateTypeDef(root, typeName, type, _indent, isDisabled);
//_commentInserted = true;
if (!suppressTransformation) {
this.generateTypeDef(root, typeName, type, _indent, isDisabled);
_commentInserted = true;
}
else if (!this.wasDefHandled(root, ":"+typeName, true)) {
codeLine = _line;
}
// END KGU#1208 2025-09-29
// CodeLine is not filled because the code has already been generated
}
else {
Expand Down
6 changes: 4 additions & 2 deletions src/lu/fisch/structorizer/gui/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Known issues (also see https://github.com/fesch/Structorizer.Desktop/issues):
- ARM export is still experimental and relies on a specific and very restricted
syntax for the element contents in order to produce meaningful results.

Current development version 3.32-33 (2025-09-24)
Current development version 3.32-34 (2025-10-19)
- 01: Bugfix #987: Duplicate subroutine comment export by Pascal generator <2>
- 01: Bugfix #988: Syntax error in Structorizer.bat and Arranger.bat fixed <2>
- 01: Bugfix #989: Expressions in EXIT elements (e.g. return) were forgotten
Expand Down Expand Up @@ -319,10 +319,12 @@ Current development version 3.32-33 (2025-09-24)
- 33: Bugfix #1210 Bash/ksh export still produced unwelcome return workarounds
to be disabled in case of active "No conversion ..." export option,
likewise unwelcome typeset commands on ksh export. <2>
- 33: Issue #1219: Thread-safe implementation (see version 3.32-32) <2>
- 33: Issue #1219 Thread-safe implementation (see version 3.32-32) <2>
- 33: Issue #1221 Comment lines were unduly trimmed and if empty skipped. <2>
- 33: Bugfix #1222 Two minor shell export flaws with CASE elements <2>
- 33: Enh. #1223 Export of Try/Throw elements to bash/ksh implemented <2>
- 34: Bugfix #1210 Defective C export in suppressed mode for includables <2>
- 34: Bugfix #1226 Errors on detecting arguments/results for outsourcing <2>

Version 3.32 (2021-09-19) requiring Java 11 or newer
- 01: Bugfix #851/2: SPECIAL-NAMES sections caused COBOL parser abort <2>
Expand Down