diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/d')
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 = \& ~ 'a'; + a = "Another" " " "Test"; + + /+ test back to back EscapeSequences +/ + a = \r\n\xff\&\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 |