Skip to content

Commit 0522109

Browse files
Marcel Heckoclaude
authored andcommitted
Auto-resolve .dsm extension in DSM #include directives (#286)
When a #include path doesn't exist as-is, automatically try appending ".dsm" before failing. This fixes the common case where DSM scripts use #include without the file extension (e.g. #include "ivr_apps" instead of #include "ivr_apps.dsm"). Replaces the previous hint-only diagnostic with an actual fallback that resolves the path transparently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 28a98a7 commit 0522109

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

apps/dsm/DSMStateDiagramCollection.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,6 @@ bool DSMStateDiagramCollection::readFile(const string& filename, const string& n
4747
if (!ifs.good()) {
4848
ERROR("loading state diagram '%s': cannot open file (%s)\n",
4949
filename.c_str(), strerror(errno));
50-
51-
// Check if the user forgot the .dsm extension (common #include mistake)
52-
string with_ext = filename + ".dsm";
53-
ifstream test_ifs(with_ext.c_str());
54-
if (test_ifs.good()) {
55-
ERROR(" Hint: '%s' exists - did you mean to use '%s' in your #include directive?\n",
56-
with_ext.c_str(), with_ext.c_str());
57-
}
5850
return false;
5951
}
6052

@@ -113,7 +105,18 @@ bool DSMStateDiagramCollection::readFile(const string& filename, const string& n
113105
return false;
114106
}
115107
} else {
116-
if (!readFile(include_name, name, current_load_path, s)) {
108+
// If path doesn't exist, try appending .dsm extension as fallback
109+
string actual_include = include_name;
110+
if (stat(include_name.c_str(), &status) != 0) {
111+
string with_ext = include_name + ".dsm";
112+
if (stat(with_ext.c_str(), &status) == 0 &&
113+
!(status.st_mode & S_IFDIR)) {
114+
DBG("'%s' not found, using '%s'\n",
115+
include_name.c_str(), with_ext.c_str());
116+
actual_include = with_ext;
117+
}
118+
}
119+
if (!readFile(actual_include, name, current_load_path, s)) {
117120
ERROR(" while processing '#include %s' in '%s'\n",
118121
include_name.c_str(), filename.c_str());
119122
return false;

doc/dsm/Readme.dsm.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ A patch for fmsc 1.0.4 from the graphical FSM editor fsme
6262
click-n-drag fashion and compiled to SEMS DSM diagrams.
6363

6464
DSM scripts can include other scripts by using the #include "script.dsm"
65-
directive. That loads a script from the load path (where the current
66-
script resides), unless an absolute path is given (e.g.
67-
#include "/path/to/script).
65+
directive. That loads a script from the load path (where the current
66+
script resides), unless an absolute path is given (e.g.
67+
#include "/path/to/script"). The .dsm extension is optional:
68+
#include "script" will automatically resolve to "script.dsm" if the
69+
bare path does not exist. If the path refers to a directory, all .dsm
70+
files in that directory are included.
6871

6972
There is SIP Session Timer (RFC4028) support, which is configured in
7073
dsm.conf. By default, session timers are turned not enabled.

doc/dsm/dsm_syntax.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@ Syntax
77
# comment, too
88

99
#include "script.dsm"
10+
#include "script"
1011
#include "script_dir"
1112
#include "/path/to/anotherscript.dsm"
13+
#include "/path/to/anotherscript"
1214
#include "/path/to/script_dir"
1315

16+
The .dsm extension is optional in #include directives: if the path does
17+
not exist as-is and appending ".dsm" matches a file, it is used
18+
automatically. Directory includes load all .dsm files from the directory.
19+
1420
import(mod_name);
1521

1622
[initial] state name

0 commit comments

Comments
 (0)