www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - rdmd --main

reply spir <denis.spir gmail.com> writes:
Hello,


The rdmd option --main is really helpful to test modules independently (it =
adds an empty main() to prevent the linker from crying). An issue is that e=
ach time we switch between .d files that have no main() (modules in tended =
for export) and app files that have one, this option must be set or removed=
 (else the linker complains for having 2 main()).
This is not very practicle for rapid edit-test cycles -- for "exploratory" =
programming in general. Would it be difficult for rdmd to detect whether a =
main is already present? It is not a big issue anyway -- just in case would=
 be easy.

Thank you very much for this tool, Andrei.


Denis
-- -- -- -- -- -- --
vit esse estrany =E2=98=A3

spir.wikidot.com
Nov 22 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules independently (it
adds an empty main() to prevent the linker from crying). An issue is that each
time we switch between .d files that have no main() (modules in tended for
export) and app files that have one, this option must be set or removed (else
the linker complains for having 2 main()).
 This is not very practicle for rapid edit-test cycles -- for "exploratory"
programming in general. Would it be difficult for rdmd to detect whether a main
is already present? It is not a big issue anyway -- just in case would be easy.

That feature could be added in several ways. 1. Cooperate with the compiler - have the compiler detect whether or not main() exists. 2. Write a tokenizer (parser is not really needed) and have it identify the occurrence of main with one of the appropriate signatures at top level. 3. Use compiler's json output. 4. Use a low-tech search such as sed to find main. I fear that 2-4 would slow things down and add complexity. Probably 1 would be the best choice. I'll ask Walter. Andrei
Nov 22 2010
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Nov 23, 10 04:38, spir wrote:
 On Mon, 22 Nov 2010 13:28:51 -0600
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:

 On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules independently (it
adds an empty main() to prevent the linker from crying). An issue is that each
time we switch between .d files that have no main() (modules in tended for
export) and app files that have one, this option must be set or removed (else
the linker complains for having 2 main()).
 This is not very practicle for rapid edit-test cycles -- for "exploratory"
programming in general. Would it be difficult for rdmd to detect whether a main
is already present? It is not a big issue anyway -- just in case would be easy.

That feature could be added in several ways. 1. Cooperate with the compiler - have the compiler detect whether or not main() exists. 2. Write a tokenizer (parser is not really needed) and have it identify the occurrence of main with one of the appropriate signatures at top level. 3. Use compiler's json output. 4. Use a low-tech search such as sed to find main. I fear that 2-4 would slow things down and add complexity. Probably 1 would be the best choice. I'll ask Walter.

Thank you for taking this into account. Indeed, asking the compiler is the best solution, but may require some work and testing, I guess. For a non-perfect solution (because would not work in 100% cases), just detecting "\nint main" or "\nvoid main" in file would nearly always work, don't you think? (Possibly adding some opt whitespace in the pattern to catch even more cases.) Or are there issues I'm not aware of. (Else, I would be happy with this, but it's only me.) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com

The issue is "not work in 100% cases" :) class Tier { private int mainValue; private int secondaryValue; int main(int factor) const { return mainValue * factor; } // ^ int secondary(int factor) const { return secondaryValue * factor; } ... }
Nov 22 2010
prev sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Andrei Alexandrescu wrote:
 On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules independently=


 (it adds an empty main() to prevent the linker from crying). An issue
 is that each time we switch between .d files that have no main()
 (modules in tended for export) and app files that have one, this
 option must be set or removed (else the linker complains for having 2
 main()).
 This is not very practicle for rapid edit-test cycles -- for
 "exploratory" programming in general. Would it be difficult for rdmd
 to detect whether a main is already present? It is not a big issue
 anyway -- just in case would be easy.

That feature could be added in several ways. =20 1. Cooperate with the compiler - have the compiler detect whether or no=

 main() exists.
=20
 2. Write a tokenizer (parser is not really needed) and have it identify=

 the occurrence of main with one of the appropriate signatures at top le=

=20
 3. Use compiler's json output.
=20
 4. Use a low-tech search such as sed to find main.
=20

sure if this would work with optlink but it does work with gnu ld. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Nov 24 2010
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On Mon, 22 Nov 2010 13:28:51 -0600
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules independently =


at each time we switch between .d files that have no main() (modules in ten= ded for export) and app files that have one, this option must be set or rem= oved (else the linker complains for having 2 main()).
 This is not very practicle for rapid edit-test cycles -- for "explorato=


r a main is already present? It is not a big issue anyway -- just in case w= ould be easy.
=20
 That feature could be added in several ways.
=20
 1. Cooperate with the compiler - have the compiler detect whether or not=

 main() exists.
=20
 2. Write a tokenizer (parser is not really needed) and have it identify=20
 the occurrence of main with one of the appropriate signatures at top leve=

=20
 3. Use compiler's json output.
=20
 4. Use a low-tech search such as sed to find main.
=20
 I fear that 2-4 would slow things down and add complexity. Probably 1=20
 would be the best choice. I'll ask Walter.

Thank you for taking this into account. Indeed, asking the compiler is the = best solution, but may require some work and testing, I guess. For a non-pe= rfect solution (because would not work in 100% cases), just detecting "\nin= t main" or "\nvoid main" in file would nearly always work, don't you think?= (Possibly adding some opt whitespace in the pattern to catch even more cas= es.) Or are there issues I'm not aware of. (Else, I would be happy with thi= s, but it's only me.) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 22 2010
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On Tue, 23 Nov 2010 04:44:51 +0800
KennyTM~ <kennytm gmail.com> wrote:

 On Nov 23, 10 04:38, spir wrote:
 On Mon, 22 Nov 2010 13:28:51 -0600
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:

 On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules independentl=




that each time we switch between .d files that have no main() (modules in t= ended for export) and app files that have one, this option must be set or r= emoved (else the linker complains for having 2 main()).
 This is not very practicle for rapid edit-test cycles -- for "explora=




her a main is already present? It is not a big issue anyway -- just in case= would be easy.
 That feature could be added in several ways.

 1. Cooperate with the compiler - have the compiler detect whether or n=



 main() exists.

 2. Write a tokenizer (parser is not really needed) and have it identify
 the occurrence of main with one of the appropriate signatures at top l=



 3. Use compiler's json output.

 4. Use a low-tech search such as sed to find main.

 I fear that 2-4 would slow things down and add complexity. Probably 1
 would be the best choice. I'll ask Walter.

Thank you for taking this into account. Indeed, asking the compiler is =


n-perfect solution (because would not work in 100% cases), just detecting "= \nint main" or "\nvoid main" in file would nearly always work, don't you th= ink? (Possibly adding some opt whitespace in the pattern to catch even more= cases.) Or are there issues I'm not aware of. (Else, I would be happy with= this, but it's only me.)
 Denis
 -- -- -- -- -- -- --
 vit esse estrany =E2=98=A3

 spir.wikidot.com

The issue is "not work in 100% cases" :) =20 class Tier { private int mainValue; private int secondaryValue; int main(int factor) const { return mainValue * factor; } // ^ int secondary(int factor) const { return secondaryValue * factor; } ... }

You are right, but this case would correctly not be caught (as long as the = search pattern does not allow free whitespace at start of main's header lin= e), because you properly indented the class's definition. Something like (untested -- and I don't know yet D's regexes): auto mainSearchPattern =3D r"^(int/void)[ \t]+main[ \t]*("; Now, we cannot prevent anyone to write Hello, world as // my first program in d ///////////////////////////////////////////////////////////// void main (){ ///////////////////////////////////////////////////////////// writeln("Hello, world!");} What I imagine is (0) if no --main in cmdline, pass this phase, else (1) re= ad the (top/passed) module into a string (2) search for main() using a paat= ern like this one (3) if not found, append "\nvoid main () {}\n". Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 23 2010
prev sibling next sibling parent Graham Fawcett <fawcett uwindsor.ca> writes:
On Tue, 23 Nov 2010 11:02:19 +0100, spir wrote:

 On Tue, 23 Nov 2010 04:44:51 +0800
 KennyTM~ <kennytm gmail.com> wrote:
 
 On Nov 23, 10 04:38, spir wrote:
 On Mon, 22 Nov 2010 13:28:51 -0600
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:

 On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules
 independently (it adds an empty main() to prevent the linker from
 crying). An issue is that each time we switch between .d files that
 have no main() (modules in tended for export) and app files that
 have one, this option must be set or removed (else the linker
 complains for having 2 main()). This is not very practicle for
 rapid edit-test cycles -- for "exploratory" programming in general.
 Would it be difficult for rdmd to detect whether a main is already
 present? It is not a big issue anyway -- just in case would be
 easy.

That feature could be added in several ways. 1. Cooperate with the compiler - have the compiler detect whether or not main() exists. 2. Write a tokenizer (parser is not really needed) and have it identify the occurrence of main with one of the appropriate signatures at top level. 3. Use compiler's json output. 4. Use a low-tech search such as sed to find main. I fear that 2-4 would slow things down and add complexity. Probably 1 would be the best choice. I'll ask Walter.

Thank you for taking this into account. Indeed, asking the compiler is the best solution, but may require some work and testing, I guess. For a non-perfect solution (because would not work in 100% cases), just detecting "\nint main" or "\nvoid main" in file would nearly always work, don't you think? (Possibly adding some opt whitespace in the pattern to catch even more cases.) Or are there issues I'm not aware of. (Else, I would be happy with this, but it's only me.) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com

class Tier { private int mainValue; private int secondaryValue; int main(int factor) const { return mainValue * factor; } // ^ int secondary(int factor) const { return secondaryValue * factor; } ... }

You are right, but this case would correctly not be caught (as long as the search pattern does not allow free whitespace at start of main's header line), because you properly indented the class's definition. Something like (untested -- and I don't know yet D's regexes): auto mainSearchPattern = r"^(int/void)[ \t]+main[ \t]*("; Now, we cannot prevent anyone to write Hello, world as // my first program in d ///////////////////////////////////////////////////////////// void main (){ ///////////////////////////////////////////////////////////// writeln("Hello, world!");} What I imagine is (0) if no --main in cmdline, pass this phase, else (1) read the (top/passed) module into a string (2) search for main() using a paatern like this one (3) if not found, append "\nvoid main () {}\n".

Your plan doesn't account for compile-time programming. E.g.: mixin template addMain() { import std.stdio; void main() { writeln("Your regex won't find me..."); } } mixin addMain; There are several other ways that "main" could be added in a non-literal way. In short, regexes are too brittle for this. The JSON output that Andrei mentioned is IMHO your best bet, until we get support from the compiler. Best, Graham
Nov 23 2010
prev sibling parent spir <denis.spir gmail.com> writes:
On Tue, 23 Nov 2010 14:43:57 +0000 (UTC)
Graham Fawcett <fawcett uwindsor.ca> wrote:

 On Tue, 23 Nov 2010 11:02:19 +0100, spir wrote:
=20
 On Tue, 23 Nov 2010 04:44:51 +0800
 KennyTM~ <kennytm gmail.com> wrote:
=20
 On Nov 23, 10 04:38, spir wrote:
 On Mon, 22 Nov 2010 13:28:51 -0600
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:

 On 11/22/10 12:53 PM, spir wrote:
 Hello,


 The rdmd option --main is really helpful to test modules
 independently (it adds an empty main() to prevent the linker from
 crying). An issue is that each time we switch between .d files that
 have no main() (modules in tended for export) and app files that
 have one, this option must be set or removed (else the linker
 complains for having 2 main()). This is not very practicle for
 rapid edit-test cycles -- for "exploratory" programming in general.
 Would it be difficult for rdmd to detect whether a main is already
 present? It is not a big issue anyway -- just in case would be
 easy.

That feature could be added in several ways. 1. Cooperate with the compiler - have the compiler detect whether or not main() exists. 2. Write a tokenizer (parser is not really needed) and have it identify the occurrence of main with one of the appropriate signatures at top level. 3. Use compiler's json output. 4. Use a low-tech search such as sed to find main. I fear that 2-4 would slow things down and add complexity. Probably 1 would be the best choice. I'll ask Walter.

Thank you for taking this into account. Indeed, asking the compiler is the best solution, but may require some work and testing, I guess. For a non-perfect solution (because would not work in 100% cases), just detecting "\nint main" or "\nvoid main" in file would nearly always work, don't you think? (Possibly adding some opt whitespace in the pattern to catch even more cases.) Or are there issues I'm not aware of. (Else, I would be happy with this, but it's only me.) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com

=20 class Tier { private int mainValue; private int secondaryValue; int main(int factor) const { return mainValue * factor; } // ^ int secondary(int factor) const { return secondaryValue * factor; } ... }

You are right, but this case would correctly not be caught (as long as the search pattern does not allow free whitespace at start of main's header line), because you properly indented the class's definition. Something like (untested -- and I don't know yet D's regexes): auto mainSearchPattern =3D r"^(int/void)[ \t]+main[ \t]*("; Now, we cannot prevent anyone to write Hello, world as =20 // my first program in d ///////////////////////////////////////////////////////////// void main (){ ///////////////////////////////////////////////////////////// writeln("Hello, world!");} =20 What I imagine is (0) if no --main in cmdline, pass this phase, else (1) read the (top/passed) module into a string (2) search for main() using a paatern like this one (3) if not found, append "\nvoid main () {}\n".

Your plan doesn't account for compile-time programming. E.g.: =20 mixin template addMain() { import std.stdio; void main() { writeln("Your regex won't find me..."); } } =20 mixin addMain; =20 There are several other ways that "main" could be added in a non-literal way. In short, regexes are too brittle for this. The JSON output that Andrei mentioned is IMHO your best bet, until we get support from the compiler.

Right. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 23 2010