Openscad "include <folder/file.scad>" doesn't really work

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Openscad "include <folder/file.scad>" doesn't really work

Elmo Mäntynen
The openscad lib MCAD (http://github.com/elmom/MCAD) I've been working
on can't easily be used how it is supposed to be used, that is, being
imported from outside the dir like in C or python. I noticed it trying
to port code in http://github.com/timschmidt/parameterized-mendel to use
  MCAD, which is imported into the repo as a git submodule. I now think
this is why the testing infra code in MCAD doesn't really work.


Doing "include <folder/file.scad>" fails if the file tries to include
another file next to it.

You can do a "git clone git://github.com/elmom/MCAD.git" or just
recreate the minimal hierarchy as follows:
testdir/MCAD/units.scad: "mm=1;"
testdir/MCAD/bearing.scad: """
include <units.scad> //this will fail
module test_bearing(){}
"""

Now the test code:
testdir/test.scad: """
include <MCAD/bearing.scad>
include <MCAD/units.scad>

echo(mm);
test_bearing();
"""

then do "openscad -s test.stl test.scad" inside testdir (or paste the
code in the openscad editor and hit F5)

This fails with
"""
WARNING: Can't open input file `units.scad'.
WARNING: Can't open input file `materials.scad'.
ECHO: 1
WARNING: Ignoring unkown module 'test_bearing'.
"""

MCAD/bearing.scad includes materials.scad after units.scad and somehow
gets to that line. See the third case below.

Commenting "include <MCAD/bearing.scad>"
just outputs (as it should)
"""
ECHO: 1
WARNING: Ignoring unkown module 'test_bearing'.
"""

Interestingly, just commenting "include <MCAD/units.scad>"
fails with
"""
WARNING: Can't open input file `units.scad'.
WARNING: Ignoring unknown variable 'mm'.
ECHO: undef
WARNING: Ignoring unkown module 'test_bearing'.
"""

Now it doesn't complain about materials.scad anymore.

This bug/feature really hampers any efforts to share modular code
easily. I consider this a major bug, which should be easy to fix.

Elmo

Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Elmo Mäntynen
OK. Doing "use <folder/file.scad> doesn't have this problem it seems. I
need "include" since "use" doesn't include variables, which is an odd
feature. Is there any reason for that? MCAD code is made safe for being
imported with "include" for this reason. Been meaning to ask about this
one also :) Fixing either feature/bug would be adequate for MCAD usage.

Elmo Mäntynen wrote:

> The openscad lib MCAD (http://github.com/elmom/MCAD) I've been working
> on can't easily be used how it is supposed to be used, that is, being
> imported from outside the dir like in C or python. I noticed it trying
> to port code in http://github.com/timschmidt/parameterized-mendel to use
>   MCAD, which is imported into the repo as a git submodule. I now think
> this is why the testing infra code in MCAD doesn't really work.
>
>
> Doing "include <folder/file.scad>" fails if the file tries to include
> another file next to it.
>
> You can do a "git clone git://github.com/elmom/MCAD.git" or just
> recreate the minimal hierarchy as follows:
> testdir/MCAD/units.scad: "mm=1;"
> testdir/MCAD/bearing.scad: """
> include <units.scad> //this will fail
> module test_bearing(){}
> """
>
> Now the test code:
> testdir/test.scad: """
> include <MCAD/bearing.scad>
> include <MCAD/units.scad>
>
> echo(mm);
> test_bearing();
> """

test_bearing should've been bearing_test :)

change the "include" to "use" and the problem disappears.

> then do "openscad -s test.stl test.scad" inside testdir (or paste the
> code in the openscad editor and hit F5)
>
> This fails with
> """
> WARNING: Can't open input file `units.scad'.
> WARNING: Can't open input file `materials.scad'.
> ECHO: 1
> WARNING: Ignoring unkown module 'test_bearing'.
> """
>
> MCAD/bearing.scad includes materials.scad after units.scad and somehow
> gets to that line. See the third case below.
>
> Commenting "include <MCAD/bearing.scad>"
> just outputs (as it should)
> """
> ECHO: 1
> WARNING: Ignoring unkown module 'test_bearing'.
> """
>
> Interestingly, just commenting "include <MCAD/units.scad>"
> fails with
> """
> WARNING: Can't open input file `units.scad'.
> WARNING: Ignoring unknown variable 'mm'.
> ECHO: undef
> WARNING: Ignoring unkown module 'test_bearing'.
> """
>
> Now it doesn't complain about materials.scad anymore.
>
> This bug/feature really hampers any efforts to share modular code
> easily. I consider this a major bug, which should be easy to fix.
>
> Elmo
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad


Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Giles Bathgate-2
On Wed, 2010-09-29 at 20:40 +0300, Elmo Mäntynen wrote:
> OK. Doing "use <folder/file.scad> doesn't have this problem it seems. I
> need "include" since "use" doesn't include variables, which is an odd
> feature. Is there any reason for that? MCAD code is made safe for being
> imported with "include" for this reason. Been meaning to ask about this
> one also :) Fixing either feature/bug would be adequate for MCAD usage.

As far as I understand "include", basically includes the text from one
file in another, as if you had just cut the contents from one file and
paste it in the other (or just concatenated the two files together)

"use" is much smarter only modules in the file are pulled into the
other, this doesn't include top level objects. also global variables
within the lib seem to get thier own namespace, and for good reason

Consider the following files:

========foo.scad=======
p = 8;

module that()
{
        echo(p);
}

=======================
 
========bar.scad=======

use <foo.scad>

p = 5;

module this()

{

that();

}

this();

=========================

if we used include the definition of p in bar.scad would override the
definition of p in foo.scad This is not usually wanted as it can be
confusing when it comes to debugging.

I agree that there does need to be some kind of feature so that you can
override, or even access foo.p if you so want to. Prehaps you can work
around the problem by using functions to return the values, rather than
global variables.

Regards

Giles


Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Elmo Mäntynen


On 10/03/2010 11:25 PM, Giles Bathgate wrote:

> On Wed, 2010-09-29 at 20:40 +0300, Elmo Mäntynen wrote:
>> OK. Doing "use<folder/file.scad>  doesn't have this problem it seems. I
>> need "include" since "use" doesn't include variables, which is an odd
>> feature. Is there any reason for that? MCAD code is made safe for being
>> imported with "include" for this reason. Been meaning to ask about this
>> one also :) Fixing either feature/bug would be adequate for MCAD usage.
>
> As far as I understand "include", basically includes the text from one
> file in another, as if you had just cut the contents from one file and
> paste it in the other (or just concatenated the two files together)

That would explain things :)

Does the the C preprocessor do things differently?

> "use" is much smarter only modules in the file are pulled into the
> other, this doesn't include top level objects. also global variables
> within the lib seem to get thier own namespace, and for good reason
>
> Consider the following files:
>
> ========foo.scad=======
> p = 8;
>
> module that()
> {
> echo(p);
> }
>
> =======================
>
> ========bar.scad=======
>
> use<foo.scad>
>
> p = 5;
>
> module this()
>
> {
>
> that();
>
> }
>
> this();
>
> =========================
>
> if we used include the definition of p in bar.scad would override the
> definition of p in foo.scad This is not usually wanted as it can be
> confusing when it comes to debugging.
>
> I agree that there does need to be some kind of feature so that you can
> override, or even access foo.p if you so want to. Prehaps you can work
> around the problem by using functions to return the values, rather than
> global variables.

Actually, I want to  have CONSTANTS that can be imported from the lib.
Of course I could use function calls, but that would be very cumbersome.

As an example, take MCAD/units.scad:
"""
include <MCAD/units.scad>

heigth = 1*cm //same as 10
length = 1*m  /same as 1000
"""

This still works, but what about constants in other files (like the
predefined bearing types in MCAD/bearing.scad) that want to import
constants from yet another file (like units.scad).

I could try to work around this, but I see no reason for not fixing this
by creating a way to include constants in addition to modules and functions

Elmo

> Regards
>
> Giles
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad

Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Jonathan Marsden
On 10/03/2010 09:45 PM, Elmo wrote:

> Does the the C preprocessor do things differently?

Yes.  See http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html which says

  GCC looks for headers requested with #include "file" first in the
  directory containing the current file, then in the directories as
  specified by -iquote options, then in the same places it would have
  looked for a header requested with angle brackets. For example, if
  /usr/include/sys/stat.h contains #include "types.h", GCC looks for
  types.h first in /usr/include/sys, then in its usual search path.

for how GCC handles this (this behaviour is compiler-dependent,
Microsoft does it slightly differently, see
http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx for their approach).

Both GCC and MS C track the directory the current text is being read
from, and use that as the first place to search, which apparently
OpenSCAD does not currently do.  I have no idea if that is a deliberate
design choice in OpenSCAD, or just an accidental side-effect of how
#include was implemented.

Jonathan

Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Elmo Mäntynen


On 10/04/2010 08:18 AM, Jonathan Marsden wrote:

> On 10/03/2010 09:45 PM, Elmo wrote:
>
>> Does the the C preprocessor do things differently?
>
> Yes.  See http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html which says
>
>    GCC looks for headers requested with #include "file" first in the
>    directory containing the current file, then in the directories as
>    specified by -iquote options, then in the same places it would have
>    looked for a header requested with angle brackets. For example, if
>    /usr/include/sys/stat.h contains #include "types.h", GCC looks for
>    types.h first in /usr/include/sys, then in its usual search path.
>
> for how GCC handles this (this behaviour is compiler-dependent,
> Microsoft does it slightly differently, see
> http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx for their approach).
>
> Both GCC and MS C track the directory the current text is being read
> from, and use that as the first place to search, which apparently
> OpenSCAD does not currently do.

This much I know :) I was pondering about does cpp just prepend the
included file to the source to be compiled? OpenSCAD variables are
really global constants and the last definition overrides all others, so
problems will occur. The cpp #def's follow the scoping rules of C, that
is any uses of a name will be replaced by the value in the last #def
before that line, not the last one in the file.

OpenSCAD should really differentiate between global constants (given on
the command line) and normal variables/constants. That way the file
local variables could really be normal variables like in C or python.

The quick "fix" would be to make "include" work as you quoted. The MCAD
code can be made to avoid the problems of client code masking local
variables, by using proper descriptive names (not a bad habit anyway ;).
I generally strive for good coding style and clear code, comments and
other nice conventions that apply.

Elmo

I have no idea if that is a deliberate
> design choice in OpenSCAD, or just an accidental side-effect of how
> #include was implemented.
>
> Jonathan
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad

Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Bas Pijls
I know that MATLAB has a funky way of dealing with global variables. I circumvented the this once by implementing constants as functions. In openscad you could put the following in an include file:

function height() =  1*cm;
function length() = height()/2;

Functions, as opposed to global variables, are included using the "use" statement.

On Mon, Oct 4, 2010 at 10:06 AM, Elmo <[hidden email]> wrote:


On 10/04/2010 08:18 AM, Jonathan Marsden wrote:
> On 10/03/2010 09:45 PM, Elmo wrote:
>
>> Does the the C preprocessor do things differently?
>
> Yes.  See http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html which says
>
>    GCC looks for headers requested with #include "file" first in the
>    directory containing the current file, then in the directories as
>    specified by -iquote options, then in the same places it would have
>    looked for a header requested with angle brackets. For example, if
>    /usr/include/sys/stat.h contains #include "types.h", GCC looks for
>    types.h first in /usr/include/sys, then in its usual search path.
>
> for how GCC handles this (this behaviour is compiler-dependent,
> Microsoft does it slightly differently, see
> http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx for their approach).
>
> Both GCC and MS C track the directory the current text is being read
> from, and use that as the first place to search, which apparently
> OpenSCAD does not currently do.

This much I know :) I was pondering about does cpp just prepend the
included file to the source to be compiled? OpenSCAD variables are
really global constants and the last definition overrides all others, so
problems will occur. The cpp #def's follow the scoping rules of C, that
is any uses of a name will be replaced by the value in the last #def
before that line, not the last one in the file.

OpenSCAD should really differentiate between global constants (given on
the command line) and normal variables/constants. That way the file
local variables could really be normal variables like in C or python.

The quick "fix" would be to make "include" work as you quoted. The MCAD
code can be made to avoid the problems of client code masking local
variables, by using proper descriptive names (not a bad habit anyway ;).
I generally strive for good coding style and clear code, comments and
other nice conventions that apply.

Elmo

I have no idea if that is a deliberate
> design choice in OpenSCAD, or just an accidental side-effect of how
> #include was implemented.
>
> Jonathan
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad

Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

Giles Bathgate-2
In reply to this post by Elmo Mäntynen
On 4 October 2010 09:06, Elmo <[hidden email]> wrote:
> The quick "fix" would be to make "include" work as you quoted. The MCAD
> code can be made to avoid the problems of client code masking local
> variables, by using proper descriptive names (not a bad habit anyway ;).
> I generally strive for good coding style and clear code, comments and
> other nice conventions that apply.
>
> Elmo

With regards to fixes and patches unfortunately it seems that the
maintainers of this project are either a) are too busy or b) don't
care
I submitted a patch to create a vector of random numbers recently,
emailed both Marius Kintel and Clifford Wolf. I have yet to get a
reply from either of them. Furthermore nothing has been done on this
project since the last commit on Jul 9, 2010 which was another patch
implemented by myself a sign() function suggested by Dan Zuras.

Hoping to hear from the Devs soon.

Regards

Giles.

Reply | Threaded
Open this post in threaded view
|

Re: Openscad "include <folder/file.scad>" doesn't really work

kintel
Administrator
In reply to this post by Elmo Mäntynen
On Sep 29, 2010, at 19:10 PM, Elmo Mäntynen wrote:
>
> Doing "include <folder/file.scad>" fails if the file tries to include
> another file next to it.

I'm slowly reading through old emails:
This is due to the OpenSCAD parser not handling nested input files at all. I think it makes sense to fix it.
I just added this comment to TODO.txt:

  - include statement doesn't support nesting. This can be fixed by
    keeping a nested stack of current input files in the lexer. See
    the "Flex & Bison" O'Reilly book, "Start States and Nested Input
    Files", page 28, for an example.

Unless someone beats me to it, I'll try looking at it one of these days

 -Marius



Reply | Threaded
Open this post in threaded view
|

Another one to look at.

Giles Bathgate-2
Marius,

Another (I think quite trivial) patch that might be worth looking at is

http://rocklinux.net/pipermail/openscad/2010-September/000591.html

My solution to this wasn't any good, but I think Steven Dicks Solution
is good, or do like he says and hunt down one for doubles in a C lexer.

Regards

Giles


Reply | Threaded
Open this post in threaded view
|

Re: Another one to look at.

kintel
Administrator
On Nov 2, 2010, at 14:46 PM, Giles Bathgate wrote:
> http://rocklinux.net/pipermail/openscad/2010-September/000591.html
>
> My solution to this wasn't any good, but I think Steven Dicks Solution
> is good, or do like he says and hunt down one for doubles in a C lexer.
>
Thanks!
I've applied this to svn&git.

 -Marius