Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Bug 3952d: __ctfeWrite #692

Open
wants to merge 3 commits into from

13 participants

kennytm David Nadlinger Daniel Murphy Don Clugston Martin Nowak Walter Bright Andrei Alexandrescu IgorStepanov Timothee Cour H. S. Teoh bearophile Jonathan Crapuchettes Yuriy Glukhov
kennytm

(This is equivalent to #296, except that I have rebased the changes on top of the master HEAD again. Please see #296 for more comments.)


Make DMD recognize the __ctfeWrite function at interpret-time, and print the arguments to console when used.

Note: D-Programming-Language/druntime#155 need to be pulled as well.

For example, the code

bool x() {
  foreach (i; 0 .. 4)
    __ctfeWriteln(i, "^^2 == ", i*i);
  return true;
}
enum _ = x();

will print

0^^2 == 0
1^^2 == 1
2^^2 == 4
3^^2 == 9

when compiling.

This is not a replacement of pragma(msg).


(BTW, Phobos's writeln can still behave like #237 by adding a CTFE version:

void write(T...)(T x) {
      if (__ctfe)
        __ctfeWrite(x);
      else
        stdout.write(x);
}

)

kennytm kennytm referenced this pull request
Closed

Bug 3952d: __ctfeWriteln #296

David Nadlinger
Collaborator

I already commented on the first incarnation of the pull request, but since I think it is important, I'll do again again: Is it really wise to force appending a newline on every call? See #296 (comment).

Daniel Murphy
Collaborator

You don't need to open a new pull request when you rebase, you can just git push origin branch -f to update the branch, and the pull request.

kennytm

@yebblies I'm not sure if doing that will cause the comments in the request to disappear.

@klickverbot I think it's better to provide the writeln first, and if people do have a lot of request for the write that worths the cost of adding another function, we could add that later.

David Nadlinger
Collaborator

@kennytm If we provide write first, we won't ever have to add a second blessed function…

kennytm

@klickverbot That's because the 2nd one was already there. But if no one uses the write, it's just a waste.

Daniel Murphy
Collaborator

@kennytm It will sometimes make comments disappear if they are on the actual commits and the rebase replaces them, but I've never seen the comments on the actual pull request (like this one) disappear.

kennytm kennytm referenced this pull request in D-Programming-Language/druntime
Merged

fix Issue 3952 part 4: Add __ctfeWrite and __ctfeWriteln. #155

kennytm

Rebased since cc7f6eb broke the merge, and added __ctfeWrite.

(Also, combined all those ddocX-postscript.sh files since they share the same code anyway...)

Don Clugston
Collaborator

This will cause segfaults. toChars() doesn't necessarily work on CTFE internal variables. Especially not pointers and ref parameters.

kennytm

@donc Can you given some explicit examples where the toChars() does not work? Thanks.

Don Clugston
Collaborator

It cannot possibly work when given a pointer (except when the pointer is NULL). CTFE pointers don't have addresses.
int a = 2;
int *x = &a;
_ctfeWritefln(x); // what is this supposed to do?

kennytm

@donc Currently it prints

a

which might be misleading, but not segfault.

Don Clugston
Collaborator

More complicated cases will segfault (eg, if a pointer inside an array points to the first element of that array), but that's not really the point -- it's just wrong. CTFE variables can contain values which have no representation outside of CTFE. Unfortunately, that applies to arrays, structs, and classes, which can also contain pointers.

kennytm

@donc That still doesn't crash:

class K
{
    void*[] r;
}

struct S
{
    void* p;
    K k;
}

int g()
{
    auto k = new K;
    void*[] arr = [];
    arr ~= arr.ptr;
    auto s = S(arr.ptr, k);
    __ctfeWriteln(s);
    return 0;
}

enum k = g();

void main()
{
}

prints

S([[][0LU]][0LU],TOK232)

If something does crash with __ctfeWriteln, it will crash pragma(msg, ...) too, because the two share the same function for printing an expression.


And it doesn't matter whether the value has no representation outside of CTFE, because __ctfeWriteln is mainly used for debugging CTFE code anyway. The function itself is a no-op outside of CTFE.

Don Clugston
Collaborator
kennytm

@donc Sorry I don't trust you ☺. If DMD segfaults, it would be a bug of DMD (e.g. bug 7568), not this pull request.

kennytm added some commits
kennytm kennytm fix Issue 3952 part 4: Add __ctfeWrite at for printing at intepret time.
This is similar to #237, but now it doesn't "rely" on Phobos. Phobos's writeln
can still use #237's behavior by using something like

    void write(T...)(T x) {
      if (__ctfe)
        __ctfeWrite(x);
      else
        stdout.write(x);
    }
6d2dcfe
kennytm kennytm Added __ctfeWrite; Test cases: Combine all compilable/*-postscript.sh…
… files.
67d4435
kennytm kennytm Test cases for __ctfeWrite[ln]. 117447e
Martin Nowak
Collaborator

Please consider to change the implementation so that __ctfeWriteln only accepts string arguments.

kennytm

@dawgfoto Why? pragma(msg, ...) supports any arguments, std.stdio.writeln supports any arguments, why __ctfeWriteln should only support string argument?

Martin Nowak
Collaborator

Yes ctfeWriteln should do the same as stdio.writeln, i.e. formatting value by using conversion
functions. Most of which can be done using conv.to or formattedWrite.
This ensures that you inspect values and types only through their
public interface and not by any compiler internal functions.

int ctfe()
{
    import std.conv;
    int i;
    __ctfeWriteln(to!string(i));
    return 0;
}
enum trigger = ctfe();

prints:
['0'][0LU..1LU]
Which is the current state of an array literal slice?

CTFE literals are in a not-yet-frozen state during interpretation
which makes them break some invariants of the rest of the compiler.
See Bug 7784 for an example.

Don Clugston
Collaborator

This ensures that you inspect values and types only through their public interface and not by any compiler internal functions.

That's not a problem, using toChars() is exactly the same thing you see in any error message (and it is what pragma(msg) uses). The problem is that in CTFE I've abused some of the expression types, and the existing toChars() doesn't cope with that, which is why I'd rather this didn't get merged just yet. It's not too hard to fix, because the number of expression types in CTFE is very small (int, float, complex, stringliteral, arrayliteral, struct, class, delegate, AAliteral, pointer to array, pointer to variable, slice of array).
OTOH allowing only strings would make it really slow for anything else, extremely slow for floating point, and it would be impossible to print pointers. I see this almost solely as a debugging aid, and that would cripple it for that.

Brad Roberts braddr referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Walter Bright

Can this functionality be done with a combination of testing __ctfe and pragma(msg) ?

Daniel Murphy
Collaborator

@WalterBright No, pragma(msg) runs during semantic, not every time the statement is interpreted.

David Nadlinger
Collaborator

@WalterBright: What @yebblies said – the value of __ctfeWrite is in that it allows printing of »runtime« values during CTFE. pragma(msg, ...) would only print the variable/expression name once during semantic analysis.

Andrei Alexandrescu
Owner

ping on this

Andrei Alexandrescu
Owner

reping

IgorStepanov

What is the resolution on this issue? Do __ctfeWrite should accept all types arguments (and process they into DMD) or __ctfeWrite should accept only one string and __ctfe writeln version should use a format function?

Timothee Cour

could we just make write/writeln work at CT (possibly in terms of __ctfeWrite) and not make it a special symbol? Ie, std.stdio would have to import std.ctfe module to access __ctfeWrite.

H. S. Teoh

@timotheecour I like the idea of implementing std.stdio.writeln in terms of ctfeWrite during CTFE. It's better to avoid the proliferation of more special __xxx symbols in the language. As long as ctfeWrite can output strings, that's good enough, let std.format take care of the formatting / conversions.

bearophile

The basic need is to print strings, without newline at the end.

If you only have a function that always adds the newline (as puts and pragma(msg) do) but you don't want to print the newline (because you are printing some complex structure like a matrix, or a tree, or more one piece at a time) then in some cases you are forced to build a large string at compile-time before printing, and this is quite bad, also because currently at compile time the memory management of large strings not good. Having a second tiny function that also prints the newline is handy.

If you also want to support the printing of things different from strings, this is handy, but if Don says this could cause problems, then we can live without it, it's not an essential feature, because you can often call to!string first.

bearophile

This feature is quite needed, what's missing before it's added to dmd?

Jonathan Crapuchettes

Do the merge conflicts and failed tests just need to be fixed for inclusion?

H. S. Teoh

ping @donc
Are we going to move ahead with this, or should we just close this as rejected?

Yuriy Glukhov

Ping and +1 to implement ctfeWrite instead of ctfeWriteln, which may be trivially implemented on top of ctfeWrite.

Martin Nowak
Collaborator

As mentioned above I think __ctfeWrite should only accept string arguments. The for printing non-string arguments we could adopt std.stdio.writeln to work in CTFE.

IgorStepanov

As mentioned above I think __ctfeWrite should only accept string arguments. The for printing non-string arguments we could adopt std.stdio.writeln to work in CTFE.

BTW, float formatting can be implemented in CTFE now, because yl2x has been implemented. There still alive only one objection: some one may want to print a pointer at CTFE (anyone unique object id). However we may add a special debug function string ctfePointerToString(void*) if it will be consider needed. Thus we may implement ctfeWrite only for string and add pointer hack in future if it will be needed.

bearophile

Allowing __ctfeWrite to write only strings is acceptable as first step. It's a reasonable scope reduction to push __ctfeWrite inside the compiler, and it leaves space to add a successive __ctfeWritef/__ctfeWritefln with formatting of different types.

Printing pointers at compile-time is probably useful because if you can allocate memory at compile-time you also want to print the pointers to debug, like to find the ones that are equal to each other. But this need is much less significant than having a good enough string printing.

Regarding the name __ctfeWrite is it necessary to have the two leading underscores? For standard stuff that's supposed to be present in all compilers like ctfeWrite I'd prefer a nicer name without those underscores.

David Nadlinger
Collaborator

Regarding the name __ctfeWrite is it necessary to have the two leading underscores?

Yes, as it must not collide with user-defined names.

Martin Nowak
Collaborator

Allowing __ctfeWrite to write only strings is acceptable as first step. It's a reasonable scope reduction to push __ctfeWrite inside the compiler, and it leaves space to add a successive __ctfeWritef/__ctfeWritefln with formatting of different types.

Everything else can be implemented using std.stdio.writeln and std.stdio.writefln.

bearophile

@klickverbot: > Yes, as it must not collide with user-defined names.

I think in this case the risks of a collision can't justify giving a so much bad looking name. If an user defines a ctfeWritef then his/her name definition overwrites the built-in function. What's bad in this? It's a quite uncommon name...

Martin Nowak
Collaborator

It's also __ctfe and you aren't supposed to use __ctfeWrite directly but writeln and writefln.

IgorStepanov

I suggest simply implement ctfeWrite with one string argument. All other logic can be implemented inside library. Lets do it so and will see how it will work.
We will able to add new functionality at any time.

Martin Nowak
Collaborator

13 participants

Anyone willing to actually do it?

IgorStepanov

@MartinNowak Ok, I'll do it once I find the time. (1-2 weeks, I hope).
O.T. When you finish review and merge #3904?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 10, 2012
  1. kennytm

    fix Issue 3952 part 4: Add __ctfeWrite at for printing at intepret time.

    kennytm authored
    This is similar to #237, but now it doesn't "rely" on Phobos. Phobos's writeln
    can still use #237's behavior by using something like
    
        void write(T...)(T x) {
          if (__ctfe)
            __ctfeWrite(x);
          else
            stdout.write(x);
        }
  2. kennytm
  3. kennytm
This page is out of date. Refresh to see the latest.
Showing with 156 additions and 253 deletions.
  1. +1 −22 src/attrib.c
  2. +29 −0 src/expression.c
  3. +2 −0  src/expression.h
  4. +1 −0  src/idgen.c
  5. +15 −4 src/interpret.c
  6. +1 −22 src/statement.c
  7. +6 −2 test/Makefile
  8. +10 −0 test/compilable/ctfeWriteln.sh
  9. +1 −1  test/compilable/ddoc1.d
  10. +1 −1  test/compilable/ddoc10.d
  11. +2 −2 test/compilable/ddoc11.d
  12. +1 −1  test/compilable/ddoc12.d
  13. +1 −1  test/compilable/ddoc13.d
  14. +2 −2 test/compilable/ddoc14.d
  15. +1 −1  test/compilable/ddoc2.d
  16. +2 −2 test/compilable/ddoc3.d
  17. +1 −1  test/compilable/ddoc4.d
  18. +3 −3 test/compilable/ddoc5.d
  19. +1 −1  test/compilable/ddoc6.d
  20. +1 −1  test/compilable/ddoc6491.d
  21. +1 −1  test/compilable/ddoc7.d
  22. +1 −1  test/compilable/ddoc8.d
  23. +1 −1  test/compilable/ddoc9.d
  24. +19 −0 test/compilable/extra-files/ctfeWriteln.d
  25. +8 −0 test/compilable/extra-files/ctfeWriteln.txt
  26. +0 −10 test/compilable/extra-files/ddoc1-postscript.sh
  27. +0 −10 test/compilable/extra-files/ddoc10-postscript.sh
  28. +0 −10 test/compilable/extra-files/ddoc11-postscript.sh
  29. +0 −10 test/compilable/extra-files/ddoc12-postscript.sh
  30. +0 −10 test/compilable/extra-files/ddoc13-postscript.sh
  31. +0 −10 test/compilable/extra-files/ddoc14-postscript.sh
  32. +0 −10 test/compilable/extra-files/ddoc2-postscript.sh
  33. +0 −10 test/compilable/extra-files/ddoc3-postscript.sh
  34. +0 −10 test/compilable/extra-files/ddoc4-postscript.sh
  35. +0 −10 test/compilable/extra-files/ddoc5-postscript.sh
  36. +0 −10 test/compilable/extra-files/ddoc6-postscript.sh
  37. +0 −10 test/compilable/extra-files/ddoc7-postscript.sh
  38. +0 −10 test/compilable/extra-files/ddoc8-postscript.sh
  39. +0 −10 test/compilable/extra-files/ddoc9-postscript.sh
  40. +0 −10 test/compilable/extra-files/ddocAny-postscript.sh
  41. +41 −0 test/compilable/extra-files/diff-postscript.sh
  42. +0 −10 test/compilable/extra-files/header-postscript.sh
  43. +0 −10 test/compilable/extra-files/json-postscript.sh
  44. +0 −10 test/compilable/extra-files/xheader-postscript.sh
  45. +1 −1  test/compilable/header.d
  46. +1 −1  test/compilable/json.d
  47. +1 −1  test/compilable/xheader.d
23 src/attrib.c
View
@@ -971,28 +971,7 @@ void PragmaDeclaration::semantic(Scope *sc)
if (ident == Id::msg)
{
if (args)
- {
- for (size_t i = 0; i < args->dim; i++)
- {
- Expression *e = (*args)[i];
-
- e = e->semantic(sc);
- if (e->op != TOKerror)
- e = e->optimize(WANTvalue | WANTinterpret);
- if (e->op == TOKerror)
- { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
- return;
- }
- StringExp *se = e->toString();
- if (se)
- {
- fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
- }
- else
- fprintf(stdmsg, "%s", e->toChars());
- }
- fprintf(stdmsg, "\n");
- }
+ printExpressionsToStdmsg(loc, args, sc);
goto Lnodecl;
}
else if (ident == Id::lib)
29 src/expression.c
View
@@ -1144,6 +1144,35 @@ void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *h
}
}
+/**************************************************
+ * Print expressions to stdmsg, used by pragma(msg).
+ */
+
+void printExpressionsToStdmsg(Loc loc, Expressions *args, Scope *sc, bool printNewLine)
+{
+ for (size_t i = 0; i < args->dim; i++)
+ {
+ Expression *e = (*args)[i];
+ if (sc)
+ {
+ e = e->semantic(sc);
+ if (e->op != TOKerror)
+ e = e->optimize(WANTvalue | WANTinterpret);
+ if (e->op == TOKerror)
+ { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
+ return;
+ }
+ }
+ StringExp *se = e->toString();
+ if (se)
+ fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
+ else
+ fprintf(stdmsg, "%s", e->toChars());
+ }
+ if (printNewLine)
+ fprintf(stdmsg, "\n");
+}
+
/******************************** Expression **************************/
Expression::Expression(Loc loc, enum TOK op, int size)
2  src/expression.h
View
@@ -83,6 +83,8 @@ void modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
Expression *resolveAliasThis(Scope *sc, Expression *e);
#endif
+void printExpressionsToStdmsg(Loc loc, Expressions *args, Scope *sc, bool printNewLine=true);
+
/* Interpreter: what form of return value expression is required?
*/
enum CtfeGoal
1  src/idgen.c
View
@@ -57,6 +57,7 @@ Msgtable msgtable[] =
{ "funcptr" },
{ "dollar", "__dollar" },
{ "ctfe", "__ctfe" },
+ { "ctfeWrite", "__ctfeWrite" },
{ "offset" },
{ "offsetof" },
{ "ModuleInfo" },
19 src/interpret.c
View
@@ -6247,6 +6247,8 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
return eresult;
}
+
+
/* If this is a built-in function, return the interpreted result,
* Otherwise, return NULL.
*/
@@ -6270,7 +6272,8 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
if (!pthis)
{
enum BUILTIN b = fd->isBuiltin();
- if (b)
+ bool isCTFEWrite = fd->ident == Id::ctfeWrite;
+ if (b || isCTFEWrite)
{ Expressions args;
args.setDim(nargs);
for (size_t i = 0; i < args.dim; i++)
@@ -6281,9 +6284,17 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
return earg;
args.tdata()[i] = earg;
}
- e = eval_builtin(loc, b, &args);
- if (!e)
- e = EXP_CANT_INTERPRET;
+ if (isCTFEWrite)
+ {
+ printExpressionsToStdmsg(loc, &args, NULL, /*printNewLine*/false);
+ e = EXP_VOID_INTERPRET;
+ }
+ else
+ {
+ e = eval_builtin(loc, b, &args);
+ if (!e)
+ e = EXP_CANT_INTERPRET;
+ }
}
}
/* Horrid hack to retrieve the builtin AA functions after they've been
23 src/statement.c
View
@@ -2748,28 +2748,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
if (ident == Id::msg)
{
if (args)
- {
- for (size_t i = 0; i < args->dim; i++)
- {
- Expression *e = (*args)[i];
-
- e = e->semantic(sc);
- if (e->op != TOKerror)
- e = e->optimize(WANTvalue | WANTinterpret);
- if (e->op == TOKerror)
- { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
- goto Lerror;
- }
- StringExp *se = e->toString();
- if (se)
- {
- fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
- }
- else
- fprintf(stdmsg, "%s", e->toChars());
- }
- fprintf(stdmsg, "\n");
- }
+ printExpressionsToStdmsg(loc, args, sc);
}
else if (ident == Id::lib)
{
8 test/Makefile
View
@@ -107,7 +107,7 @@ endif
runnable_tests=$(wildcard runnable/*.d) $(wildcard runnable/*.html) $(wildcard runnable/*.sh)
runnable_test_results=$(addsuffix .out,$(addprefix $(RESULTS_DIR)/,$(runnable_tests)))
-compilable_tests=$(wildcard compilable/*.d)
+compilable_tests=$(wildcard compilable/*.d) $(wildcard compilable/*.sh)
compilable_test_results=$(addsuffix .out,$(addprefix $(RESULTS_DIR)/,$(compilable_tests)))
fail_compilation_tests=$(wildcard fail_compilation/*.d)
@@ -134,6 +134,10 @@ $(RESULTS_DIR)/runnable/%.sh.out: runnable/%.sh $(RESULTS_DIR)/.created $(RESULT
$(RESULTS_DIR)/compilable/%.d.out: compilable/%.d $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test $(DMD)
$(QUIET) ./$(RESULTS_DIR)/d_do_test $(<D) $* d
+$(RESULTS_DIR)/compilable/%.sh.out: compilable/%.sh $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test $(DMD)
+ $(QUIET) echo " ... $(<D)/$*.sh"
+ $(QUIET) ./$(<D)/$*.sh
+
$(RESULTS_DIR)/fail_compilation/%.d.out: fail_compilation/%.d $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test $(DMD)
$(QUIET) ./$(RESULTS_DIR)/d_do_test $(<D) $* d
@@ -145,7 +149,7 @@ clean:
$(QUIET)if [ -e $(RESULTS_DIR) ]; then rm -rf $(RESULTS_DIR); fi
$(RESULTS_DIR)/.created:
- @echo Creating output directory: $(RESULTS_DIR)
+ @echo Creating output directory: $(RESULTS_DIR)
$(QUIET)if [ ! -d $(RESULTS_DIR) ]; then mkdir $(RESULTS_DIR); fi
$(QUIET)if [ ! -d $(RESULTS_DIR)/runnable ]; then mkdir $(RESULTS_DIR)/runnable; fi
$(QUIET)if [ ! -d $(RESULTS_DIR)/compilable ]; then mkdir $(RESULTS_DIR)/compilable; fi
10 test/compilable/ctfeWriteln.sh
View
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+result_file=${RESULTS_DIR}/compilable/ctfeWriteln.txt
+source_file=compilable/extra-files/ctfeWriteln.d
+$DMD -m${MODEL} $x -c -o- $source_file 2> $result_file
+if [ $? -ne 0 ]; then
+ exit 1;
+fi
+compilable/extra-files/diff-postscript.sh ctfeWriteln.txt
+
2  test/compilable/ddoc1.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc1-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc1.html
// REQUIRED_ARGS: -d
/** This module is for ABC
2  test/compilable/ddoc10.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc10-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc10.html
// 294
4 test/compilable/ddoc11.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc11-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc11.html
/// The various floating point exceptions
enum
@@ -49,7 +49,7 @@ struct lldiv_t { long quot,rem; }
- void *calloc(size_t, size_t); ///
+ void *calloc(size_t, size_t); ///
void *malloc(size_t); /// dittx
/**
2  test/compilable/ddoc12.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc12-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc12.html
int ruhred; /// This documents correctly.
int rühred; /// This should too
2  test/compilable/ddoc13.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc13-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc13.html
/// struct doc
struct Bug4107(T)
4 test/compilable/ddoc14.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc14-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc14.html
alias void V;
@@ -77,7 +77,7 @@ interface Interface {
V mColon(lazy P p) ; /// 10
}
+/
-
+
public P variable; /// 0
V mNone(lazy P p) {} /// 1
pure nothrow V mPrefix(lazy P p) {} /// 2
2  test/compilable/ddoc2.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc2-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc2.html
/**
* Summary
4 test/compilable/ddoc3.d
View
@@ -1,7 +1,7 @@
// EXTRA_SOURCES: extra-files/ddoc3.ddoc
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc3-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc3.html
/**
* Summary
@@ -42,7 +42,7 @@
* $(TROW 4, 5, 6)
* )
*
- * $(D_CODE
+ * $(D_CODE
$(B pragma)( $(I name) );
$(B pragma)( $(I name) , $(I option) [ $(I option) ] );
$(U $(LPAREN))
2  test/compilable/ddoc4.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc4-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc4.html
/**
a
6 test/compilable/ddoc5.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc5-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc5.html
/**
@@ -15,10 +15,10 @@ class TestMembers(TemplateArg)
public:
/**
- a static method
+ a static method
Params: idx = index
-
+
*/
static void PublicStaticMethod(int idx)
{
2  test/compilable/ddoc6.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc6-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc6.html
/**
*
2  test/compilable/ddoc6491.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh 6491
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc6491.html
module ddoc6491;
2  test/compilable/ddoc7.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc7-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc7.html
//-----------------------------------------------
/// my enum
2  test/compilable/ddoc8.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc8-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc8.html
/** foo */
2  test/compilable/ddoc9.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
-// POST_SCRIPT: compilable/extra-files/ddoc9-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc9.html
// 273
19 test/compilable/extra-files/ctfeWriteln.d
View
@@ -0,0 +1,19 @@
+// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh
+
+int sum_of_sq(int x) pure nothrow @safe
+{
+ int result = 0;
+ foreach (i; 0 .. x)
+ {
+ __ctfeWrite(i, "^^2 == ");
+ int power = i ^^ 2;
+ __ctfeWriteln(power);
+ result += power;
+ }
+ __ctfeWriteln("result == ", result);
+ return result;
+
+}
+
+static assert(sum_of_sq(7) == 91);
+
8 test/compilable/extra-files/ctfeWriteln.txt
View
@@ -0,0 +1,8 @@
+0^^2 == 0
+1^^2 == 1
+2^^2 == 4
+3^^2 == 9
+4^^2 == 16
+5^^2 == 25
+6^^2 == 36
+result == 91
10 test/compilable/extra-files/ddoc1-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc1.html > ${RESULTS_DIR}/compilable/ddoc1.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc1.html ${RESULTS_DIR}/compilable/ddoc1.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc1.html{,.2}
-
10 test/compilable/extra-files/ddoc10-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc10.html > ${RESULTS_DIR}/compilable/ddoc10.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc10.html ${RESULTS_DIR}/compilable/ddoc10.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc10.html{,.2}
-
10 test/compilable/extra-files/ddoc11-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc11.html > ${RESULTS_DIR}/compilable/ddoc11.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc11.html ${RESULTS_DIR}/compilable/ddoc11.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc11.html{,.2}
-
10 test/compilable/extra-files/ddoc12-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc12.html > ${RESULTS_DIR}/compilable/ddoc12.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc12.html ${RESULTS_DIR}/compilable/ddoc12.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc12.html{,.2}
-
10 test/compilable/extra-files/ddoc13-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc13.html > ${RESULTS_DIR}/compilable/ddoc13.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc13.html ${RESULTS_DIR}/compilable/ddoc13.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc13.html{,.2}
-
10 test/compilable/extra-files/ddoc14-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc14.html > ${RESULTS_DIR}/compilable/ddoc14.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc14.html ${RESULTS_DIR}/compilable/ddoc14.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc14.html{,.2}
-
10 test/compilable/extra-files/ddoc2-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc2.html > ${RESULTS_DIR}/compilable/ddoc2.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc2.html ${RESULTS_DIR}/compilable/ddoc2.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc2.html{,.2}
-
10 test/compilable/extra-files/ddoc3-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc3.html > ${RESULTS_DIR}/compilable/ddoc3.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc3.html ${RESULTS_DIR}/compilable/ddoc3.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc3.html{,.2}
-
10 test/compilable/extra-files/ddoc4-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc4.html > ${RESULTS_DIR}/compilable/ddoc4.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc4.html ${RESULTS_DIR}/compilable/ddoc4.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc4.html{,.2}
-
10 test/compilable/extra-files/ddoc5-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc5.html > ${RESULTS_DIR}/compilable/ddoc5.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc5.html ${RESULTS_DIR}/compilable/ddoc5.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc5.html{,.2}
-
10 test/compilable/extra-files/ddoc6-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc6.html > ${RESULTS_DIR}/compilable/ddoc6.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc6.html ${RESULTS_DIR}/compilable/ddoc6.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc6.html{,.2}
-
10 test/compilable/extra-files/ddoc7-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc7.html > ${RESULTS_DIR}/compilable/ddoc7.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc7.html ${RESULTS_DIR}/compilable/ddoc7.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc7.html{,.2}
-
10 test/compilable/extra-files/ddoc8-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc8.html > ${RESULTS_DIR}/compilable/ddoc8.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc8.html ${RESULTS_DIR}/compilable/ddoc8.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc8.html{,.2}
-
10 test/compilable/extra-files/ddoc9-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc9.html > ${RESULTS_DIR}/compilable/ddoc9.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc9.html ${RESULTS_DIR}/compilable/ddoc9.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc9.html{,.2}
-
10 test/compilable/extra-files/ddocAny-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-GREP_OPTIONS= grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc$1.html > ${RESULTS_DIR}/compilable/ddoc$1.html.2
-diff --strip-trailing-cr compilable/extra-files/ddoc$1.html ${RESULTS_DIR}/compilable/ddoc$1.html.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/ddoc$1.html{,.2}
-
41 test/compilable/extra-files/diff-postscript.sh
View
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+if [ $# -le 0 ]; then
+ echo "Usage: $0 [filename]"
+ echo ""
+ echo "This tool is used to check if two generated files are the same."
+ exit 2
+fi
+
+case $1 in
+ *.html)
+ filter_string="Generated by Ddoc from"
+ ;;
+ *.di)
+ filter_string="D import file generated from"
+ ;;
+ json.out)
+ filter_string="\"file\" : "
+ ;;
+ *)
+ filter_string=
+ ;;
+esac
+
+generated=${RESULTS_DIR}/compilable/$1
+filtered=${RESULTS_DIR}/compilable/$1.2
+expected=compilable/extra-files/$1
+
+if [ -n "$filter_string" ]; then
+ GREP_OPTIONS= grep -v "$filter_string" $generated > $filtered
+else
+ cp $generated $filtered
+fi
+
+diff -u --strip-trailing-cr $expected $filtered
+if [ $? -ne 0 ]; then
+ exit 1;
+fi
+
+rm $filtered $generated
+
10 test/compilable/extra-files/header-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "D import file generated from" ${RESULTS_DIR}/compilable/header.di > ${RESULTS_DIR}/compilable/header.di.2
-diff --strip-trailing-cr compilable/extra-files/header.di ${RESULTS_DIR}/compilable/header.di.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/header.di{,.2}
-
10 test/compilable/extra-files/json-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "\"file\" : " ${RESULTS_DIR}/compilable/json.out > ${RESULTS_DIR}/compilable/json.out.2
-diff --strip-trailing-cr compilable/extra-files/json.out ${RESULTS_DIR}/compilable/json.out.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/json.out{,.2}
-
10 test/compilable/extra-files/xheader-postscript.sh
View
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-grep -v "D import file generated from" ${RESULTS_DIR}/compilable/xheader.di > ${RESULTS_DIR}/compilable/xheader.di.2
-diff --strip-trailing-cr compilable/extra-files/xheader.di ${RESULTS_DIR}/compilable/xheader.di.2
-if [ $? -ne 0 ]; then
- exit 1;
-fi
-
-rm ${RESULTS_DIR}/compilable/xheader.di{,.2}
-
2  test/compilable/header.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -H -Hdtest_results/compilable
-// POST_SCRIPT: compilable/extra-files/header-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh header.di
// REQUIRED_ARGS: -d
module foo.bar;
2  test/compilable/json.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -o- -X -Xftest_results/compilable/json.out
-// POST_SCRIPT: compilable/extra-files/json-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh json.out
struct X;
2  test/compilable/xheader.d
View
@@ -1,6 +1,6 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -H -Hdtest_results/compilable
-// POST_SCRIPT: compilable/extra-files/xheader-postscript.sh
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh xheader.di
// for D 2.0 only
Something went wrong with that request. Please try again.