summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2021-11-21 17:04:21 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2021-11-21 17:09:35 +0900
commite6ba08c3b21cdb14ee3a97b5d584759a4597b54b (patch)
treee8b4121323f2f448aeaa15bf3bddb465f36aea8b /debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d
parentf312c235ea5f9971066f3808997d20f89c25f33b (diff)
downloadextra-dependencies-e6ba08c3b21cdb14ee3a97b5d584759a4597b54b.tar.gz
extra-dependencies-e6ba08c3b21cdb14ee3a97b5d584759a4597b54b.zip
uncrustify-trinity: updated based on upstream version 0.74.0
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/1438.d1
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/HashMap.d1059
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/Lexer.d2335
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/bug-indent.d34
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/casts.d13
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/const.d9
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/d_sp_paren.d23
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/delegate.d20
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/enum.d6
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/extern_.d6
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/funcfunc.d5
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/imports.d8
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/invariant.d1
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/numbers.d45
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/sort_import.d19
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/square_indent_tab.d24
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if.d14
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if_in_struct.d5
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/strings.d32
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template.d27
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing000.d12
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing001.d9
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_use.d2
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst01.d23
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst02.d30
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst03.d145
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/type_spacing000.d2
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces000.d12
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces001.d9
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces002.d19
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-1.d10
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-2.d8
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-3.d7
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile.d27
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/wysiwyg_strings.d9
35 files changed, 4010 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/1438.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/1438.d
new file mode 100644
index 00000000..10a43753
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/1438.d
@@ -0,0 +1 @@
+invariant (1 <= day && day <= 31);
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/HashMap.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/HashMap.d
new file mode 100644
index 00000000..618b3e59
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/HashMap.d
@@ -0,0 +1,1059 @@
+/*******************************************************************************
+
+ @file HashMap.d
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for damages
+ of any kind arising from the use of this software.
+
+ Permission is hereby granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and/or
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment within documentation of
+ said product would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any distribution
+ of the source.
+
+ 4. Derivative works are permitted, but they must carry this notice
+ in full and credit the original source.
+
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+ Written by Doug Lea with assistance from members of JCP JSR-166
+ Expert Group and released to the public domain, as explained at
+ http://creativecommons.org/licenses/publicdomain
+
+ @version Initial version, July 2004
+ @author Doug Lea; ported/modified by Kris
+
+*******************************************************************************/
+
+module mango.cache.HashMap;
+
+/******************************************************************************
+
+******************************************************************************/
+
+extern (C)
+{
+ int memcmp (char *, char *, uint);
+}
+
+
+/**
+ * A hash table supporting full concurrency of retrievals and
+ * adjustable expected concurrency for updates. This class obeys the
+ * same functional specification as {@link java.util.Hashtable}, and
+ * includes versions of methods corresponding to each method of
+ * <tt>Hashtable</tt>. However, even though all operations are
+ * thread-safe, retrieval operations do <em>not</em> entail locking,
+ * and there is <em>not</em> any support for locking the entire table
+ * in a way that prevents all access. This class is fully
+ * interoperable with <tt>Hashtable</tt> in programs that rely on its
+ * thread safety but not on its synchronization details.
+ *
+ * <p> Retrieval operations (including <tt>get</tt>) generally do not
+ * block, so may overlap with update operations (including
+ * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
+ * of the most recently <em>completed</em> update operations holding
+ * upon their onset. For aggregate operations such as <tt>putAll</tt>
+ * and <tt>clear</tt>, concurrent retrievals may reflect insertion or
+ * removal of only some entries. Similarly, Iterators and
+ * Enumerations return elements reflecting the state of the hash table
+ * at some point at or since the creation of the iterator/enumeration.
+ * They do <em>not</em> throw
+ * {@link ConcurrentModificationException}. However, iterators are
+ * designed to be used by only one thread at a time.
+ *
+ * <p> The allowed concurrency among update operations is guided by
+ * the optional <tt>concurrencyLevel</tt> constructor argument
+ * (default 16), which is used as a hint for internal sizing. The
+ * table is internally partitioned to try to permit the indicated
+ * number of concurrent updates without contention. Because placement
+ * in hash tables is essentially random, the actual concurrency will
+ * vary. Ideally, you should choose a value to accommodate as many
+ * threads as will ever concurrently modify the table. Using a
+ * significantly higher value than you need can waste space and time,
+ * and a significantly lower value can lead to thread contention. But
+ * overestimates and underestimates within an order of magnitude do
+ * not usually have much noticeable impact. A value of one is
+ * appropriate when it is known that only one thread will modify and
+ * all others will only read. Also, resizing this or any other kind of
+ * hash table is a relatively slow operation, so, when possible, it is
+ * a good idea to provide estimates of expected table sizes in
+ * constructors.
+ *
+ * <p>This class and its views and iterators implement all of the
+ * <em>optional</em> methods of the {@link Map} and {@link Iterator}
+ * interfaces.
+ *
+ * <p> Like {@link java.util.Hashtable} but unlike {@link
+ * java.util.HashMap}, this class does NOT allow <tt>null</tt> to be
+ * used as a key or value.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../guide/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ */
+
+class HashMap
+{
+ alias void[] K;
+ alias Object V;
+ alias jhash hash; // jhash, fnv, or walter
+
+ /*
+ * The basic strategy is to subdivide the table among Segments,
+ * each of which itself is a concurrently readable hash table.
+ */
+
+ /* ---------------- Constants -------------- */
+
+ /**
+ * The default initial number of table slots for this table.
+ * Used when not otherwise specified in constructor.
+ */
+ private const uint DEFAULT_INITIAL_CAPACITY = 16;
+
+ /**
+ * The maximum capacity, used if a higher value is implicitly
+ * specified by either of the constructors with arguments. MUST
+ * be a power of two <= 1<<30 to ensure that entries are indexible
+ * using ints.
+ */
+ private const uint MAXIMUM_CAPACITY = 1 << 30;
+
+ /**
+ * The default load factor for this table. Used when not
+ * otherwise specified in constructor.
+ */
+ private const float DEFAULT_LOAD_FACTOR = 0.75f;
+
+ /**
+ * The default number of concurrency control segments.
+ **/
+ private const uint DEFAULT_SEGMENTS = 16;
+
+ /**
+ * The maximum number of segments to allow; used to bound
+ * constructor arguments.
+ */
+ private const uint MAX_SEGMENTS = 1 << 16; // slightly conservative
+
+
+ /* ---------------- Fields -------------- */
+
+ /**
+ * Mask value for indexing into segments. The upper bits of a
+ * key's hash code are used to choose the segment.
+ **/
+ private final int segmentMask;
+
+ /**
+ * Shift value for indexing within segments.
+ **/
+ private final int segmentShift;
+
+ /**
+ * The segments, each of which is a specialized hash table
+ */
+ private final Segment[] segments;
+
+
+ /* ---------------- Small Utilities -------------- */
+
+ /**
+ * Returns a hash code for non-null Object x.
+ * Uses the same hash code spreader as most other java.util hash tables.
+ * @param x the object serving as a key
+ * @return the hash code
+ */
+ private static final uint walter(K x)
+ {
+ uint h = typeid(char[]).getHash (&x);
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+ }
+
+ /**
+ * Returns a hash code for non-null Object x.
+ * uses the FNV hash function
+ * @param x the object serving as a key
+ * @return the hash code
+ */
+ private static final uint fnv(K x)
+ {
+ uint hash = 2_166_136_261;
+
+ foreach (ubyte c; cast(ubyte[]) x)
+ {
+ hash ^= c;
+ hash *= 16_777_619;
+ }
+ return hash;
+ }
+
+
+
+ /**
+ * hash() -- hash a variable-length key into a 32-bit value
+ * k : the key (the unaligned variable-length array of bytes)
+ * len : the length of the key, counting by bytes
+ * level : can be any 4-byte value
+ * Returns a 32-bit value. Every bit of the key affects every bit of
+ * the return value. Every 1-bit and 2-bit delta achieves avalanche.
+ * About 36+6len instructions.
+ *
+ * The best hash table sizes are powers of 2. There is no need to do
+ * mod a prime (mod is sooo slow!). If you need less than 32 bits,
+ * use a bitmask. For example, if you need only 10 bits, do
+ * h = (h & hashmask(10));
+ * In which case, the hash table should have hashsize(10) elements.
+ *
+ * If you are hashing n strings (ub1 **)k, do it like this:
+ * for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+ *
+ * By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+ * code any way you wish, private, educational, or commercial. It's free.
+ *
+ * See http://burlteburtle.net/bob/hash/evahash.html
+ * Use for hash table lookup, or anything where one collision in 2^32 is
+ * acceptable. Do NOT use for cryptographic purposes.
+ */
+
+ static final uint jhash (K x)
+ {
+ ubyte* k;
+ uint a,
+ b,
+ c,
+ len;
+
+ len = x.length;
+ k = cast(ubyte *) x;
+ a = b = 0x9e3779b9;
+
+ // the previous hash value
+ c = 0;
+
+ // handle most of the key
+ while (len >= 12)
+ {
+ a += *cast(uint *)(k+0);
+ b += *cast(uint *)(k+4);
+ c += *cast(uint *)(k+8);
+
+ a -= b; a -= c; a ^= (c>>13);
+ b -= c; b -= a; b ^= (a<<8);
+ c -= a; c -= b; c ^= (b>>13);
+ a -= b; a -= c; a ^= (c>>12);
+ b -= c; b -= a; b ^= (a<<16);
+ c -= a; c -= b; c ^= (b>>5);
+ a -= b; a -= c; a ^= (c>>3);
+ b -= c; b -= a; b ^= (a<<10);
+ c -= a; c -= b; c ^= (b>>15);
+ k += 12; len -= 12;
+ }
+
+ // handle the last 11 bytes
+ c += x.length;
+ switch (len)
+ {
+ case 11: c+=(cast(uint)k[10]<<24);
+ case 10: c+=(cast(uint)k[9]<<16);
+ case 9 : c+=(cast(uint)k[8]<<8);
+ case 8 : b+=(cast(uint)k[7]<<24);
+ case 7 : b+=(cast(uint)k[6]<<16);
+ case 6 : b+=(cast(uint)k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=(cast(uint)k[3]<<24);
+ case 3 : a+=(cast(uint)k[2]<<16);
+ case 2 : a+=(cast(uint)k[1]<<8);
+ case 1 : a+=k[0];
+ default:
+ }
+
+ a -= b; a -= c; a ^= (c>>13);
+ b -= c; b -= a; b ^= (a<<8);
+ c -= a; c -= b; c ^= (b>>13);
+ a -= b; a -= c; a ^= (c>>12);
+ b -= c; b -= a; b ^= (a<<16);
+ c -= a; c -= b; c ^= (b>>5);
+ a -= b; a -= c; a ^= (c>>3);
+ b -= c; b -= a; b ^= (a<<10);
+ c -= a; c -= b; c ^= (b>>15);
+
+ return c;
+ }
+
+
+ /**
+ * Returns the segment that should be used for key with given hash
+ * @param hash the hash code for the key
+ * @return the segment
+ */
+ private final Segment segmentFor(uint hash)
+ {
+ return segments[(hash >>> segmentShift) & segmentMask];
+ }
+
+ /* ---------------- Inner Classes -------------- */
+
+ /**
+ * ConcurrentHashMap list entry. Note that this is never exported
+ * out as a user-visible Map.Entry.
+ *
+ * Because the value field is volatile, not final, it is legal wrt
+ * the Java Memory Model for an unsynchronized reader to see null
+ * instead of initial value when read via a data race. Although a
+ * reordering leading to this is not likely to ever actually
+ * occur, the Segment.readValueUnderLock method is used as a
+ * backup in case a null (pre-initialized) value is ever seen in
+ * an unsynchronized access method.
+ */
+ private static class HashEntry
+ {
+ final K key;
+ final uint hash;
+ final V value;
+ final HashEntry next;
+
+ this (K key, uint hash, HashEntry next, V value)
+ {
+ this.key = key;
+ this.hash = hash;
+ this.next = next;
+ this.value = value;
+ }
+ }
+
+ /**
+ * Segments are specialized versions of hash tables. This
+ * subclasses from ReentrantLock opportunistically, just to
+ * simplify some locking and avoid separate construction.
+ **/
+ static class Segment
+ {
+ /*
+ * Segments maintain a table of entry lists that are ALWAYS
+ * kept in a consistent state, so can be read without locking.
+ * Next fields of nodes are immutable (final). All list
+ * additions are performed at the front of each bin. This
+ * makes it easy to check changes, and also fast to traverse.
+ * When nodes would otherwise be changed, new nodes are
+ * created to replace them. This works well for hash tables
+ * since the bin lists tend to be short. (The average length
+ * is less than two for the default load factor threshold.)
+ *
+ * Read operations can thus proceed without locking, but rely
+ * on selected uses of volatiles to ensure that completed
+ * write operations performed by other threads are
+ * noticed. For most purposes, the "count" field, tracking the
+ * number of elements, serves as that volatile variable
+ * ensuring visibility. This is convenient because this field
+ * needs to be read in many read operations anyway:
+ *
+ * - All (unsynchronized) read operations must first read the
+ * "count" field, and should not look at table entries if
+ * it is 0.
+ *
+ * - All (synchronized) write operations should write to
+ * the "count" field after structurally changing any bin.
+ * The operations must not take any action that could even
+ * momentarily cause a concurrent read operation to see
+ * inconsistent data. This is made easier by the nature of
+ * the read operations in Map. For example, no operation
+ * can reveal that the table has grown but the threshold
+ * has not yet been updated, so there are no atomicity
+ * requirements for this with respect to reads.
+ *
+ * As a guide, all critical volatile reads and writes to the
+ * count field are marked in code comments.
+ */
+
+ /**
+ * The number of elements in this segment's region.
+ **/
+ int count;
+
+ /**
+ * The table is rehashed when its size exceeds this threshold.
+ * (The value of this field is always (int)(capacity *
+ * loadFactor).)
+ */
+ int threshold;
+
+ /**
+ * The per-segment table. Declared as a raw type, casted
+ * to HashEntry<K,V> on each use.
+ */
+ HashEntry[] table;
+
+ /**
+ * The load factor for the hash table. Even though this value
+ * is same for all segments, it is replicated to avoid needing
+ * links to outer object.
+ * @serial
+ */
+ final float loadFactor;
+
+ this (int initialCapacity, float lf)
+ {
+ loadFactor = lf;
+ setTable (new HashEntry[initialCapacity]);
+ }
+
+ /**
+ * Set table to new HashEntry array.
+ * Call only while holding lock or in constructor.
+ **/
+ private final void setTable (HashEntry[] newTable)
+ {
+ threshold = cast(int) (newTable.length * loadFactor);
+ volatile table = newTable;
+ }
+
+ /**
+ * Return properly casted first entry of bin for given hash
+ */
+ private final HashEntry getFirst (uint hash)
+ {
+ HashEntry[] tab;
+
+ volatile tab = table;
+ return tab [hash & (tab.length - 1)];
+ }
+
+ /**
+ * Return true if the two keys match
+ */
+ private static final bool matchKey (K a, K b)
+ {
+ if (a.length == b.length)
+ return cast(bool) (memcmp (cast(char*) a, cast(char*) b, a.length) == 0);
+ return false;
+ }
+
+ /* Specialized implementations of map methods */
+
+ final V get (K key, uint hash)
+ {
+ int c;
+
+ // read-volatile
+ volatile c = count;
+ if (c)
+ {
+ HashEntry e = getFirst (hash);
+ while (e)
+ {
+ if (hash == e.hash && matchKey (key, e.key))
+ {
+ V v;
+ volatile v = e.value;
+ if (v)
+ return v;
+
+ synchronized (this)
+ return e.value;
+ }
+ e = e.next;
+ }
+ }
+ return null;
+ }
+
+
+ final bool containsKey (K key, uint hash)
+ {
+ int c;
+
+ // read-volatile
+ volatile c = count;
+ if (c)
+ {
+ HashEntry e = getFirst (hash);
+ while (e)
+ {
+ if (e.hash == hash && matchKey (key, e.key))
+ return true;
+ e = e.next;
+ }
+ }
+ return false;
+ }
+
+
+
+ final synchronized V replace (K key, uint hash, V newValue)
+ {
+ HashEntry e = getFirst(hash);
+ while (e && (e.hash != hash || !matchKey (key, e.key)))
+ e = e.next;
+
+ V oldValue = null;
+ if (e)
+ volatile
+ {
+ oldValue = e.value;
+ e.value = newValue;
+ }
+ return oldValue;
+ }
+
+
+ final synchronized V put (K key, uint hash, V value, bool onlyIfAbsent)
+ {
+ int c;
+
+ volatile c = count;
+ if (c++ > threshold)
+ rehash();
+
+ HashEntry[] tab;
+ volatile tab = table;
+ uint index = hash & (tab.length - 1);
+ HashEntry first = tab[index];
+ HashEntry e = first;
+
+ while (e && (e.hash != hash || !matchKey (key, e.key)))
+ e = e.next;
+
+ V oldValue;
+ if (e)
+ {
+ volatile oldValue = e.value;
+ if (!onlyIfAbsent)
+ volatile e.value = value;
+ }
+ else
+ {
+ oldValue = null;
+ tab[index] = new HashEntry (key, hash, first, value);
+
+ // write-volatile
+ volatile count = c;
+ }
+ return oldValue;
+ }
+
+
+ private final void rehash ()
+ {
+ HashEntry[] oldTable;
+
+ volatile oldTable = table;
+ int oldCapacity = oldTable.length;
+ if (oldCapacity >= MAXIMUM_CAPACITY)
+ return;
+
+ /*
+ * Reclassify nodes in each list to new Map. Because we are
+ * using power-of-two expansion, the elements from each bin
+ * must either stay at same index, or move with a power of two
+ * offset. We eliminate unnecessary node creation by catching
+ * cases where old nodes can be reused because their next
+ * fields won't change. Statistically, at the default
+ * threshold, only about one-sixth of them need cloning when
+ * a table doubles. The nodes they replace will be garbage
+ * collectable as soon as they are no longer referenced by any
+ * reader thread that may be in the midst of traversing table
+ * right now.
+ */
+
+ HashEntry[] newTable = new HashEntry[oldCapacity << 1];
+ threshold = cast(int) (newTable.length * loadFactor);
+ int sizeMask = newTable.length - 1;
+
+ for (int i = 0; i < oldCapacity ; ++i)
+ {
+ // We need to guarantee that any existing reads of old Map can
+ // proceed. So we cannot yet null out each bin.
+ HashEntry e = oldTable[i];
+
+ if (e)
+ {
+ HashEntry next = e.next;
+ uint idx = e.hash & sizeMask;
+
+ // Single node on list
+ if (next is null)
+ newTable[idx] = e;
+ else
+ {
+ // Reuse trailing consecutive sequence at same slot
+ HashEntry lastRun = e;
+ int lastIdx = idx;
+ for (HashEntry last=next; last; last = last.next)
+ {
+ uint k = last.hash & sizeMask;
+ if (k != lastIdx)
+ {
+ lastIdx = k;
+ lastRun = last;
+ }
+ }
+ newTable[lastIdx] = lastRun;
+
+ // Clone all remaining nodes
+ for (HashEntry p = e; p !is lastRun; p = p.next)
+ {
+ uint k = p.hash & sizeMask;
+ HashEntry n = newTable[k];
+ newTable[k] = new HashEntry(p.key, p.hash, n, p.value);
+ }
+ }
+ }
+ }
+ volatile table = newTable;
+ }
+
+ /**
+ * Remove; match on key only if value null, else match both.
+ */
+ final synchronized V remove (K key, uint hash, V value)
+ {
+ int c;
+ HashEntry[] tab;
+
+ volatile c = count - 1;
+ volatile tab = table;
+
+ uint index = hash & (tab.length - 1);
+ HashEntry first = tab[index];
+ HashEntry e = first;
+
+ while (e && (e.hash != hash || !matchKey (key, e.key)))
+ e = e.next;
+
+ V oldValue = null;
+ if (e)
+ {
+ V v;
+ volatile v = e.value;
+ if (value is null || value == v)
+ {
+ oldValue = v;
+
+ // All entries following removed node can stay
+ // in list, but all preceding ones need to be
+ // cloned.
+ HashEntry newFirst = e.next;
+ for (HashEntry p = first; p !is e; p = p.next)
+ newFirst = new HashEntry (p.key, p.hash, newFirst, p.value);
+ tab[index] = newFirst;
+
+ // write-volatile
+ volatile count = c;
+ }
+ }
+ return oldValue;
+ }
+
+
+ final synchronized void clear()
+ {
+ if (count)
+ {
+ HashEntry[] tab;
+ volatile tab = table;
+
+ for (int i = 0; i < tab.length ; i++)
+ tab[i] = null;
+
+ // write-volatile
+ volatile count = 0;
+ }
+ }
+ }
+
+
+
+ /* ---------------- Public operations -------------- */
+
+ /**
+ * Creates a new, empty map with the specified initial
+ * capacity and the specified load factor.
+ *
+ * @param initialCapacity the initial capacity. The implementation
+ * performs internal sizing to accommodate this many elements.
+ * @param loadFactor the load factor threshold, used to control resizing.
+ * @param concurrencyLevel the estimated number of concurrently
+ * updating threads. The implementation performs internal sizing
+ * to try to accommodate this many threads.
+ * @throws IllegalArgumentException if the initial capacity is
+ * negative or the load factor or concurrencyLevel are
+ * nonpositive.
+ */
+ public this (uint initialCapacity, float loadFactor, uint concurrencyLevel)
+ {
+ assert (loadFactor > 0);
+
+ if (concurrencyLevel > MAX_SEGMENTS)
+ concurrencyLevel = MAX_SEGMENTS;
+
+ // Find power-of-two sizes best matching arguments
+ int sshift = 0;
+ int ssize = 1;
+ while (ssize < concurrencyLevel)
+ {
+ ++sshift;
+ ssize <<= 1;
+ }
+
+ segmentShift = 32 - sshift;
+ segmentMask = ssize - 1;
+ this.segments = new Segment[ssize];
+
+ if (initialCapacity > MAXIMUM_CAPACITY)
+ initialCapacity = MAXIMUM_CAPACITY;
+
+ int c = initialCapacity / ssize;
+ if (c * ssize < initialCapacity)
+ ++c;
+
+ int cap = 1;
+ while (cap < c)
+ cap <<= 1;
+
+ for (int i = 0; i < this.segments.length; ++i)
+ this.segments[i] = new Segment (cap, loadFactor);
+ }
+
+ /**
+ * Creates a new, empty map with the specified initial
+ * capacity, and with default load factor and concurrencyLevel.
+ *
+ * @param initialCapacity The implementation performs internal
+ * sizing to accommodate this many elements.
+ * @throws IllegalArgumentException if the initial capacity of
+ * elements is negative.
+ */
+ public this (uint initialCapacity)
+ {
+ this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+ }
+
+ /**
+ * Creates a new, empty map with a default initial capacity,
+ * load factor, and concurrencyLevel.
+ */
+ public this ()
+ {
+ this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped in this table.
+ *
+ * @param key a key in the table.
+ * @return the value to which the key is mapped in this table;
+ * <tt>null</tt> if the key is not mapped to any value in
+ * this table.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
+ */
+ public V get (K key)
+ {
+ uint hash = hash(key); // throws NullPointerException if key null
+ return segmentFor(hash).get(key, hash);
+ }
+
+ /**
+ * Tests if the specified object is a key in this table.
+ *
+ * @param key possible key.
+ * @return <tt>true</tt> if and only if the specified object
+ * is a key in this table, as determined by the
+ * <tt>equals</tt> method; <tt>false</tt> otherwise.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
+ */
+ public bool containsKey (K key)
+ {
+ uint hash = hash(key); // throws NullPointerException if key null
+ return segmentFor(hash).containsKey(key, hash);
+ }
+
+ /**
+ * Maps the specified <tt>key</tt> to the specified
+ * <tt>value</tt> in this table. Neither the key nor the
+ * value can be <tt>null</tt>.
+ *
+ * <p> The value can be retrieved by calling the <tt>get</tt> method
+ * with a key that is equal to the original key.
+ *
+ * @param key the table key.
+ * @param value the value.
+ * @return the previous value of the specified key in this table,
+ * or <tt>null</tt> if it did not have one.
+ * @throws NullPointerException if the key or value is
+ * <tt>null</tt>.
+ */
+ public V put (K key, V value)
+ {
+ assert (value);
+
+ uint hash = hash(key);
+ return segmentFor(hash).put(key, hash, value, false);
+ }
+
+ /**
+ * If the specified key is not already associated
+ * with a value, associate it with the given value.
+ * This is equivalent to
+ * <pre>
+ * if (!map.containsKey(key))
+ * return map.put(key, value);
+ * else
+ * return map.get(key);
+ * </pre>
+ * Except that the action is performed atomically.
+ * @param key key with which the specified value is to be associated.
+ * @param value value to be associated with the specified key.
+ * @return previous value associated with specified key, or <tt>null</tt>
+ * if there was no mapping for key.
+ * @throws NullPointerException if the specified key or value is
+ * <tt>null</tt>.
+ */
+ public V putIfAbsent (K key, V value)
+ {
+ assert (value);
+
+ uint hash = hash(key);
+ return segmentFor(hash).put(key, hash, value, true);
+ }
+
+
+ /**
+ * Removes the key (and its corresponding value) from this
+ * table. This method does nothing if the key is not in the table.
+ *
+ * @param key the key that needs to be removed.
+ * @return the value to which the key had been mapped in this table,
+ * or <tt>null</tt> if the key did not have a mapping.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
+ */
+ public V remove (K key)
+ {
+ uint hash = hash(key);
+ return segmentFor(hash).remove(key, hash, null);
+ }
+
+ /**
+ * Remove entry for key only if currently mapped to given value.
+ * Acts as
+ * <pre>
+ * if (map.get(key).equals(value)) {
+ * map.remove(key);
+ * return true;
+ * } else return false;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param value value associated with the specified key.
+ * @return true if the value was removed
+ * @throws NullPointerException if the specified key is
+ * <tt>null</tt>.
+ */
+ public bool remove (K key, V value)
+ {
+ uint hash = hash(key);
+ return cast(bool) (segmentFor(hash).remove(key, hash, value) !is null);
+ }
+
+
+ /**
+ * Replace entry for key only if currently mapped to some value.
+ * Acts as
+ * <pre>
+ * if ((map.containsKey(key)) {
+ * return map.put(key, value);
+ * } else return null;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param value value to be associated with the specified key.
+ * @return previous value associated with specified key, or <tt>null</tt>
+ * if there was no mapping for key.
+ * @throws NullPointerException if the specified key or value is
+ * <tt>null</tt>.
+ */
+ public V replace (K key, V value)
+ {
+ assert (value);
+
+ uint hash = hash(key);
+ return segmentFor(hash).replace(key, hash, value);
+ }
+
+
+ /**
+ * Removes all mappings from this map.
+ */
+ public void clear ()
+ {
+ for (int i = 0; i < segments.length; ++i)
+ segments[i].clear();
+ }
+
+
+ /**
+ * Returns an enumeration of the keys in this table.
+ *
+ * @return an enumeration of the keys in this table.
+ * @see #keySet
+ */
+ public KeyIterator keys ()
+ {
+ return new KeyIterator (this);
+ }
+
+ /**
+ * Returns an enumeration of the values in this table.
+ *
+ * @return an enumeration of the values in this table.
+ * @see #values
+ */
+ public ValueIterator elements ()
+ {
+ return new ValueIterator (this);
+ }
+
+ /**********************************************************************
+
+ Iterate over all keys in hashmap
+
+ **********************************************************************/
+
+ int opApply (int delegate(inout char[]) dg)
+ {
+ int result = 0;
+ KeyIterator iterator = keys ();
+
+ while (iterator.hasNext)
+ {
+ char[] ca = cast(char[]) iterator.next;
+ if ((result = dg (ca)) != 0)
+ break;
+ }
+ return result;
+ }
+
+ /**********************************************************************
+
+ Iterate over all keys in hashmap
+
+ **********************************************************************/
+
+ int opApply (int delegate(inout char[], inout Object) dg)
+ {
+ int result = 0;
+ KeyIterator iterator = keys ();
+
+ while (iterator.hasNext)
+ {
+ HashEntry he = iterator.nextElement;
+ char[] ca = cast(char[]) he.key;
+ if ((result = dg (ca, he.value)) != 0)
+ break;
+ }
+ return result;
+ }
+
+
+ /* ---------------- Iterator Support -------------- */
+
+ abstract static class HashIterator
+ {
+ int nextSegmentIndex;
+ int nextTableIndex;
+ HashEntry[] currentTable;
+ HashEntry nextEntry;
+ HashEntry lastReturned;
+ HashMap map;
+
+ this (HashMap map)
+ {
+ this.map = map;
+ nextSegmentIndex = map.segments.length - 1;
+ nextTableIndex = -1;
+ advance();
+ }
+
+ final void advance ()
+ {
+ if (nextEntry !is null && (nextEntry = nextEntry.next) !is null)
+ return;
+
+ while (nextTableIndex >= 0)
+ {
+ if ( (nextEntry = currentTable[nextTableIndex--]) !is null)
+ return;
+ }
+
+ while (nextSegmentIndex >= 0)
+ {
+ Segment seg = map.segments[nextSegmentIndex--];
+ volatile if (seg.count)
+ {
+ currentTable = seg.table;
+ for (int j = currentTable.length - 1; j >= 0; --j)
+ {
+ if ((nextEntry = currentTable[j]) !is null)
+ {
+ nextTableIndex = j - 1;
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ public bool hasNext ()
+ {
+ return cast(bool) (nextEntry !is null);
+ }
+
+ HashEntry nextElement ()
+ {
+ if (nextEntry is null)
+ throw new Exception ("no such element in HashMap");
+
+ lastReturned = nextEntry;
+ advance ();
+ return lastReturned;
+ }
+ }
+
+ static class KeyIterator : HashIterator
+ {
+ this (HashMap map) {super (map);}
+ public K next() { return super.nextElement().key; }
+ }
+
+ static class ValueIterator : HashIterator
+ {
+ this (HashMap map) {super (map);}
+ public V next() { volatile return super.nextElement().value; }
+ }
+
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/Lexer.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/Lexer.d
new file mode 100644
index 00000000..004d9d8a
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/Lexer.d
@@ -0,0 +1,2335 @@
+/+
+ Copyright (c) 1999-2006 by Digital Mars
+ All Rights Reserved
+ written by Walter Bright www.digitalmars.com
+ License for redistribution is by either the Artistic License in artistic.txt, or the GNU General Public License in gnu.txt.
+ See the included readme.txt for details.
+ D Language conversion by: J Duncan
++/
+
+/**
+ d language lexer
+*/
+
+module dparser.Lexer;
+
+import dparser.Root;
+
+import dparser.Tokens;
+import dparser.Token;
+import dparser.Keyword;
+
+import dparser.Types;
+
+import dparser.Module;
+import dparser.Identifier;
+import dparser.unialpha;
+
+import dparser.OutBuffer;
+
+//private import std.ctype;
+//private import std.string;
+//import dwf.core.debugapi;
+
+int errno = 0;
+
+//#if _WIN32 && __DMC__
+// from \dm\src\include\setlocal.h
+//extern "C" char * __cdecl __locale_decpoint;
+char* __locale_decpoint;
+//#endif
+//const uint LS = 0x2028; // UTF line separator
+//const uint PS = 0x2029; // UTF paragraph separator
+
+//extern int isUniAlpha(unsigned u);
+//extern int HtmlNamedEntity(unsigned char *p, int length);
+
+/**
+ Lexer object
+*/
+
+class Lexer
+{
+
+ static Identifier[char[]] stringtable;
+ static OutBuffer stringbuffer;
+ static Token* freelist;
+
+ Token token; // current token
+ Module mod; // current module
+ Loc loc; // for error messages
+ ubyte *base; // pointer to start of buffer
+ ubyte *end; // past end of buffer
+ ubyte *p; // current character
+ int doDocComment; // collect doc comment information
+ int anyToken; // !=0 means seen at least one token
+ int commentToken; // !=0 means comments are TOKcomment's
+
+
+ this( Module mod, ubyte* base, uint begoffset, uint endoffset, int doDocComment, int commentToken )
+ {
+ if( stringbuffer is null )
+ stringbuffer = new OutBuffer;
+ loc = Loc(mod, 1);
+
+ this.base = base;
+ this.end = base + endoffset;
+ this.p = base + begoffset;
+ this.mod = mod;
+ this.doDocComment = doDocComment;
+ this.commentToken = commentToken;
+
+ /*
+ If first line starts with '#!', ignore the line
+ */
+
+ if( p[0] == '#' && p[1] =='!' )
+ {
+ p += 2;
+ while( true )
+ {
+ ubyte c = *p;
+ switch( c )
+ {
+ case '\n':
+ p++;
+ break;
+
+ case '\r':
+ p++;
+ if( *p == '\n' )
+ p++;
+ break;
+
+ case 0:
+ case 0x1A:
+ break;
+
+ default:
+ if( c & 0x80 )
+ {
+ uint u = decodeUTF();
+ if( u == PS || u == LS )
+ break;
+ }
+ p++;
+ continue;
+ }
+ break;
+ }
+
+ loc.linnum = 2;
+ }
+
+ }
+
+
+
+ // generate a unique identifier for this string
+ static Identifier idPool( in char[] str )
+ {
+// StringValue sv;
+// uint len = s.length;
+// StringValue sv = stringtable.update(s, len);
+// Identifier* id = cast(Identifier*) sv.ptrvalue;
+// if( id is null )
+ if( (str in stringtable) == null )
+ {
+ stringtable[str] = new Identifier( str, TOK.TOKidentifier );
+ }
+ return stringtable[str];
+ }
+
+ static void initKeywords()
+ {
+ // build character map
+ cmtable_init();
+
+ // create keyword tokens & identifiers
+ dparser.Keyword.initKeywords();
+
+ // create standard lexer tokens
+ dparser.Token.createLexerTokens();
+ }
+
+ // Combine two document comments into one.
+ static char[] combineComments( char[] c1, char[] c2 )
+ {
+ char[] c = c2;
+ if( c1.length )
+ {
+ c = c1;
+ if( c2.length )
+ {
+ c = c1 ~ "\n" ~ c2;
+ }
+ }
+ return c;
+ }
+
+ // Decode UTF character. Issue error messages for invalid sequences. Return decoded character, advance p to last character in UTF sequence.
+ //! fix
+ uint decodeUTF()
+ {
+ ubyte* s = p;
+ ubyte c = *s;
+
+ assert( c & 0x80 );
+ if( !(c & 0x80) )
+ return c;
+
+ return cast(uint) 'X';
+ /*
+ dchar u;
+ uint len;
+
+
+
+ // Check length of remaining string up to 6 UTF-8 characters
+ for( len = 1; len < 6 && s[len]; len++ )
+ {
+
+ }
+ /+
+ uint idx = 0;
+ char* msg = utf_decodeChar( s, len, &idx, &u );
+ p += idx - 1;
+ if( msg )
+ {
+ error(msg);
+ }
+ +/
+ return u;
+ */
+ }
+
+ void error( ... )
+ {
+ if( (mod !is null) && !global.gag )
+ {
+ writefln( formatLoc( loc, _arguments, _argptr ) );
+ /*
+ char[] p = loc.toChars();
+ if( p.length )
+ writef( "%s: ", p );
+ writefx( stdout, _arguments, _argptr, 1 );
+ */
+ if( global.errors >= global.max_errors ) // moderate blizzard of cascading messages
+ throw new Exception( "too many errors" );
+ }
+
+ global.errors++;
+ }
+
+ void errorLoc(Loc loc, ...)
+ {
+ if( (mod !is null) && !global.gag )
+ {
+ writefln( formatLoc( loc, _arguments, _argptr ) );
+ /*
+ char[] p = loc.toChars();
+ if( p.length )
+ writef("%s: ", p);
+ writefx(stdout, _arguments, _argptr, 1);
+ */
+ if( global.errors >= 20 ) // moderate blizzard of cascading messages
+ throw new Exception( "too many errors" );
+ }
+
+ global.errors++;
+ }
+
+
+ TOK nextToken()
+ {
+ if( token.next )
+ {
+ Token* t = token.next;
+ memcpy( &token, t, Token.sizeof );
+// t.next = freelist;
+// freelist = t;
+ }
+ else
+ {
+ scan( &token );
+ }
+// token.print();
+ return token.value;
+ }
+
+ Token* peek( inout Token ct )
+ {
+ Token* t;
+ if( ct.next )
+ t = ct.next;
+ else
+ {
+ t = new Token;
+ scan( t );
+ t.next = null;
+ ct.next = t;
+ }
+ return t;
+ }
+
+ // Turn next token in buffer into a token.
+
+ void scan( Token* t )
+ {
+// debug writefln("scan token");
+ uint lastLine = loc.linnum;
+ uint linnum;
+ t.blockComment = null;
+ t.lineComment = null;
+ while( true )
+ {
+ t.ptr = p;
+// debug writefln( " p = %d, *p = ", cast(uint)p, cast(char)*p );
+ switch( *p )
+ {
+ case 0:
+ case 0x1a:
+ t.value = TOK.TOKeof; // end of file
+// debug writefln( " EOF" );
+ return;
+
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ p++;
+// debug writefln( " whitespace" );
+ continue; // skip white space
+
+ case '\r':
+// debug writefln( " cr" );
+ p++;
+ if( *p != '\n' ) // if CR stands by itself
+ loc.linnum++;
+ continue; // skip white space
+
+ case '\n':
+// debug writefln( " nl" );
+ p++;
+ loc.linnum++;
+ continue; // skip white space
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ t.value = number(t);
+ return;
+
+/*
+ #if CSTRINGS
+ case '\'':
+ t.value = charConstant(t, 0);
+ return;
+
+ case '"':
+ t.value = stringConstant(t,0);
+ return;
+
+ case 'l':
+ case 'L':
+ if( p[1] == '\'')
+ {
+ p++;
+ t.value = charConstant(t, 1);
+ return;
+ }
+ else if( p[1] == '"')
+ {
+ p++;
+ t.value = stringConstant(t, 1);
+ return;
+ }
+ #else
+*/
+ case '\'':
+// debug writefln( " char" );
+ t.value = charConstant(t,0);
+ return;
+
+ case 'r':
+// debug writefln( " wysiwyg" );
+ if( p[1] != '"')
+ goto case_identifier;
+ p++;
+ case '`':
+ t.value = wysiwygStringConstant(t, *p);
+ return;
+
+ case 'x':
+// debug writefln( " hex string" );
+ if( p[1] != '"')
+ goto case_identifier;
+ p++;
+ t.value = hexStringConstant(t);
+ return;
+
+
+ case '"':
+// debug writefln( " string" );
+ t.value = escapeStringConstant( t, 0 );
+// debug writefln( t.ustring );
+ return;
+
+ case '\\': // escaped string literal
+// debug writefln( " escaped string literal" );
+ uint c;
+ stringbuffer.offset = 0;
+ do
+ {
+ p++;
+ c = escapeSequence();
+ stringbuffer.write(c);
+ } while (*p == '\\');
+// t.len = stringbuffer.offset;
+// stringbuffer.write(cast(byte)0);
+ t.ustring = stringbuffer.toString;
+// memcpy( t.ustring.ptr, stringbuffer.data, stringbuffer.offset );
+ t.postfix = 0;
+ t.value = TOK.TOKstring;
+ return;
+
+ case 'l':
+ case 'L':
+// #endif
+
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'm': case 'n': case 'o':
+ case 'p': case 'q': /*case 'r':*/ case 's': case 't':
+ case 'u': case 'v': case 'w': /*case 'x':*/ case 'y':
+ case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z':
+ case '_':
+ case_identifier:
+ {
+// debug writefln( " identifier" );
+ ubyte c;
+ do
+ {
+ c = *++p;
+ } while( isidchar(c) || (c & 0x80 && isUniAlpha( decodeUTF())) );
+
+// sv = stringtable.update((char *)t.ptr, p - t.ptr);
+ char[] tmp;
+ tmp.length = p - t.ptr;
+ memcpy( tmp.ptr, t.ptr, p - t.ptr );
+ Identifier id;
+ Identifier* pid = tmp in stringtable;
+ if( pid )
+ {
+ id = *pid;
+ }
+
+ if( id is null )
+ {
+ id = new Identifier( tmp, TOK.TOKidentifier );
+ stringtable[tmp] = id;
+ }
+
+ t.identifier = id;
+ t.value = cast(TOK) id.value;
+ anyToken = 1;
+
+ // if special identifier token
+ if( *t.ptr == '_')
+ {
+ static char date[11+1];
+ static char time[8+1];
+ static char timestamp[24+1];
+
+ if( !date[0] ) // lazy evaluation
+ {
+ //!!
+ /+
+ time_t t;
+ char *p;
+ .time(&t);
+ p = ctime(&t);
+ assert(p);
+ sprintf(date.ptr, "%.6s %.4s", p + 4, p + 20);
+ sprintf(time.ptr, "%.8s", p + 11);
+ sprintf(timestamp.ptr, "%.24s", p);
+ +/
+ }
+
+ if( mod && id is Id.FILE )
+ {
+ t.value = TOK.TOKstring;
+ if( loc.filename.length )
+ t.ustring = loc.filename;
+ else
+ t.ustring = mod.identifier.toChars();
+ goto Llen;
+ }
+ else if( mod && id == Id.LINE )
+ {
+ t.value = TOK.TOKint64v;
+ t.uns64value = loc.linnum;
+ }
+ else if( id == Id.DATE )
+ {
+ t.value = TOK.TOKstring;
+ //! t.ustring = date;
+ goto Llen;
+ }
+ else if( id == Id.TIME )
+ {
+ t.value = TOK.TOKstring;
+ //! t.ustring = time;
+ goto Llen;
+ }
+ else if( id == Id.TIMESTAMP )
+ {
+ t.value = TOK.TOKstring;
+ //! t.ustring = timestamp;
+ Llen:
+ t.postfix = 0;
+// t.len = strlen((char *)t.ustring);
+ }
+ }
+ //printf("t.value = %d\n",t.value);
+ return;
+ }
+
+ // comments
+ case '/':
+ p++;
+ switch( *p )
+ {
+ case '=':
+ p++;
+ t.value = TOK.TOKdivass;
+ return;
+
+ case '*': // '/*'
+ p++;
+ linnum = loc.linnum;
+ while( true )
+ {
+ while( true )
+ {
+ ubyte c = *p;
+ switch( c )
+ {
+ case '/':
+ break;
+
+ case '\n':
+ loc.linnum++;
+ p++;
+ continue;
+
+ case '\r':
+ p++;
+ if( *p != '\n')
+ loc.linnum++;
+ continue;
+
+ case 0:
+ case 0x1A:
+ error("unterminated /* */ comment");
+ p = end;
+ t.value = TOK.TOKeof;
+ return;
+
+ default:
+ if( c & 0x80)
+ {
+ uint u = decodeUTF();
+ if( u == PS || u == LS )
+ loc.linnum++;
+ }
+ p++;
+ continue;
+ }
+ break;
+ }
+ p++;
+ if( p[-2] == '*' && p - 3 != t.ptr )
+ break;
+ }
+
+ if( commentToken )
+ {
+ t.value = TOK.TOKcomment;
+ return;
+ }
+ // if /** but not /**/
+ else if( doDocComment && t.ptr[2] == '*' && p - 4 != t.ptr )
+ getDocComment( t, lastLine == linnum ); //! ?
+ continue;
+
+ case '/': // do // style comments
+ linnum = loc.linnum;
+ while (1)
+ {
+ ubyte c = *++p;
+ switch (c)
+ {
+ case '\n':
+ break;
+
+ case '\r':
+ if( p[1] == '\n')
+ p++;
+ break;
+
+ case 0:
+ case 0x1a:
+ if( commentToken )
+ {
+ p = end;
+ t.value = TOK.TOKcomment;
+ return;
+ }
+ if( doDocComment && t.ptr[2] == '/' )
+ getDocComment( t, lastLine == linnum );
+ p = end;
+ t.value = TOK.TOKeof;
+ return;
+
+ default:
+ if( c & 0x80)
+ {
+ uint u = decodeUTF();
+ if( u == PS || u == LS)
+ break;
+ }
+ continue;
+ }
+ break;
+ }
+
+ if( commentToken )
+ {
+ p++;
+ loc.linnum++;
+ t.value = TOK.TOKcomment;
+ return;
+ }
+ if( doDocComment && t.ptr[2] == '/' )
+ getDocComment( t, lastLine == linnum );
+
+ p++;
+ loc.linnum++;
+ continue;
+
+ case '+':
+ { int nest;
+ linnum = loc.linnum;
+ p++;
+ nest = 1;
+ while (1)
+ {
+ ubyte c = *p;
+ switch (c)
+ {
+ case '/':
+ p++;
+ if( *p == '+')
+ {
+ p++;
+ nest++;
+ }
+ continue;
+
+ case '+':
+ p++;
+ if( *p == '/')
+ {
+ p++;
+ if( --nest == 0)
+ break;
+ }
+ continue;
+
+ case '\r':
+ p++;
+ if( *p != '\n')
+ loc.linnum++;
+ continue;
+
+ case '\n':
+ loc.linnum++;
+ p++;
+ continue;
+
+ case 0:
+ case 0x1A:
+ error("unterminated /+ +/ comment");
+ p = end;
+ t.value = TOK.TOKeof;
+ return;
+
+ default:
+ if( c & 0x80 )
+ {
+ uint u = decodeUTF();
+ if( u == PS || u == LS)
+ loc.linnum++;
+ }
+ p++;
+ continue;
+ }
+ break;
+ }
+ if( commentToken )
+ {
+ t.value = TOK.TOKcomment;
+ return;
+ }
+ if( doDocComment && t.ptr[2] == '+' && p - 4 != t.ptr )
+ {
+ // if /++ but not /++/
+ getDocComment(t, lastLine == linnum);
+ }
+ continue;
+ }
+ default:
+ break;
+ }
+ t.value = TOK.TOKdiv;
+ return;
+
+ case '.':
+ p++;
+ if( isdigit(*p))
+ {
+ p--;
+ t.value = inreal(t);
+ }
+ else if( p[0] == '.')
+ {
+ if( p[1] == '.')
+ {
+ p += 2;
+ t.value = TOK.TOKdotdotdot;
+ }
+ else
+ {
+ p++;
+ t.value = TOK.TOKslice;
+ }
+ }
+ else
+ t.value = TOK.TOKdot;
+ return;
+
+ case '&':
+ p++;
+ if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKandass;
+ }
+ else if( *p == '&')
+ {
+ p++;
+ t.value = TOK.TOKandand;
+ }
+ else
+ t.value = TOK.TOKand;
+ return;
+
+ // |, ||, |=
+ case '|':
+ p++;
+ if( *p == '=' )
+ { p++;
+ t.value = TOK.TOKorass;
+ }
+ else if( *p == '|')
+ { p++;
+ t.value = TOK.TOKoror;
+ }
+ else
+ t.value = TOK.TOKor;
+ return;
+
+ case '-':
+ p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKminass;
+ }
+ else if( *p == '-')
+ { p++;
+ t.value = TOK.TOKminusminus;
+ }
+ else
+ t.value = TOK.TOKmin;
+ return;
+
+ // +, +=, ++
+ case '+':
+ p++;
+ if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKaddass; // +=
+ }
+ else if( *p == '+')
+ { p++;
+ t.value = TOK.TOKplusplus; // ++
+ }
+ else
+ t.value = TOK.TOKadd; // +
+ return;
+
+ // <, <=, <<=, <<, <>=, <>
+ case '<':
+ p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKle; // <=
+ }
+ else if( *p == '<')
+ { p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKshlass; // <<=
+ }
+ else
+ t.value = TOK.TOKshl; // <<
+ }
+ else if( *p == '>')
+ { p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKleg; // <>=
+ }
+ else
+ t.value = TOK.TOKlg; // <>
+ }
+ else
+ t.value = TOK.TOKlt; // <
+ return;
+
+ // >, >>, >>>, >=, >>=, >>>=
+ case '>':
+ p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKge; // >=
+ }
+ else if( *p == '>')
+ { p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKshrass; // >>=
+ }
+ else if( *p == '>')
+ { p++;
+ if( *p == '=')
+ { p++;
+ t.value = TOK.TOKushrass; // >>>=
+ }
+ else
+ t.value = TOK.TOKushr; // >>>
+ }
+ else
+ t.value = TOK.TOKshr; // >>
+ }
+ else
+ t.value = TOK.TOKgt; // >
+ return;
+
+ case '!':
+ p++;
+ if( *p == '=')
+ { p++;
+ if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKnotidentity; // !==
+ }
+ else
+ t.value = TOK.TOKnotequal; // !=
+ }
+ else if( *p == '<')
+ {
+ p++;
+ if( *p == '>')
+ {
+ p++;
+ if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKunord; // !<>=
+ }
+ else
+ t.value = TOK.TOKue; // !<>
+ }
+ else if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKug; // !<=
+ }
+ else
+ t.value = TOK.TOKuge; // !<
+ }
+ else if( *p == '>')
+ { p++;
+ if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKul; // !>=
+ }
+ else
+ t.value = TOK.TOKule; // !>
+ }
+ else
+ t.value = TOK.TOKnot; // !
+ return;
+
+ case '=':
+ p++;
+ if( *p == '=')
+ {
+ p++;
+ if( *p == '=')
+ {
+ p++;
+ t.value = TOK.TOKidentity; // ===
+ }
+ else
+ t.value = TOK.TOKequal; // ==
+ }
+ else
+ t.value = TOK.TOKassign; // =
+ return;
+
+ case '~':
+ p++;
+ if( *p == '=' )
+ {
+ p++;
+ t.value = TOK.TOKcatass; // ~=
+ }
+ else
+ t.value = TOK.TOKtilde; // ~
+ return;
+
+ // SINGLE
+ case '(': p++; t.value = TOK.TOKlparen; return;
+ case ')': p++; t.value = TOK.TOKrparen; return;
+ case '[': p++; t.value = TOK.TOKlbracket; return;
+ case ']': p++; t.value = TOK.TOKrbracket; return;
+ case '{': p++; t.value = TOK.TOKlcurly; return;
+ case '}': p++; t.value = TOK.TOKrcurly; return;
+ case '?': p++; t.value = TOK.TOKquestion; return;
+ case ',': p++; t.value = TOK.TOKcomma; return;
+ case ';': p++; t.value = TOK.TOKsemicolon; return;
+ case ':': p++; t.value = TOK.TOKcolon; return;
+ case '$': p++; t.value = TOK.TOKdollar; return;
+ // DOUBLE
+ case '*': p++; if( *p == '=' ) { p++; t.value = TOK.TOKmulass; } else t.value = TOK.TOKmul; return;
+ case '%': p++; if( *p == '=' ) { p++; t.value = TOK.TOKmodass; } else t.value = TOK.TOKmod; return;
+ case '^': p++; if( *p == '=' ) { p++; t.value = TOK.TOKxorass; } else t.value = TOK.TOKxor; return;
+// removed 148 case '~': p++; if( *p == '=' ) { p++; t.value = TOK.TOKcatass; } else t.value = TOK.TOKtilde; return;
+
+
+ case '#':
+ p++;
+ Pragma();
+ continue;
+
+ default:
+ {
+ debug writefln( " default char" );
+ ubyte c = *p;
+ if( c & 0x80 )
+ {
+ uint u = decodeUTF();
+ // Check for start of unicode identifier
+ if( isUniAlpha(u) )
+ goto case_identifier;
+
+ if( u == PS || u == LS )
+ {
+ loc.linnum++;
+ p++;
+ continue;
+ }
+ }
+ if( isprint(c))
+ error("unsupported char '%s'", cast(char)c);
+ else
+ error("unsupported char 0x%02x", cast(ubyte)c);
+ p++;
+ continue;
+ }
+ }
+ }
+ }
+
+
+
+ // Parse escape sequence.
+ uint escapeSequence()
+ {
+ uint c;
+ int n;
+ int ndigits;
+
+ c = *p;
+ switch ( c )
+ {
+ case '\'':
+ case '"':
+ case '?':
+ case '\\':
+ Lconsume:
+ p++;
+ break;
+
+ case 'a': c = 7; goto Lconsume;
+ case 'b': c = 8; goto Lconsume;
+ case 'f': c = 12; goto Lconsume;
+ case 'n': c = 10; goto Lconsume;
+ case 'r': c = 13; goto Lconsume;
+ case 't': c = 9; goto Lconsume;
+ case 'v': c = 11; goto Lconsume;
+
+ case 'u':
+ ndigits = 4;
+ goto Lhex;
+ case 'U':
+ ndigits = 8;
+ goto Lhex;
+ case 'x':
+ ndigits = 2;
+ Lhex:
+ p++;
+ c = *p;
+ if( ishex(c))
+ {
+ uint v;
+ n = 0;
+ v = 0;
+ while (1)
+ {
+ if( isdigit(c))
+ c -= '0';
+ else if( islower(c))
+ c -= 'a' - 10;
+ else
+ c -= 'A' - 10;
+ v = v * 16 + c;
+ c = *++p;
+ if( ++n == ndigits)
+ break;
+ if( !ishex(c))
+ { error("escape hex sequence has %d hex digits instead of %d", n, ndigits);
+ break;
+ }
+ }
+//! if( ndigits != 2 && !utf_isValidDchar(v))
+//! error("invalid UTF character \\U%08x", v);
+ c = v;
+ }
+ else
+ error("undefined escape hex sequence \\%s\n",c);
+ break;
+
+ case '&': // named character entity
+ for( ubyte *idstart = ++p; 1; p++ )
+ {
+ switch( *p )
+ {
+ case ';':
+ //!!!
+ /+
+ c = HtmlNamedEntity(idstart, p - idstart);
+ if( c == ~0 )
+ {
+ error("unnamed character entity &%.*s;", p - idstart, idstart);
+ c = ' ';
+ }
+
+ p++;
+ +/
+ break;
+
+ default:
+ if( isalpha(*p) || (p != idstart + 1 && isdigit(*p)))
+ continue;
+ error("unterminated named entity");
+ break;
+ }
+ break;
+ }
+ break;
+
+ case 0:
+ case 0x1a: // end of file
+ c = '\\';
+ break;
+
+ default:
+ if( isoctal(c) )
+ {
+ ubyte v;
+ n = 0;
+ do
+ {
+ v = v * 8 + (c - '0');
+ c = *++p;
+ } while (++n < 3 && isoctal(c));
+ c = v;
+ }
+ else
+ error("undefined escape sequence \\%s\n",c);
+ break;
+ }
+ return c;
+ }
+
+ /**************************************
+ */
+
+ TOK wysiwygStringConstant( Token *t, int tc )
+ {
+ uint c;
+ Loc start = loc;
+
+ p++;
+ stringbuffer.offset = 0;
+ while (1)
+ {
+ c = *p++;
+ switch( c )
+ {
+ case '\n':
+ loc.linnum++;
+ break;
+
+ case '\r':
+ if( *p == '\n')
+ continue; // ignore
+ c = '\n'; // treat EndOfLine as \n character
+ loc.linnum++;
+ break;
+
+ case 0:
+ case 0x1a:
+ error("unterminated string constant starting at %s", start.toChars());
+ t.ustring = "";
+ t.postfix = 0;
+ return TOK.TOKstring;
+
+ case '"':
+ case '`':
+ if( c == tc)
+ {
+// t.len = stringbuffer.offset;
+ stringbuffer.write(cast(byte)0);
+ t.ustring = stringbuffer.toString;
+// t.ustring = (ubyte *)mem.malloc(stringbuffer.offset);
+// memcpy(t.ustring, stringbuffer.data, stringbuffer.offset);
+ stringPostfix(t);
+ return TOK.TOKstring;
+ }
+ break;
+
+ default:
+ if( c & 0x80)
+ {
+ p--;
+ uint u = decodeUTF();
+ p++;
+ if( u == PS || u == LS)
+ loc.linnum++;
+ stringbuffer.write(u);
+ continue;
+ }
+ break;
+ }
+ stringbuffer.write(c);
+ }
+ }
+
+ /**************************************
+ * Lex hex strings:
+ * x"0A ae 34FE BD"
+ */
+
+ TOK hexStringConstant(Token *t)
+ {
+ uint c;
+ Loc start = loc;
+ uint n = 0;
+ uint v;
+
+ p++;
+ stringbuffer.offset = 0;
+ while (1)
+ {
+ c = *p++;
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ continue; // skip white space
+
+ case '\r':
+ if( *p == '\n')
+ continue; // ignore
+ // Treat isolated '\r' as if it were a '\n'
+ case '\n':
+ loc.linnum++;
+ continue;
+
+ case 0:
+ case 0x1a:
+ error("unterminated string constant starting at %s", start.toChars());
+ t.ustring = "";
+ t.postfix = 0;
+ return TOK.TOKstring;
+
+ case '"':
+ if( n & 1 )
+ {
+ error("odd number (%d) of hex characters in hex string", n);
+ stringbuffer.write(v);
+ }
+// t.len = stringbuffer.offset;
+// stringbuffer.write(cast(byte)0);
+ t.ustring = stringbuffer.toString;
+// t.ustring = (ubyte *)mem.malloc(stringbuffer.offset);
+// memcpy(t.ustring, stringbuffer.data, stringbuffer.offset);
+ stringPostfix(t);
+ return TOK.TOKstring;
+
+ default:
+ if( c >= '0' && c <= '9')
+ c -= '0';
+ else if( c >= 'a' && c <= 'f')
+ c -= 'a' - 10;
+ else if( c >= 'A' && c <= 'F')
+ c -= 'A' - 10;
+ else if( c & 0x80)
+ {
+ p--;
+ uint u = decodeUTF();
+ p++;
+ if( u == PS || u == LS)
+ loc.linnum++;
+ else
+ error("non-hex character \\u%x", u);
+ }
+ else
+ error("non-hex character '%s'", c);
+ if( n & 1)
+ {
+ v = (v << 4) | c;
+ stringbuffer.write(v);
+ }
+ else
+ v = c;
+ n++;
+ break;
+ }
+ }
+ }
+
+ /**************************************
+ */
+
+ TOK escapeStringConstant(Token *t, int wide)
+ {
+ uint c;
+ Loc start = loc;
+ p++;
+ stringbuffer.offset = 0;
+ // debug writefln( "escape string constant: %s", std.string.toString( cast(char*)p ) );
+ while( 1 )
+ {
+ c = *p++;
+ switch( c )
+ {
+ case '\\':
+ switch (*p)
+ {
+ case 'u':
+ case 'U':
+ case '&':
+ c = escapeSequence();
+ stringbuffer.write(c);
+ continue;
+
+ default:
+ c = escapeSequence();
+ break;
+ }
+ break;
+
+ case '\n':
+ loc.linnum++;
+ break;
+
+ case '\r':
+ if( *p == '\n')
+ continue; // ignore
+ c = '\n'; // treat EndOfLine as \n character
+ loc.linnum++;
+ break;
+
+ case '"':
+// writefln( "end of string: ", stringbuffer.toString );
+ t.ustring = stringbuffer.toString().dup;
+ // t.len = stringbuffer.offset;
+ // stringbuffer.write(cast(byte)0);
+ // t.ustring = (ubyte *)mem.malloc(stringbuffer.offset);
+ // memcpy(t.ustring, stringbuffer.data, stringbuffer.offset);
+ stringPostfix(t);
+
+ return TOK.TOKstring;
+
+ case 0:
+ case 0x1a:
+ p--;
+ error("unterminated string constant starting at %s", start.toChars());
+ t.ustring = "";
+// t.len = 0;
+ t.postfix = 0;
+ return TOK.TOKstring;
+
+ default:
+ if( c & 0x80 )
+ {
+ p--;
+ c = decodeUTF();
+ if( c == LS || c == PS )
+ {
+ c = '\n';
+ loc.linnum++;
+ }
+ p++;
+ stringbuffer.write(cast(char)c);
+ continue;
+ }
+ break;
+ }
+ stringbuffer.write(cast(char)c);
+// writefln( stringbuffer.toString );
+ }
+ }
+
+ //**************************************
+ TOK charConstant(Token *t, int wide)
+ {
+ uint c;
+ TOK tk = TOK.TOKcharv;
+ //printf("Lexer.charConstant\n");
+ p++;
+ c = *p++;
+ switch( c )
+ {
+ case '\\':
+ switch (*p)
+ {
+ case 'u':
+ t.uns64value = escapeSequence();
+ tk = TOK.TOKwcharv;
+ break;
+
+ case 'U':
+ case '&':
+ t.uns64value = escapeSequence();
+ tk = TOK.TOKdcharv;
+ break;
+
+ default:
+ t.uns64value = escapeSequence();
+ break;
+ }
+ break;
+
+ case '\n':
+ L1:
+ loc.linnum++;
+ case '\r':
+ case 0:
+ case 0x1a:
+ case '\'':
+ error("unterminated character constant");
+ return tk;
+
+ default:
+ if( c & 0x80)
+ {
+ p--;
+ c = decodeUTF();
+ p++;
+ if( c == LS || c == PS )
+ goto L1;
+ if( c < 0xd800 || (c >= 0xe000 && c < 0xfffe))
+ tk = TOK.TOKwcharv;
+ else
+ tk = TOK.TOKdcharv;
+ }
+ t.uns64value = c;
+ break;
+ }
+
+ if( *p != '\'' )
+ {
+ error("unterminated character constant");
+ return tk;
+ }
+ p++;
+ return tk;
+ }
+
+ // Get postfix of string literal.
+ void stringPostfix(Token *t)
+ {
+ switch( *p )
+ {
+ case 'c':
+ case 'w':
+ case 'd':
+ t.postfix = *p;
+ p++;
+ break;
+
+ default:
+ t.postfix = 0;
+ break;
+ }
+ }
+
+ /***************************************
+ * Read \u or \U unicode sequence
+ * Input:
+ * u 'u' or 'U'
+ */
+ /*
+ uint Wchar(uint u)
+ {
+ uint value;
+ uint n;
+ ubyte c;
+ uint nchars;
+
+ nchars = (u == 'U') ? 8 : 4;
+ value = 0;
+ for (n = 0; 1; n++)
+ {
+ ++p;
+ if( n == nchars)
+ break;
+ c = *p;
+ if( !ishex(c))
+ {
+ error("\\%s sequence must be followed by %d hex characters", u, nchars);
+ break;
+ }
+ if( isdigit(c))
+ c -= '0';
+ else if( islower(c))
+ c -= 'a' - 10;
+ else
+ c -= 'A' - 10;
+ value <<= 4;
+ value |= c;
+ }
+ return value;
+ }
+ */
+
+ /**************************************
+ * Read in a number.
+ * If it's an integer, store it in tok.TKutok.Vlong.
+ * integers can be decimal, octal or hex
+ * Handle the suffixes U, UL, LU, L, etc.
+ * If it's double, store it in tok.TKutok.Vdouble.
+ * Returns:
+ * TKnum
+ * TKdouble,...
+ */
+
+ TOK number(Token *t)
+ {
+ //debug writefln("Lexer.number()");
+ // We use a state machine to collect numbers
+ enum STATE
+ {
+ STATE_initial,
+ STATE_0,
+ STATE_decimal,
+ STATE_octal,
+ STATE_octale,
+ STATE_hex,
+ STATE_binary,
+ STATE_hex0,
+ STATE_binary0,
+ STATE_hexh,
+ STATE_error
+ }
+
+ enum FLAGS
+ {
+ FLAGS_decimal = 1, // decimal
+ FLAGS_unsigned = 2, // u or U suffix
+ FLAGS_long = 4, // l or L suffix
+ }
+ FLAGS flags = FLAGS.FLAGS_decimal;
+
+ int i;
+ TOK result;
+ int base;
+ stringbuffer.offset = 0;
+// stringbuffer.data = null;
+ STATE state = STATE.STATE_initial;
+ ubyte* start = p;
+
+ TOK _isreal()
+ {
+ p = start;
+ return inreal(t);
+ }
+
+ while( true )
+ {
+ char c = cast(char)*p;
+ switch( state )
+ {
+ case STATE.STATE_initial: // opening state
+ if( c == '0' )
+ state = STATE.STATE_0;
+ else
+ state = STATE.STATE_decimal;
+ break;
+
+ case STATE.STATE_0:
+ flags = cast(FLAGS) (flags & ~FLAGS.FLAGS_decimal);
+ switch (c)
+ {
+ // #if ZEROH
+// case 'H': // 0h
+// case 'h':
+// goto hexh;
+ // #endif
+ case 'X':
+ case 'x':
+ state = STATE.STATE_hex0;
+ break;
+
+ case '.':
+ if( p[1] == '.') // .. is a separate token
+ goto done;
+ case 'i':
+ case 'f':
+ case 'F':
+ goto _Real;
+ // #if ZEROH
+// case 'E':
+// case 'e':
+// goto case_hex;
+ // #endif
+ case 'B':
+ case 'b':
+ state = STATE.STATE_binary0;
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ state = STATE.STATE_octal;
+ break;
+
+ // #if ZEROH
+// case '8': case '9': case 'A':
+// case 'C': case 'D': case 'F':
+// case 'a': case 'c': case 'd': case 'f':
+// case_hex:
+// state = STATE.STATE_hexh;
+// break;
+ // #endif
+ case '_':
+ state = STATE.STATE_octal;
+ p++;
+ continue;
+
+ default:
+ goto done;
+ }
+ break;
+
+ case STATE.STATE_decimal: // reading decimal number
+
+ // if its not a digit - decimal complete or not a decimal
+ if( !isdigit( c ) )
+ {
+// debug writefln( "\tnon-digit( %s )", c );
+ // #if ZEROH
+// if( ishex(c) || c == 'H' || c == 'h' )
+// goto hexh;
+ // #endif
+ //! wtf ?
+ // ignore embedded _
+ if( c == '_' )
+ {
+ p++;
+ continue;
+ }
+
+ // check decimal point - make real
+ if( c == '.' && p[1] != '.' )
+ goto _Real;
+
+ // check for mantra - make real
+ if( c == 'i' || c == 'f' || c == 'F' || c == 'e' || c == 'E' )
+ {
+ _Real: // It's a real number. Back up and rescan as a real
+ p = start;
+ return inreal(t);
+ }
+
+ goto done;
+ }
+ break;
+
+ case STATE.STATE_hex0: // reading hex number
+ case STATE.STATE_hex:
+ if( !ishex(c) )
+ {
+ if( c == '_') // ignore embedded _
+ {
+ p++;
+ continue;
+ }
+ if( c == '.' && p[1] != '.' )
+ goto _Real;
+ if( c == 'P' || c == 'p' || c == 'i' )
+ goto _Real;
+ if( state == STATE.STATE_hex0 )
+ error("Hex digit expected, not '%s'", c);
+ goto done;
+ }
+ state = STATE.STATE_hex;
+ break;
+
+ // #if ZEROH
+// hexh:
+// state = STATE.STATE_hexh;
+//
+// case STATE.STATE_hexh: // parse numbers like 0FFh
+// if( !ishex(c))
+// {
+// if( c == 'H' || c == 'h')
+// {
+// p++;
+// base = 16;
+// goto done;
+// }
+// else
+// {
+// // Check for something like 1E3 or 0E24
+// if( memchr(stringbuffer.data.ptr, 'E', stringbuffer.offset) || memchr( stringbuffer.data.ptr, 'e', stringbuffer.offset))
+// goto _Real;
+// error("Hex digit expected, not '%s'", c);
+// goto done;
+// }
+// }
+// break;
+ // #endif
+
+ case STATE.STATE_octal: // reading octal number
+ case STATE.STATE_octale: // reading octal number with non-octal digits
+ if( !isoctal(c) )
+ {
+// #if ZEROH
+// if( ishex(c) || c == 'H' || c == 'h' )
+// goto hexh;
+// #endif
+ if( c == '_' ) // ignore embedded _
+ {
+ p++;
+ continue;
+ }
+ if( c == '.' && p[1] != '.' )
+ goto _Real;
+ if( c == 'i' )
+ goto _Real;
+ if( isdigit(c) )
+ state = STATE.STATE_octale;
+ else
+ goto done;
+ }
+ break;
+
+ case STATE.STATE_binary0: // starting binary number
+ case STATE.STATE_binary: // reading binary number
+ if( c != '0' && c != '1')
+ {
+ // #if ZEROH
+// if( ishex(c) || c == 'H' || c == 'h' )
+// goto hexh;
+ // #endif
+ if( c == '_' ) // ignore embedded _
+ {
+ p++;
+ continue;
+ }
+ if( state == STATE.STATE_binary0 )
+ {
+ error("binary digit expected");
+ state = STATE.STATE_error;
+ break;
+ }
+ else
+ goto done;
+ }
+ state = STATE.STATE_binary;
+ break;
+
+ case STATE.STATE_error: // for error recovery
+ if( !isdigit(c) ) // scan until non-digit
+ goto done;
+ break;
+
+ default:
+ assert(0);
+ }
+ stringbuffer.write(cast(char)c);
+ p++;
+ }
+ done:
+ stringbuffer.write( cast(char)0 ); // terminate string
+
+// debug writefln( "\tdigit complete( %s )", stringbuffer.toString );
+
+ if( state == STATE.STATE_octale )
+ error("Octal digit expected");
+
+ uinteger_t n; // unsigned >=64 bit integer type
+
+ if( stringbuffer.offset == 2 && ( state == STATE.STATE_decimal || state == STATE.STATE_0 ) )
+ n = stringbuffer.data[0] - '0';
+ else
+ {
+ // Convert string to integer
+ char* p = cast(char*)stringbuffer.data.ptr;
+ int r = 10;
+ int d;
+ if( *p == '0' )
+ {
+ if( p[1] == 'x' || p[1] == 'X')
+ {
+ // "0x#"
+ p += 2;
+ r = 16;
+ }
+ else if( p[1] == 'b' || p[1] == 'B')
+ {
+ // "0b#" - binary
+ p += 2;
+ r = 2;
+ }
+ else if( isdigit(p[1]))
+ {
+ p += 1;
+ r = 8;
+ }
+ }
+
+ n = 0;
+
+ while( true )
+ {
+ if( *p >= '0' && *p <= '9' )
+ d = *p - '0';
+ else if( *p >= 'a' && *p <= 'z' )
+ d = *p - 'a' + 10;
+ else if( *p >= 'A' && *p <= 'Z' )
+ d = *p - 'A' + 10;
+ else
+ break;
+
+ if( d >= r )
+ break;
+
+ if( n * r + d < n)
+ {
+ error( "integer overflow" );
+ break;
+ }
+
+ n = n * r + d;
+ p++;
+ }
+
+ // if n needs more than 64 bits
+ if( n.sizeof > 8 && n > 0xffffffffffffffffL )
+ error("integer overflow");
+ }
+
+ // Parse trailing 'u', 'U', 'l' or 'L' in any combination
+ while( true )
+ {
+ ubyte f;
+ switch( *p )
+ {
+ case 'U':
+ case 'u':
+ f = FLAGS.FLAGS_unsigned;
+ goto L1;
+ case 'L':
+ case 'l':
+ f = FLAGS.FLAGS_long;
+ L1:
+ p++;
+ if( flags & f )
+ error("unrecognized token");
+ flags = cast(FLAGS) (flags | f);
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+
+ switch ( flags )
+ {
+ case 0:
+ /* Octal or Hexadecimal constant.
+ * First that fits: int, uint, long, ulong
+ */
+ if( n & 0x8000000000000000L )
+ result = TOK.TOKuns64v;
+ else if( n & 0xffffffff00000000L )
+ result = TOK.TOKint64v;
+ else if( n & 0x80000000 )
+ result = TOK.TOKuns32v;
+ else
+ result = TOK.TOKint32v;
+ break;
+
+ case FLAGS.FLAGS_decimal:
+ /* First that fits: int, long, long long
+ */
+ if( n & 0x8000000000000000L )
+ {
+ error("signed integer overflow");
+ result = TOK.TOKuns64v;
+ }
+ else if( n & 0xffffffff80000000L )
+ result = TOK.TOKint64v;
+ else
+ result = TOK.TOKint32v;
+ break;
+
+ case FLAGS.FLAGS_unsigned:
+ case FLAGS.FLAGS_decimal | FLAGS.FLAGS_unsigned:
+ /* First that fits: uint, ulong
+ */
+ if( n & 0xffffffff00000000L )
+ result = TOK.TOKuns64v;
+ else
+ result = TOK.TOKuns32v;
+ break;
+
+ case FLAGS.FLAGS_decimal | FLAGS.FLAGS_long:
+ if( n & 0x8000000000000000L )
+ {
+ error("signed integer overflow");
+ result = TOK.TOKuns64v;
+ }
+ else
+ result = TOK.TOKint64v;
+ break;
+
+ case FLAGS.FLAGS_long:
+ if( n & 0x8000000000000000L )
+ result = TOK.TOKuns64v;
+ else
+ result = TOK.TOKint64v;
+ break;
+
+ case FLAGS.FLAGS_unsigned | FLAGS.FLAGS_long:
+ case FLAGS.FLAGS_decimal | FLAGS.FLAGS_unsigned | FLAGS.FLAGS_long:
+ result = TOK.TOKuns64v;
+ break;
+
+ default:
+ debug writefln("%x",flags);
+ assert(0);
+ }
+ t.uns64value = n;
+ return result;
+ }
+
+ /**************************************
+ * Read in characters, converting them to real.
+ * Bugs:
+ * Exponent overflow not detected.
+ * Too much requested precision is not detected.
+ */
+
+ TOK inreal(Token *t)
+ {
+ int dblstate;
+ uint c;
+ char hex; // is this a hexadecimal-floating-constant?
+ TOK result;
+
+ //printf("Lexer.inreal()\n");
+ stringbuffer.offset = 0;
+ dblstate = 0;
+ hex = 0;
+ Lnext:
+ while (1)
+ {
+ // Get next char from input
+ c = *p++;
+ //printf("dblstate = %d, c = '%s'\n", dblstate, c);
+ while (1)
+ {
+ switch (dblstate)
+ {
+ case 0: // opening state
+ if( c == '0')
+ dblstate = 9;
+ else if( c == '.')
+ dblstate = 3;
+ else
+ dblstate = 1;
+ break;
+
+ case 9:
+ dblstate = 1;
+ if( c == 'X' || c == 'x')
+ {
+ hex++;
+ break;
+ }
+ case 1: // digits to left of .
+ case 3: // digits to right of .
+ case 7: // continuing exponent digits
+ if( !isdigit(c) && !(hex && isxdigit(c)))
+ {
+ if( c == '_')
+ goto Lnext; // ignore embedded '_'
+ dblstate++;
+ continue;
+ }
+ break;
+
+ case 2: // no more digits to left of .
+ if( c == '.')
+ {
+ dblstate++;
+ break;
+ }
+ case 4: // no more digits to right of .
+ if( (c == 'E' || c == 'e') || hex && (c == 'P' || c == 'p'))
+ {
+ dblstate = 5;
+ hex = 0; // exponent is always decimal
+ break;
+ }
+ if( hex)
+ error("binary-exponent-part required");
+ goto done;
+
+ case 5: // looking immediately to right of E
+ dblstate++;
+ if( c == '-' || c == '+')
+ break;
+ case 6: // 1st exponent digit expected
+ if( !isdigit(c))
+ error("exponent expected");
+ dblstate++;
+ break;
+
+ case 8: // past end of exponent digits
+ goto done;
+ }
+ break;
+ }
+ stringbuffer.write(c);
+ }
+ done:
+ p--;
+
+ stringbuffer.write(cast(byte)0);
+
+// #if _WIN32 && __DMC__
+ char *save = __locale_decpoint;
+ __locale_decpoint = ".";
+// #endif
+ t.float80value = strtold(cast(char *)stringbuffer.data.ptr, null);
+ errno = 0;
+ switch( *p )
+ {
+ case 'F':
+ case 'f':
+ strtof(cast(char *)stringbuffer.data.ptr, null);
+ result = TOK.TOKfloat32v;
+ p++;
+ break;
+
+ default:
+ strtod(cast(char *)stringbuffer.data.ptr, null);
+ result = TOK.TOKfloat64v;
+ break;
+
+ case 'L':
+ case 'l':
+ result = TOK.TOKfloat80v;
+ p++;
+ break;
+ }
+ if( *p == 'i' || *p == 'I')
+ {
+ p++;
+ switch( result )
+ {
+ case TOK.TOKfloat32v:
+ result = TOK.TOKimaginary32v;
+ break;
+ case TOK.TOKfloat64v:
+ result = TOK.TOKimaginary64v;
+ break;
+ case TOK.TOKfloat80v:
+ result = TOK.TOKimaginary80v;
+ break;
+ }
+ }
+// #if _WIN32 && __DMC__
+ __locale_decpoint = save;
+// #endif
+ if( errno == ERANGE)
+ error("number is not representable");
+ return result;
+ }
+
+
+
+
+ /*********************************************
+ * Do pragma.
+ * Currently, the only pragma supported is:
+ * #line linnum [filespec]
+ */
+
+ void Pragma()
+ {
+ Token tok;
+ int linnum;
+ char[] filespec;
+ Loc loc = this.loc;
+
+ scan(&tok);
+
+ if( tok.value != TOK.TOKidentifier || tok.identifier != Id.line )
+ goto Lerr;
+
+ scan(&tok);
+ if( tok.value == TOK.TOKint32v || tok.value == TOK.TOKint64v )
+ linnum = tok.uns64value - 1;
+ else
+ goto Lerr;
+
+ while (1)
+ {
+ switch (*p)
+ {
+ case 0:
+ case 0x1a:
+ case '\n':
+ Lnewline:
+ this.loc.linnum = linnum;
+ if( filespec.length )
+ this.loc.filename = filespec;
+ return;
+
+ case '\r':
+ p++;
+ if( *p != '\n')
+ { p--;
+ goto Lnewline;
+ }
+ continue;
+
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ p++;
+ continue; // skip white space
+
+ case '_':
+ if( mod && memcmp(p, cast(char*)"__FILE__", 8) == 0)
+ {
+ p += 8;
+//! filespec = mem.strdup(loc.filename ? loc.filename : mod.identifier.toChars());
+ }
+ continue;
+
+ case '"':
+ if( filespec )
+ goto Lerr;
+ stringbuffer.offset = 0;
+ p++;
+ while (1)
+ {
+ uint c;
+ c = *p;
+ switch (c)
+ {
+ case '\n':
+ case '\r':
+ case 0:
+ case 0x1a:
+ goto Lerr;
+
+ case '"':
+ stringbuffer.write(cast(byte)0);
+ // filespec = mem.strdup((char *)stringbuffer.data);
+ filespec = stringbuffer.toString.dup;
+ p++;
+ break;
+
+ default:
+ if( c & 0x80 )
+ {
+ uint u = decodeUTF();
+ if( u == PS || u == LS )
+ goto Lerr;
+ }
+ stringbuffer.write(c);
+ p++;
+ continue;
+ }
+ break;
+ }
+ continue;
+
+ default:
+ if( *p & 0x80 )
+ {
+ uint u = decodeUTF();
+ if( u == PS || u == LS)
+ goto Lnewline;
+ }
+ goto Lerr;
+ }
+ }
+
+ Lerr:
+ errorLoc(loc, "#line integer [\"filespec\"]\\n expected");
+ }
+
+
+
+ /***************************************************
+ * Parse doc comment embedded between t.ptr and p.
+ * Remove trailing blanks and tabs from lines.
+ * Replace all newlines with \n.
+ * Remove leading comment character from each line.
+ * Decide if it's a lineComment or a blockComment.
+ * Append to previous one for this token.
+ */
+
+ void getDocComment( Token *t, uint lineComment )
+ {
+ auto OutBuffer buf = new OutBuffer;
+ ubyte ct = t.ptr[2];
+ ubyte *q = t.ptr + 3; // start of comment text
+ int linestart = 0;
+
+ ubyte *qend = p;
+
+ if( ct == '*' || ct == '+')
+ qend -= 2;
+
+ // Scan over initial row of ****'s or ++++'s or ////'s
+ for (; q < qend; q++)
+ {
+ if( *q != ct)
+ break;
+ }
+
+ // Remove trailing row of ****'s or ++++'s
+ if( ct != '/')
+ {
+ for (; q < qend; qend--)
+ {
+ if( qend[-1] != ct)
+ break;
+ }
+ }
+
+ for (; q < qend; q++)
+ {
+ ubyte c = *q;
+
+ switch (c)
+ {
+ case '*':
+ case '+':
+ if( linestart && c == ct)
+ { linestart = 0;
+ // Trim preceding whitespace up to preceding \n
+ while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t'))
+ buf.offset--;
+ continue;
+ }
+ break;
+
+ case ' ':
+ case '\t':
+ break;
+
+ case '\r':
+ if( q[1] == '\n')
+ continue; // skip the \r
+ goto Lnewline;
+
+ default:
+ if( c == 226)
+ {
+ // If LS or PS
+ if( q[1] == 128 &&
+ (q[2] == 168 || q[2] == 169))
+ {
+ q += 2;
+ goto Lnewline;
+ }
+ }
+ linestart = 0;
+ break;
+
+ Lnewline:
+ c = '\n'; // replace all newlines with \n
+ case '\n':
+ linestart = 1;
+
+ // Trim trailing whitespace
+ while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t'))
+ buf.offset--;
+
+ break;
+ }
+ buf.write(c);
+ }
+
+ // Always end with a newline
+ if( !buf.offset || buf.data[buf.offset - 1] != '\n' )
+ buf.writenl();
+
+ //buf.write(cast(char)0);
+
+ // It's a line comment if the start of the doc comment comes
+ // after other non-whitespace on the same line.
+// ubyte** dc = (lineComment && anyToken)
+// ? &t.lineComment
+// : &t.blockComment;
+
+ char[] dc = (lineComment && anyToken) ? t.lineComment : t.blockComment;
+
+ // Combine with previous doc comment, if any
+ if( dc.length )
+ dc = combineComments( dc, buf.toString().dup );
+ else
+ dc = buf.toString().dup;
+
+// writefln( dc );
+
+ if( lineComment && anyToken )
+ t.lineComment = dc;
+ else
+ t.blockComment = dc;
+
+ }
+
+}
+
+// character maps
+static ubyte[256] cmtable;
+
+const int CMoctal = 0x1;
+const int CMhex = 0x2;
+const int CMidchar = 0x4;
+
+ubyte isoctal (ubyte c) { return cmtable[c] & CMoctal; }
+ubyte ishex (ubyte c) { return cmtable[c] & CMhex; }
+ubyte isidchar(ubyte c) { return cmtable[c] & CMidchar; }
+
+static void cmtable_init()
+{
+ for( uint c = 0; c < cmtable.length; c++ )
+ {
+ if( '0' <= c && c <= '7' )
+ cmtable[c] |= CMoctal;
+ if( isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') )
+ cmtable[c] |= CMhex;
+ if( isalnum(c) || c == '_' )
+ cmtable[c] |= CMidchar;
+ }
+}
+
+
+/+
+struct StringValue
+{
+ union
+ {
+ int intvalue;
+ void *ptrvalue;
+ dchar *string;
+ }
+
+ char[] lstring;
+}
+#define CASE_BASIC_TYPES
+ case TOKwchar: case TOKdchar:
+ case TOKbit: case TOKbool: case TOKchar:
+ case TOKint8: case TOKuns8:
+ case TOKint16: case TOKuns16:
+ case TOKint32: case TOKuns32:
+ case TOKint64: case TOKuns64:
+ case TOKfloat32: case TOKfloat64: case TOKfloat80:
+ case TOKimaginary32: case TOKimaginary64: case TOKimaginary80:
+ case TOKcomplex32: case TOKcomplex64: case TOKcomplex80:
+ case TOKvoid:
+
+#define CASE_BASIC_TYPES_X(t) \
+ case TOKvoid: t = Type::tvoid; goto LabelX; \
+ case TOKint8: t = Type::tint8; goto LabelX; \
+ case TOKuns8: t = Type::tuns8; goto LabelX; \
+ case TOKint16: t = Type::tint16; goto LabelX; \
+ case TOKuns16: t = Type::tuns16; goto LabelX; \
+ case TOKint32: t = Type::tint32; goto LabelX; \
+ case TOKuns32: t = Type::tuns32; goto LabelX; \
+ case TOKint64: t = Type::tint64; goto LabelX; \
+ case TOKuns64: t = Type::tuns64; goto LabelX; \
+ case TOKfloat32: t = Type::tfloat32; goto LabelX; \
+ case TOKfloat64: t = Type::tfloat64; goto LabelX; \
+ case TOKfloat80: t = Type::tfloat80; goto LabelX; \
+ case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
+ case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
+ case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
+ case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
+ case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
+ case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
+ case TOKbit: t = Type::tbit; goto LabelX; \
+ case TOKchar: t = Type::tchar; goto LabelX; \
+ case TOKwchar: t = Type::twchar; goto LabelX; \
+ case TOKdchar: t = Type::tdchar; goto LabelX; \
+ LabelX
++/
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/bug-indent.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/bug-indent.d
new file mode 100644
index 00000000..321ab6f1
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/bug-indent.d
@@ -0,0 +1,34 @@
+class TemplatedClass(T) {}
+class TemplatedClass2(T,U) {}
+
+class Axxxxxxxxxxxxxxxx {
+alias A = int*;
+void f(){
+}
+}
+
+class C
+{
+ //--------------| <= (1) - non first col comment -> indent
+Axxxxxxxxxxxxxxxx.A createAssignment()
+{
+ return(null);
+}
+void func2(Axxxxxxxxxxxxxxxx[] container){
+ foreach (v; container) {
+ v.f();
+ }
+}
+
+ // | <= (2)
+void func3(TemplatedClass!int aValue)
+{
+}
+
+void func4(TemplatedClass2!(int, int) b){
+}
+}
+
+int main(){
+ return 0;
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/casts.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/casts.d
new file mode 100644
index 00000000..42d54916
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/casts.d
@@ -0,0 +1,13 @@
+void foo(int a)
+{
+ char ch;
+
+ ch = cast(char) a;
+ ch = cast(char) 45;
+ ch = (char) a; // not a d cast
+ ch = (int)45;
+ ch = cast(foo)*bar;
+ ch = cast(foo)-bar;
+ ch = cast(foo)+45;
+ ch = cast(foo)&45;
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/const.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/const.d
new file mode 100644
index 00000000..778957fd
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/const.d
@@ -0,0 +1,9 @@
+// hello
+A b() {
+ return null;
+}
+
+const(C) d() {
+ return null;
+}
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/d_sp_paren.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/d_sp_paren.d
new file mode 100644
index 00000000..2b28a7f1
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/d_sp_paren.d
@@ -0,0 +1,23 @@
+version(unittest) {
+import foo;
+}
+
+void main() {
+scope(exit) {
+foo();
+}
+
+scope(success) suckit();
+
+scope f = new Foo();
+if(foo)
+{
+}
+
+try {
+throw(e);
+}
+catch(Exception e) {
+}
+}
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/delegate.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/delegate.d
new file mode 100644
index 00000000..0115ae00
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/delegate.d
@@ -0,0 +1,20 @@
+module er;
+
+void delegate(ubyte[] a) TSender;
+bool delegate(ushort a) TVerifier;
+typedef ushort TAddr;
+
+public void delegate(ubyte[] a) TSender;
+public bool delegate(ushort a) TVerifier;
+public typedef ushort TAddr;
+
+void delegate() dg;
+ dg = { int y; };
+
+ int opApply(int delegate(inout Type [, ...]) dg);
+
+void main()
+{
+ assert( findIf( "bcecg", ( int x ) { return x == 'a'; } ) == 5 );
+}
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/enum.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/enum.d
new file mode 100644
index 00000000..804ef27c
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/enum.d
@@ -0,0 +1,6 @@
+/* sized enum like in C# */
+enum Metrics : int {
+SM_CXSCREEN = 0,
+SM_CYSCREEN,
+SM_CXVSCROLL,
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/extern_.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/extern_.d
new file mode 100644
index 00000000..a583b08e
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/extern_.d
@@ -0,0 +1,6 @@
+extern(D): void func();
+
+void x()
+{
+ int xx;
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/funcfunc.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/funcfunc.d
new file mode 100644
index 00000000..ee717abc
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/funcfunc.d
@@ -0,0 +1,5 @@
+int main()
+{
+ mWriter( "class Clst_"c )( cluster.getChild( HO_SHORT_NAME ).getText() )( " : Cluster {"c ).newline;
+}
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/imports.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/imports.d
new file mode 100644
index 00000000..758fefb7
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/imports.d
@@ -0,0 +1,8 @@
+
+private import mango.cache.Payload;
+
+private import mango.io.Exception,
+ mango.io.PickleRegistry;
+
+public import mango.cluster.model.ICluster;
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/invariant.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/invariant.d
new file mode 100644
index 00000000..46a8efdc
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/invariant.d
@@ -0,0 +1 @@
+invariant (C) c;
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/numbers.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/numbers.d
new file mode 100644
index 00000000..e51bf8ac
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/numbers.d
@@ -0,0 +1,45 @@
+
+/* This file goes over all the various number formats for D */
+
+int foo(int bar)
+{
+ int a;
+
+ /*
+ * Interger Literals
+ */
+
+ /* Suffixes */
+ a = 0L + 123U + 345u + 456Lu + 567LU + 678UL + 789_uL;
+
+ /* Decimal */
+ a = 0 + 123456 + 123_456 + 1_2_3_4_5_6;
+
+ /* Binary */
+ a = 0b1010101 + 0B1001;
+
+ /* Octal */
+ a = 01234567_ + 07_6_5_2;
+
+ /* Hexadecimal */
+ a = 0x1234567890abcdefABCDEF_ + 0X7_6_5_2;
+
+ float b;
+ real c;
+ ifloat d;
+ ireal e;
+
+ /* Floats: float [FloatSuffix] [ImaginarySuffix] */
+
+ /* HexFloat */
+ b = 0xabc.defp-1024 + 0x.defP-64 + 0x123p+32 + 0x123P+16 + 0x123p1024;
+ d = 0x123p45 + 0x234.fi + 0. + .3f;
+ e = 3 + 5i;
+ e = 3.4 + 5.6i;
+}
+
+/* test '..' ranges */
+void main() {
+ char[] c = "kkkkkkkkkkkkkkkkkkkkk";
+ writefln("%s", c[2..3]);
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/sort_import.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/sort_import.d
new file mode 100644
index 00000000..d929f8e8
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/sort_import.d
@@ -0,0 +1,19 @@
+// should be ddd, eee, fff
+import ddd;
+import fff;
+import eee;
+
+// should be aaa, ccc
+import ccc;
+import aaa;
+// should be just bbb
+import bbb;
+
+// should not change these, as it can't handle multi-line imports
+private import mango.ccc;
+private import mango.bbb,
+ mango.aaa;
+
+void foo();
+
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/square_indent_tab.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/square_indent_tab.d
new file mode 100644
index 00000000..1dee3a17
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/square_indent_tab.d
@@ -0,0 +1,24 @@
+auto getOperatorsMap() {
+ return [
+ "/" : TokenType.Slash,
+ "/=" : TokenType.SlashAssign,
+ "." : TokenType.Dot,
+ ".." : TokenType.DoubleDot,
+ "..." : TokenType.TripleDot,
+ "&" : TokenType.Ampersand,
+ "&=" : TokenType.AmpersandAssign,
+ "&&" : TokenType.DoubleAmpersand,
+ "|" : TokenType.Pipe,
+ "|=" : TokenType.PipeAssign,
+ "||" : TokenType.DoublePipe,
+ "-" : TokenType.Minus,
+ "-=" : TokenType.MinusAssign,
+ "--" : TokenType.DoubleMinus,
+ "+" : TokenType.Plus,
+ "+=" : TokenType.PlusAssign,
+ "++" : TokenType.DoublePlus,
+ "<" : TokenType.Less,
+ "<=" : TokenType.LessAssign,
+ "<<" : TokenType.DoubleLess
+ ];
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if.d
new file mode 100644
index 00000000..24e6eaba
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if.d
@@ -0,0 +1,14 @@
+ClLinearExpression opBinary(string op) (double constant)
+ {
+ static if (op == "+")
+ return new ClLinearExpression(this, 1, constant);
+ else
+ static if (op == "-")
+ return new ClLinearExpression(this, 1, -constant);
+ else
+ static if (op == "*")
+ return new ClLinearExpression(this, constant, 0);
+ else
+ static if (op == "/")
+ return new ClLinearExpression(this, 1.0 / constant, 0);
+ }
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if_in_struct.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if_in_struct.d
new file mode 100644
index 00000000..be936335
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/static_if_in_struct.d
@@ -0,0 +1,5 @@
+struct Widget {
+ static if (true)
+ void fun() {
+ }
+} \ No newline at end of file
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/strings.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/strings.d
new file mode 100644
index 00000000..a62adec3
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/strings.d
@@ -0,0 +1,32 @@
+
+/* This file goes over all the various string formats for D */
+
+int foo(int bar)
+{
+ char [] a;
+ char b;
+
+ a = r"WYSIWYG";
+ a = `WYSIWYG`;
+ b = 'c';
+ a = x"12 34 5678 90";
+ a = "This\nis a \"test\"";
+ a = \' ~ \" ~ \? ~ \\ ~ \a ~ \b ~ \f ~ \n ~ \r ~ \t ~ \v;
+ a = \x1B ~ \0 ~ \74 ~ \123;
+ a = \u1234 ~ \U12345678;
+ a = \&amp; ~ 'a';
+ a = "Another" " " "Test";
+
+ /+ test back to back EscapeSequences +/
+ a = \r\n\xff\&amp;\u1234;
+
+ a = "char"c;
+ a = "wchar"w;
+ a = "dchar"d;
+
+ /*
+ * multi line string
+ */
+ a = r"Line 1
+ line 2";
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template.d
new file mode 100644
index 00000000..fe5a162c
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template.d
@@ -0,0 +1,27 @@
+template Foo (T, U)
+{
+class Bar { }
+
+T foo(T t, U u) { }
+
+T abc;
+
+typedef T* FooType;
+typedef Tte** FooType0;
+typedef int* FooType1;
+typedef const char FooType2;
+}
+
+alias Foo!(int, char) f;
+f.Bar b;
+f.foo(1,2);
+f.abc = 3;
+
+ to!string(10.0);
+ TFoo!int.t x;
+
+class Abc (T)
+{
+ T t;
+}
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing000.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing000.d
new file mode 100644
index 00000000..627ca266
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing000.d
@@ -0,0 +1,12 @@
+void fun() {
+ if (something(a1, a2))
+ return;
+ if (something!a1)
+ return;
+ if (something!(a1, a2) )
+ return;
+ if (something!(a1, a2).Ptr)
+ return;
+ if (something!a1.Ptr)
+ return;
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing001.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing001.d
new file mode 100644
index 00000000..745e5b36
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_spacing001.d
@@ -0,0 +1,9 @@
+void func0(TemplatedClass2!(int, int) b){
+}
+
+void func1(TemplatedClass2!(int, int)b){
+}
+
+
+void func2(TemplatedClass!int b){
+} \ No newline at end of file
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_use.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_use.d
new file mode 100644
index 00000000..94cdbf6b
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/template_use.d
@@ -0,0 +1,2 @@
+auto x = a!"23" + a!`23` + a!`2
+3` + a!23 + a!23.23;
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst01.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst01.d
new file mode 100644
index 00000000..3a3728f2
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst01.d
@@ -0,0 +1,23 @@
+package void writeRegister(int aRegisterOffset, ushort aValue)
+in {
+ assert(aRegisterOffset >= 0);
+ assert(aRegisterOffset < IMAGE_SIZE);
+} body {
+int idx = aRegisterOffset / 2;
+ mMemCache[idx] = aValue;
+ uint readback;
+ uint st;
+ uint st2;
+ volatile {
+ mMemImage[idx] = aValue;
+ //readback = (cast(uint*)mMemImage.ptr)[ idx/2 ];
+ //st = mMemImage[ 0x28/2 ];
+ //st2 = mMemImage[ 0x2A/2 ];
+ }
+ //if( aValue != readback )
+ {
+ //debug(IRQ) writefln( "writeRegister %04x, %04x", aRegisterOffset, aValue);
+ }
+ // comment
+}
+//
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst02.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst02.d
new file mode 100644
index 00000000..0b428d60
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst02.d
@@ -0,0 +1,30 @@
+ package static ushort calcHeaderCrc(bool aStartupFrame, bool aSyncFrame, ushort aFrameId, ushort aPayloadWords) {
+ uint crcData = aPayloadWords;
+
+ crcData |= (aFrameId << 7);
+
+ if (aSyncFrame) {
+ crcData |= BIT_19;
+ }
+
+ if (aStartupFrame) {
+ crcData |= BIT_18;
+ }
+
+ ushort crc = 0x1a;
+ const ushort table[16] = [
+ 0x0000, 0x0385, 0x070A, 0x048F,
+ 0x0591, 0x0614, 0x029B, 0x011E,
+ 0x00A7, 0x0322, 0x07AD, 0x0428,
+ 0x0536, 0x06B3, 0x023C, 0x01B9];
+
+ for (int i = 0; i < 5; ++i) {
+ if (i != 0) {
+ crcData <<= 4;
+ }
+ crc = ((crc << 4) & 0x7FF) ^ table[((crc >> 7) ^ (crcData >> 16)) & 0x0F];
+ }
+
+ return(crc);
+ }
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst03.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst03.d
new file mode 100644
index 00000000..611f12f9
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/tst03.d
@@ -0,0 +1,145 @@
+import std.stdio;
+
+void foo()
+{
+float f = x % y;
+double d = x % y;
+real r = x % y;
+result = (x < y); // false if x or y is nan
+assert(e == 0);
+int array[17];
+array[] = value;
+int array[17];
+for (i = 0; i < array.length; i++)
+ func(array[i]);
+int array[17];
+foreach (int value; array)
+ func(value);
+int[] array;
+
+array.length = array.length + 1;
+array[array.length - 1] = x;
+char[] s1;
+char[] s2;
+char[] s;
+
+s = s1 ~ s2;
+s ~= "hello";
+
+
+writefln("Calling all cars %s times!", ntimes);
+Louter:
+ for (i = 0; i < 10; i++)
+ {
+ for (j = 0; j < 10; j++)
+ {
+ if (j == 3)
+ break Louter;
+ if (j == 4)
+ continue Louter;
+ }
+ }
+ // break Louter goes here
+ typedef bit bHandle;
+ typedef int iHandle = -1;
+typedef void* Handle = cast(void*)(-1);
+Handle h;
+h = func();
+if (h != Handle.init)
+ ;
+char[] string = "hello";
+
+if (string < "betty")
+;
+int* p = address;
+
+volatile { i = *p; }
+
+char [] ml = "This text spans
+multiple
+lines
+";
+
+}
+
+void dostring(char[] s)
+{
+ switch (s)
+ {
+ case "hello": ;
+ case "goodbye": ;
+ case "maybe": ;
+ default: ;
+ }
+}
+
+struct ABC
+{
+ int z; // z is aligned to the default
+
+ align (1) int x; // x is byte aligned
+ align (4)
+ {
+ ... // declarations in {} are dword aligned
+ }
+ align (2): // switch to word alignment from here on
+
+ int y; // y is word aligned
+}
+
+struct Foo
+{
+ int i;
+ union
+ {
+ struct { int x; long y; }
+ char* p;
+ }
+}
+
+struct Foo { int x; int y; } // note there is no terminating ;
+Foo foo;
+
+
+struct Foo { int x; int y; }
+
+off = Foo.y.offsetof;
+
+union U { int a; long b; }
+U x = { a:5 };
+
+struct S { int a; int b; }
+S x = { b:3, a:5 };
+
+int[3] a = [ 3, 2, 0 ];
+int[3] a = [ 3, 2 ]; // unsupplied initializers are 0, just like in C
+int[3] a = [ 2:0, 0:3, 1:2 ];
+int[3] a = [ 2:0, 0:3, 2 ]; // if not supplied, the index is the
+ // previous one plus one.
+
+enum color { black, red, green }
+int[3] c = [ black:3, green:2, red:5 ];
+
+char[] file = `c:\root\file.c`;
+char[] quoteString = \" r"[^\\]*(\\.[^\\]*)*" \";
+
+char[] hello = "hello world" \n;
+char[] foo_ascii = "hello"; // string is taken to be ascii
+wchar[] foo_wchar = "hello"; // string is taken to be wchar
+
+enum COLORS { red, blue, green };
+
+char[][COLORS.max + 1] cstring =
+[
+ COLORS.red : "red",
+ COLORS.blue : "blue",
+ COLORS.green : "green",
+];
+
+ const ushort table1[16] = [
+ 0x00A7, 0x0322, 0x07AD, 0x0428,
+ 0x0536, 0x06B3, 0x023C, 0x01B9];
+
+ const ushort table2[16] = [ 0x0000, 0x0385, 0x070A, 0x048F,
+ 0x0536, 0x06B3, 0x023C, 0x01B9];
+
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/type_spacing000.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/type_spacing000.d
new file mode 100644
index 00000000..e11e545b
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/type_spacing000.d
@@ -0,0 +1,2 @@
+alias jhash hash;
+alias Foo!(int, char) f;
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces000.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces000.d
new file mode 100644
index 00000000..d2f1b642
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces000.d
@@ -0,0 +1,12 @@
+struct A
+{
+ static if (true)
+ void f() { }
+}
+struct B
+{
+ static if(true)
+ int a;
+ else
+ int e;
+} \ No newline at end of file
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces001.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces001.d
new file mode 100644
index 00000000..a59ab020
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces001.d
@@ -0,0 +1,9 @@
+module x;
+static if (1)
+ void fun()
+ {
+ }
+static if (1)
+ void gun()
+ {
+ } \ No newline at end of file
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces002.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces002.d
new file mode 100644
index 00000000..5e45e999
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/vbraces002.d
@@ -0,0 +1,19 @@
+int super_fun(bool a, bool b, bool c, bool d)
+{
+ int i = 6;
+ static if (true)
+ while (true)
+ if(b)
+ return 1;
+ else if (c)
+ while (true)
+ if(d)
+ return 2;
+ else
+ while (true)
+ if(a)
+ return 3;
+ while (d)
+ return 4;
+ return 1;
+} \ No newline at end of file
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-1.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-1.d
new file mode 100644
index 00000000..c9f41d3f
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-1.d
@@ -0,0 +1,10 @@
+{
+ while (a)
+ {
+ volatile if (b)
+ {
+ b--;
+ break;
+ }
+ }
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-2.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-2.d
new file mode 100644
index 00000000..bc5a0de4
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-2.d
@@ -0,0 +1,8 @@
+{
+ if (e)
+ volatile
+ {
+ a++;
+ }
+ return oldValue;
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-3.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-3.d
new file mode 100644
index 00000000..039f788a
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile-3.d
@@ -0,0 +1,7 @@
+{
+ if (e)
+ {
+ if (!value)
+ volatile e.value = value;
+ }
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile.d
new file mode 100644
index 00000000..c42d1893
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/volatile.d
@@ -0,0 +1,27 @@
+void foo(void)
+{
+while (nextSegmentIndex >= 0)
+{
+ Segment seg = map.segments[nextSegmentIndex--];
+ volatile if (seg.count)
+ {
+ currentTable = seg.table;
+ for (int j = currentTable.length - 1; j >= 0; --j)
+ {
+ if ((nextEntry = currentTable[j]) !is null)
+ {
+ nextTableIndex = j - 1;
+ return;
+ }
+ }
+ }
+}
+
+if (e)
+ volatile
+ {
+ oldValue = e.value;
+ e.value = newValue;
+ }
+return oldValue;
+}
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/wysiwyg_strings.d b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/wysiwyg_strings.d
new file mode 100644
index 00000000..cfdec32a
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d/wysiwyg_strings.d
@@ -0,0 +1,9 @@
+auto s = `\`;
+auto t = `\a
+b
+`;
+
+auto u = r"\";
+auto v = r"\a
+b
+"; \ No newline at end of file