Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Bug 3952d: __ctfeWrite #692

Open
wants to merge 3 commits into from

11 participants

kennytm David Nadlinger Daniel Murphy Don Clugston Martin Nowak Walter Bright Andrei Alexandrescu IgorStepanov Timothee Cour H. S. Teoh bearophile
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);
}

)

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 February 19, 2012
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.

added some commits August 08, 2011
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 Added __ctfeWrite; Test cases: Combine all compilable/*-postscript.sh…
… files.
67d4435
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
donc commented March 29, 2012

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 October 21, 2012
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 3 unique commits by 1 author.

Mar 10, 2012
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 Added __ctfeWrite; Test cases: Combine all compilable/*-postscript.sh…
… files.
67d4435
kennytm Test cases for __ctfeWrite[ln]. 117447e
This page is out of date. Refresh to see the latest.

Showing 47 changed files with 156 additions and 253 deletions. Show diff stats Hide diff stats

  1. 23  src/attrib.c
  2. 29  src/expression.c
  3. 2  src/expression.h
  4. 1  src/idgen.c
  5. 19  src/interpret.c
  6. 23  src/statement.c
  7. 8  test/Makefile
  8. 10  test/compilable/ctfeWriteln.sh
  9. 2  test/compilable/ddoc1.d
  10. 2  test/compilable/ddoc10.d
  11. 4  test/compilable/ddoc11.d
  12. 2  test/compilable/ddoc12.d
  13. 2  test/compilable/ddoc13.d
  14. 4  test/compilable/ddoc14.d
  15. 2  test/compilable/ddoc2.d
  16. 4  test/compilable/ddoc3.d
  17. 2  test/compilable/ddoc4.d
  18. 6  test/compilable/ddoc5.d
  19. 2  test/compilable/ddoc6.d
  20. 2  test/compilable/ddoc6491.d
  21. 2  test/compilable/ddoc7.d
  22. 2  test/compilable/ddoc8.d
  23. 2  test/compilable/ddoc9.d
  24. 19  test/compilable/extra-files/ctfeWriteln.d
  25. 8  test/compilable/extra-files/ctfeWriteln.txt
  26. 10  test/compilable/extra-files/ddoc1-postscript.sh
  27. 10  test/compilable/extra-files/ddoc10-postscript.sh
  28. 10  test/compilable/extra-files/ddoc11-postscript.sh
  29. 10  test/compilable/extra-files/ddoc12-postscript.sh
  30. 10  test/compilable/extra-files/ddoc13-postscript.sh
  31. 10  test/compilable/extra-files/ddoc14-postscript.sh
  32. 10  test/compilable/extra-files/ddoc2-postscript.sh
  33. 10  test/compilable/extra-files/ddoc3-postscript.sh
  34. 10  test/compilable/extra-files/ddoc4-postscript.sh
  35. 10  test/compilable/extra-files/ddoc5-postscript.sh
  36. 10  test/compilable/extra-files/ddoc6-postscript.sh
  37. 10  test/compilable/extra-files/ddoc7-postscript.sh
  38. 10  test/compilable/extra-files/ddoc8-postscript.sh
  39. 10  test/compilable/extra-files/ddoc9-postscript.sh
  40. 10  test/compilable/extra-files/ddocAny-postscript.sh
  41. 41  test/compilable/extra-files/diff-postscript.sh
  42. 10  test/compilable/extra-files/header-postscript.sh
  43. 10  test/compilable/extra-files/json-postscript.sh
  44. 10  test/compilable/extra-files/xheader-postscript.sh
  45. 2  test/compilable/header.d
  46. 2  test/compilable/json.d
  47. 2  test/compilable/xheader.d
23  src/attrib.c
@@ -971,28 +971,7 @@ void PragmaDeclaration::semantic(Scope *sc)
971 971
     if (ident == Id::msg)
972 972
     {
973 973
         if (args)
974  
-        {
975  
-            for (size_t i = 0; i < args->dim; i++)
976  
-            {
977  
-                Expression *e = (*args)[i];
978  
-
979  
-                e = e->semantic(sc);
980  
-                if (e->op != TOKerror)
981  
-                    e = e->optimize(WANTvalue | WANTinterpret);
982  
-                if (e->op == TOKerror)
983  
-                {   errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
984  
-                    return;
985  
-                }
986  
-                StringExp *se = e->toString();
987  
-                if (se)
988  
-                {
989  
-                    fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
990  
-                }
991  
-                else
992  
-                    fprintf(stdmsg, "%s", e->toChars());
993  
-            }
994  
-            fprintf(stdmsg, "\n");
995  
-        }
  974
+            printExpressionsToStdmsg(loc, args, sc);
996 975
         goto Lnodecl;
997 976
     }
998 977
     else if (ident == Id::lib)
29  src/expression.c
@@ -1144,6 +1144,35 @@ void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *h
1144 1144
     }
1145 1145
 }
1146 1146
 
  1147
+/**************************************************
  1148
+ * Print expressions to stdmsg, used by pragma(msg).
  1149
+ */
  1150
+
  1151
+void printExpressionsToStdmsg(Loc loc, Expressions *args, Scope *sc, bool printNewLine)
  1152
+{
  1153
+    for (size_t i = 0; i < args->dim; i++)
  1154
+    {
  1155
+        Expression *e = (*args)[i];
  1156
+        if (sc)
  1157
+        {
  1158
+            e = e->semantic(sc);
  1159
+            if (e->op != TOKerror)
  1160
+                e = e->optimize(WANTvalue | WANTinterpret);
  1161
+            if (e->op == TOKerror)
  1162
+            {   errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
  1163
+                return;
  1164
+            }
  1165
+        }
  1166
+        StringExp *se = e->toString();
  1167
+        if (se)
  1168
+            fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
  1169
+        else
  1170
+            fprintf(stdmsg, "%s", e->toChars());
  1171
+    }
  1172
+    if (printNewLine)
  1173
+        fprintf(stdmsg, "\n");
  1174
+}
  1175
+
1147 1176
 /******************************** Expression **************************/
1148 1177
 
1149 1178
 Expression::Expression(Loc loc, enum TOK op, int size)
2  src/expression.h
@@ -83,6 +83,8 @@ void modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
83 83
 Expression *resolveAliasThis(Scope *sc, Expression *e);
84 84
 #endif
85 85
 
  86
+void printExpressionsToStdmsg(Loc loc, Expressions *args, Scope *sc, bool printNewLine=true);
  87
+
86 88
 /* Interpreter: what form of return value expression is required?
87 89
  */
88 90
 enum CtfeGoal
1  src/idgen.c
@@ -57,6 +57,7 @@ Msgtable msgtable[] =
57 57
     { "funcptr" },
58 58
     { "dollar", "__dollar" },
59 59
     { "ctfe", "__ctfe" },
  60
+    { "ctfeWrite", "__ctfeWrite" },
60 61
     { "offset" },
61 62
     { "offsetof" },
62 63
     { "ModuleInfo" },
19  src/interpret.c
@@ -6247,6 +6247,8 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
6247 6247
     return eresult;
6248 6248
 }
6249 6249
 
  6250
+
  6251
+
6250 6252
 /* If this is a built-in function, return the interpreted result,
6251 6253
  * Otherwise, return NULL.
6252 6254
  */
@@ -6270,7 +6272,8 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
6270 6272
     if (!pthis)
6271 6273
     {
6272 6274
         enum BUILTIN b = fd->isBuiltin();
6273  
-        if (b)
  6275
+        bool isCTFEWrite = fd->ident == Id::ctfeWrite;
  6276
+        if (b || isCTFEWrite)
6274 6277
         {   Expressions args;
6275 6278
             args.setDim(nargs);
6276 6279
             for (size_t i = 0; i < args.dim; i++)
@@ -6281,9 +6284,17 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
6281 6284
                     return earg;
6282 6285
                 args.tdata()[i] = earg;
6283 6286
             }
6284  
-            e = eval_builtin(loc, b, &args);
6285  
-            if (!e)
6286  
-                e = EXP_CANT_INTERPRET;
  6287
+            if (isCTFEWrite)
  6288
+            {
  6289
+                printExpressionsToStdmsg(loc, &args, NULL, /*printNewLine*/false);
  6290
+                e = EXP_VOID_INTERPRET;
  6291
+            }
  6292
+            else
  6293
+            {
  6294
+                e = eval_builtin(loc, b, &args);
  6295
+                if (!e)
  6296
+                    e = EXP_CANT_INTERPRET;
  6297
+            }
6287 6298
         }
6288 6299
     }
6289 6300
     /* Horrid hack to retrieve the builtin AA functions after they've been
23  src/statement.c
@@ -2748,28 +2748,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
2748 2748
     if (ident == Id::msg)
2749 2749
     {
2750 2750
         if (args)
2751  
-        {
2752  
-            for (size_t i = 0; i < args->dim; i++)
2753  
-            {
2754  
-                Expression *e = (*args)[i];
2755  
-
2756  
-                e = e->semantic(sc);
2757  
-                if (e->op != TOKerror)
2758  
-                    e = e->optimize(WANTvalue | WANTinterpret);
2759  
-                if (e->op == TOKerror)
2760  
-                {   errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
2761  
-                    goto Lerror;
2762  
-                }
2763  
-                StringExp *se = e->toString();
2764  
-                if (se)
2765  
-                {
2766  
-                    fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
2767  
-                }
2768  
-                else
2769  
-                    fprintf(stdmsg, "%s", e->toChars());
2770  
-            }
2771  
-            fprintf(stdmsg, "\n");
2772  
-        }
  2751
+            printExpressionsToStdmsg(loc, args, sc);
2773 2752
     }
2774 2753
     else if (ident == Id::lib)
2775 2754
     {
8  test/Makefile
@@ -107,7 +107,7 @@ endif
107 107
 runnable_tests=$(wildcard runnable/*.d) $(wildcard runnable/*.html) $(wildcard runnable/*.sh)
108 108
 runnable_test_results=$(addsuffix .out,$(addprefix $(RESULTS_DIR)/,$(runnable_tests)))
109 109
 
110  
-compilable_tests=$(wildcard compilable/*.d)
  110
+compilable_tests=$(wildcard compilable/*.d) $(wildcard compilable/*.sh)
111 111
 compilable_test_results=$(addsuffix .out,$(addprefix $(RESULTS_DIR)/,$(compilable_tests)))
112 112
 
113 113
 fail_compilation_tests=$(wildcard fail_compilation/*.d)
@@ -134,6 +134,10 @@ $(RESULTS_DIR)/runnable/%.sh.out: runnable/%.sh $(RESULTS_DIR)/.created $(RESULT
134 134
 $(RESULTS_DIR)/compilable/%.d.out: compilable/%.d $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test $(DMD)
135 135
 	$(QUIET) ./$(RESULTS_DIR)/d_do_test $(<D) $* d
136 136
 
  137
+$(RESULTS_DIR)/compilable/%.sh.out: compilable/%.sh $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test $(DMD)
  138
+	$(QUIET) echo " ... $(<D)/$*.sh"
  139
+	$(QUIET) ./$(<D)/$*.sh
  140
+
137 141
 $(RESULTS_DIR)/fail_compilation/%.d.out: fail_compilation/%.d $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test $(DMD)
138 142
 	$(QUIET) ./$(RESULTS_DIR)/d_do_test $(<D) $* d
139 143
 
@@ -145,7 +149,7 @@ clean:
145 149
 	$(QUIET)if [ -e $(RESULTS_DIR) ]; then rm -rf $(RESULTS_DIR); fi
146 150
 
147 151
 $(RESULTS_DIR)/.created:
148  
-	@echo Creating output directory: $(RESULTS_DIR) 
  152
+	@echo Creating output directory: $(RESULTS_DIR)
149 153
 	$(QUIET)if [ ! -d $(RESULTS_DIR) ]; then mkdir $(RESULTS_DIR); fi
150 154
 	$(QUIET)if [ ! -d $(RESULTS_DIR)/runnable ]; then mkdir $(RESULTS_DIR)/runnable; fi
151 155
 	$(QUIET)if [ ! -d $(RESULTS_DIR)/compilable ]; then mkdir $(RESULTS_DIR)/compilable; fi
10  test/compilable/ctfeWriteln.sh
... ...
@@ -0,0 +1,10 @@
  1
+#!/bin/sh
  2
+
  3
+result_file=${RESULTS_DIR}/compilable/ctfeWriteln.txt
  4
+source_file=compilable/extra-files/ctfeWriteln.d
  5
+$DMD -m${MODEL} $x -c -o- $source_file 2> $result_file
  6
+if [ $? -ne 0 ]; then
  7
+    exit 1;
  8
+fi
  9
+compilable/extra-files/diff-postscript.sh ctfeWriteln.txt
  10
+
2  test/compilable/ddoc1.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc1-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc1.html
4 4
 // REQUIRED_ARGS: -d
5 5
 
6 6
 /** This module is for ABC
2  test/compilable/ddoc10.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc10-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc10.html
4 4
 
5 5
 // 294
6 6
 
4  test/compilable/ddoc11.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc11-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc11.html
4 4
 
5 5
 /// The various floating point exceptions
6 6
 enum
@@ -49,7 +49,7 @@ struct lldiv_t { long quot,rem; }
49 49
 
50 50
 
51 51
 
52  
-    void *calloc(size_t, size_t);	/// 
  52
+    void *calloc(size_t, size_t);	///
53 53
     void *malloc(size_t);	/// dittx
54 54
 
55 55
 /**
2  test/compilable/ddoc12.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc12-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc12.html
4 4
 
5 5
 int ruhred; /// This documents correctly.
6 6
 int rühred; /// This should too
2  test/compilable/ddoc13.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc13-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc13.html
4 4
 
5 5
 /// struct doc
6 6
 struct Bug4107(T)
4  test/compilable/ddoc14.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc14-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc14.html
4 4
 
5 5
 
6 6
 alias void V;
@@ -77,7 +77,7 @@ interface Interface {
77 77
     V mColon(lazy P p) ; /// 10
78 78
 }
79 79
 +/
80  
-    
  80
+
81 81
 public P variable;  /// 0
82 82
 V mNone(lazy P p) {}  /// 1
83 83
 pure nothrow V mPrefix(lazy P p) {}   /// 2
2  test/compilable/ddoc2.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc2-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc2.html
4 4
 
5 5
 /**
6 6
  * Summary
4  test/compilable/ddoc3.d
... ...
@@ -1,7 +1,7 @@
1 1
 // EXTRA_SOURCES: extra-files/ddoc3.ddoc
2 2
 // PERMUTE_ARGS:
3 3
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
4  
-// POST_SCRIPT: compilable/extra-files/ddoc3-postscript.sh
  4
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc3.html
5 5
 
6 6
 /**
7 7
  * Summary
@@ -42,7 +42,7 @@
42 42
  *	$(TROW 4, 5, 6)
43 43
  *	)
44 44
  *
45  
- * $(D_CODE 
  45
+ * $(D_CODE
46 46
       $(B pragma)( $(I name) );
47 47
       $(B pragma)( $(I name) , $(I option) [ $(I option) ] );
48 48
       $(U $(LPAREN))
2  test/compilable/ddoc4.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc4-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc4.html
4 4
 
5 5
 /**
6 6
     a
6  test/compilable/ddoc5.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc5-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc5.html
4 4
 
5 5
 /**
6 6
 
@@ -15,10 +15,10 @@ class TestMembers(TemplateArg)
15 15
   public:
16 16
     /**
17 17
 
18  
-       a static method 
  18
+       a static method
19 19
 
20 20
        Params: idx = index
21  
-   
  21
+
22 22
     */
23 23
     static void PublicStaticMethod(int  idx)
24 24
     {
2  test/compilable/ddoc6.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc6-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc6.html
4 4
 
5 5
 /**
6 6
  *
2  test/compilable/ddoc6491.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh 6491
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc6491.html
4 4
 
5 5
 module ddoc6491;
6 6
 
2  test/compilable/ddoc7.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc7-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc7.html
4 4
 
5 5
 //-----------------------------------------------
6 6
 /// my enum
2  test/compilable/ddoc8.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc8-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc8.html
4 4
 
5 5
 /** foo */
6 6
 
2  test/compilable/ddoc9.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -D -Ddtest_results/compilable -o-
3  
-// POST_SCRIPT: compilable/extra-files/ddoc9-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh ddoc9.html
4 4
 
5 5
 // 273
6 6
 
19  test/compilable/extra-files/ctfeWriteln.d
... ...
@@ -0,0 +1,19 @@
  1
+// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh
  2
+
  3
+int sum_of_sq(int x) pure nothrow @safe
  4
+{
  5
+    int result = 0;
  6
+    foreach (i; 0 .. x)
  7
+    {
  8
+        __ctfeWrite(i, "^^2 == ");
  9
+        int power = i ^^ 2;
  10
+        __ctfeWriteln(power);
  11
+        result += power;
  12
+    }
  13
+    __ctfeWriteln("result == ", result);
  14
+    return result;
  15
+
  16
+}
  17
+
  18
+static assert(sum_of_sq(7) == 91);
  19
+
8  test/compilable/extra-files/ctfeWriteln.txt
... ...
@@ -0,0 +1,8 @@
  1
+0^^2 == 0
  2
+1^^2 == 1
  3
+2^^2 == 4
  4
+3^^2 == 9
  5
+4^^2 == 16
  6
+5^^2 == 25
  7
+6^^2 == 36
  8
+result == 91
10  test/compilable/extra-files/ddoc1-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc1.html > ${RESULTS_DIR}/compilable/ddoc1.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc1.html ${RESULTS_DIR}/compilable/ddoc1.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc1.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc10-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc10.html > ${RESULTS_DIR}/compilable/ddoc10.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc10.html ${RESULTS_DIR}/compilable/ddoc10.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc10.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc11-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc11.html > ${RESULTS_DIR}/compilable/ddoc11.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc11.html ${RESULTS_DIR}/compilable/ddoc11.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc11.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc12-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc12.html > ${RESULTS_DIR}/compilable/ddoc12.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc12.html ${RESULTS_DIR}/compilable/ddoc12.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc12.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc13-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc13.html > ${RESULTS_DIR}/compilable/ddoc13.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc13.html ${RESULTS_DIR}/compilable/ddoc13.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc13.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc14-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc14.html > ${RESULTS_DIR}/compilable/ddoc14.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc14.html ${RESULTS_DIR}/compilable/ddoc14.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc14.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc2-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc2.html > ${RESULTS_DIR}/compilable/ddoc2.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc2.html ${RESULTS_DIR}/compilable/ddoc2.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc2.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc3-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc3.html > ${RESULTS_DIR}/compilable/ddoc3.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc3.html ${RESULTS_DIR}/compilable/ddoc3.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc3.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc4-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc4.html > ${RESULTS_DIR}/compilable/ddoc4.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc4.html ${RESULTS_DIR}/compilable/ddoc4.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc4.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc5-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc5.html > ${RESULTS_DIR}/compilable/ddoc5.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc5.html ${RESULTS_DIR}/compilable/ddoc5.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc5.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc6-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc6.html > ${RESULTS_DIR}/compilable/ddoc6.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc6.html ${RESULTS_DIR}/compilable/ddoc6.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc6.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc7-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc7.html > ${RESULTS_DIR}/compilable/ddoc7.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc7.html ${RESULTS_DIR}/compilable/ddoc7.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc7.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc8-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc8.html > ${RESULTS_DIR}/compilable/ddoc8.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc8.html ${RESULTS_DIR}/compilable/ddoc8.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc8.html{,.2}
10  
-
10  test/compilable/extra-files/ddoc9-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc9.html > ${RESULTS_DIR}/compilable/ddoc9.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc9.html ${RESULTS_DIR}/compilable/ddoc9.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc9.html{,.2}
10  
-
10  test/compilable/extra-files/ddocAny-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-GREP_OPTIONS= grep -v "Generated by Ddoc from" ${RESULTS_DIR}/compilable/ddoc$1.html > ${RESULTS_DIR}/compilable/ddoc$1.html.2
4  
-diff --strip-trailing-cr compilable/extra-files/ddoc$1.html ${RESULTS_DIR}/compilable/ddoc$1.html.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/ddoc$1.html{,.2}
10  
-
41  test/compilable/extra-files/diff-postscript.sh
... ...
@@ -0,0 +1,41 @@
  1
+#!/bin/sh
  2
+
  3
+if [ $# -le 0 ]; then
  4
+    echo "Usage: $0 [filename]"
  5
+    echo ""
  6
+    echo "This tool is used to check if two generated files are the same."
  7
+    exit 2
  8
+fi
  9
+
  10
+case $1 in
  11
+    *.html)
  12
+        filter_string="Generated by Ddoc from"
  13
+        ;;
  14
+    *.di)
  15
+        filter_string="D import file generated from"
  16
+        ;;
  17
+    json.out)
  18
+        filter_string="\"file\" : "
  19
+        ;;
  20
+    *)
  21
+        filter_string=
  22
+        ;;
  23
+esac
  24
+
  25
+generated=${RESULTS_DIR}/compilable/$1
  26
+filtered=${RESULTS_DIR}/compilable/$1.2
  27
+expected=compilable/extra-files/$1
  28
+
  29
+if [ -n "$filter_string" ]; then
  30
+    GREP_OPTIONS= grep -v "$filter_string" $generated > $filtered
  31
+else
  32
+    cp $generated $filtered
  33
+fi
  34
+
  35
+diff -u --strip-trailing-cr $expected $filtered
  36
+if [ $? -ne 0 ]; then
  37
+    exit 1;
  38
+fi
  39
+
  40
+rm $filtered $generated
  41
+
10  test/compilable/extra-files/header-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "D import file generated from" ${RESULTS_DIR}/compilable/header.di > ${RESULTS_DIR}/compilable/header.di.2
4  
-diff --strip-trailing-cr compilable/extra-files/header.di ${RESULTS_DIR}/compilable/header.di.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/header.di{,.2}
10  
-
10  test/compilable/extra-files/json-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "\"file\" : " ${RESULTS_DIR}/compilable/json.out > ${RESULTS_DIR}/compilable/json.out.2
4  
-diff --strip-trailing-cr compilable/extra-files/json.out ${RESULTS_DIR}/compilable/json.out.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/json.out{,.2}
10  
-
10  test/compilable/extra-files/xheader-postscript.sh
... ...
@@ -1,10 +0,0 @@
1  
-#!/usr/bin/env bash
2  
-
3  
-grep -v "D import file generated from" ${RESULTS_DIR}/compilable/xheader.di > ${RESULTS_DIR}/compilable/xheader.di.2
4  
-diff --strip-trailing-cr compilable/extra-files/xheader.di ${RESULTS_DIR}/compilable/xheader.di.2
5  
-if [ $? -ne 0 ]; then
6  
-    exit 1;
7  
-fi
8  
-
9  
-rm ${RESULTS_DIR}/compilable/xheader.di{,.2}
10  
-
2  test/compilable/header.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -H -Hdtest_results/compilable
3  
-// POST_SCRIPT: compilable/extra-files/header-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh header.di
4 4
 // REQUIRED_ARGS: -d
5 5
 
6 6
 module foo.bar;
2  test/compilable/json.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -o- -X -Xftest_results/compilable/json.out
3  
-// POST_SCRIPT: compilable/extra-files/json-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh json.out
4 4
 
5 5
 struct X;
6 6
 
2  test/compilable/xheader.d
... ...
@@ -1,6 +1,6 @@
1 1
 // PERMUTE_ARGS:
2 2
 // REQUIRED_ARGS: -H -Hdtest_results/compilable
3  
-// POST_SCRIPT: compilable/extra-files/xheader-postscript.sh
  3
+// POST_SCRIPT: compilable/extra-files/diff-postscript.sh xheader.di
4 4
 
5 5
 // for D 2.0 only
6 6
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.