This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository mkgmap.

commit e042a28f504f79a79a17d00dccace7f64331ebcd
Author: Bas Couwenberg <sebas...@xs4all.nl>
Date:   Tue Mar 3 23:01:06 2015 +0100

    Imported Upstream version 0.0.0+svn3478
---
 resources/help/en/options                          |  10 ++
 resources/mkgmap-version.properties                |   4 +-
 resources/styles/default/inc/name                  |   8 +
 resources/styles/default/lines                     |   3 +-
 .../parabola/imgfmt/app/labelenc/Utf8Decoder.java  |   1 -
 src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java       |  14 +-
 src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java       |   2 +-
 src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java       |  41 +++--
 src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java        | 183 +++++++++++++++++++--
 src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java  |  43 +++++
 src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java   |   9 +
 .../parabola/mkgmap/combiners/GmapsuppBuilder.java |   4 +-
 .../me/parabola/mkgmap/combiners/MdrBuilder.java   |   4 +-
 .../parabola/mkgmap/osmstyle/RuleFileReader.java   |  38 +++--
 .../me/parabola/mkgmap/scan/SyntaxException.java   |   2 +-
 test/resources/rules/multi-or-twice.test           |  18 ++
 test/resources/rules/multi-or-with-and.test        |  19 +++
 test/resources/rules/or-at-end.test                |  30 ++++
 .../mkgmap/osmstyle/RuleFileReaderTest.java        |   1 +
 19 files changed, 376 insertions(+), 58 deletions(-)

diff --git a/resources/help/en/options b/resources/help/en/options
index f13bef2..5a978e6 100644
--- a/resources/help/en/options
+++ b/resources/help/en/options
@@ -125,6 +125,16 @@ Address search options:
   same code page and sorting options (eg. --code-page, --latin1 etc) must
   be used as were used to compile the individual map tiles.
 
+--x-split-name-index
+    A temporary option to enable indexing each part of a street name 
separately.
+    So for example if the street is "Aleksandra Gryglewskiego" then you will 
be able to
+    search for it as both "Aleksandra" and "Gryglewskiego".  It will also 
increase the
+    size of the index.  Useful in countries where searching for the first word 
in name
+    is not the right thing to do.
+
+    Note that this option is still experimental and there may be problems. If 
you find
+    any let us know!
+
 --bounds=directory|zipfile
     A directory or a zipfile containing the preprocessed bounds files. 
     Bounds files in a zipfile must be located in the zipfiles root directory.
diff --git a/resources/mkgmap-version.properties 
b/resources/mkgmap-version.properties
index 78cc6d5..7a0d191 100644
--- a/resources/mkgmap-version.properties
+++ b/resources/mkgmap-version.properties
@@ -1,2 +1,2 @@
-svn.version: 3436
-build.timestamp: 2015-02-02T06:43:48+0000
+svn.version: 3478
+build.timestamp: 2015-02-26T07:49:21+0000
diff --git a/resources/styles/default/inc/name 
b/resources/styles/default/inc/name
index f3e9d98..67f0a62 100644
--- a/resources/styles/default/inc/name
+++ b/resources/styles/default/inc/name
@@ -13,6 +13,7 @@ operator=${name}  { delete operator; }
 brand=${name}     { delete brand; }
 
 # None of operator, brand given
+ref=* & (operator!=* & brand!=*) & (highway=bus_stop | railway=tram_stop | 
railway=halt | railway=station) { name '${name} ${ref}' | '${ref}' }
 ref=* & (operator!=* & brand!=*) { name '${ref} ${name}' | '${ref}' }
 
 # Both operator and brand given
@@ -24,6 +25,13 @@ operator=* & brand=* {
 }
 
 # One of operator or brand given
+operator=* & brand!=* & (highway=bus_stop | railway=tram_stop | railway=halt | 
railway=station) {
+ name '${name} ${ref} ${operator}' |
+      '${name} ${operator}' |
+      '${ref} ${operator}' |
+      '${operator}'
+}
+
 operator=* & brand!=* {
  name '${operator}: ${ref} ${name}' |
       '${operator}: ${name}' |
diff --git a/resources/styles/default/lines b/resources/styles/default/lines
index c43a29c..e2d79c0 100644
--- a/resources/styles/default/lines
+++ b/resources/styles/default/lines
@@ -163,7 +163,8 @@ power=line [0x29 resolution 21]
 
 railway=abandoned [0x0a road_class=0 road_speed=1 resolution 22]
 railway=platform [0x16 road_class=0 road_speed=0 resolution 23]
-railway=* & !(tunnel=yes) [0x14 resolution 22]
+# Railway lines, note that many devices display type 0x14 only at resolution 
24 
+(railway=rail | railway=tram | railway=disused | railway=subway | 
railway=narrow_gauge | railway=light_rail | railway=preserved) & !(tunnel=yes) 
[0x14 resolution 22]
 
 (man_made=cable|(man_made=* & man_made ~ '.*pipe.*')) & area!=yes &
 tunnel!=yes & location != underground
diff --git a/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java 
b/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java
index 73345fc..fe0ed56 100644
--- a/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java
+++ b/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java
@@ -42,7 +42,6 @@ public class Utf8Decoder implements CharacterDecoder {
        public boolean addByte(int b) {
                if (b == 0) {
                        needreset = true;
-                       out.write(0);
                        return true;
                }
 
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java 
b/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
index 3791d31..a2096ca 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
@@ -88,15 +88,17 @@ public class Mdr20 extends Mdr2x {
                Collator collator = getConfig().getSort().getCollator();
 
                String lastName = null;
+               String lastPartialName = null;
                Mdr5Record lastCity = null;
                int record = 0;
-               int cityRecord = 0;
+               int cityRecord = 1;
                int lastMapNumber = 0;
 
                for (SortKey<Mdr7Record> key : keys) {
                        Mdr7Record street = key.getObject();
 
                        String name = street.getName();
+                       String partialName = street.getPartialName();
                        Mdr5Record city = street.getCity();
 
                        boolean citySameByName = city.isSameByName(collator, 
lastCity);
@@ -104,18 +106,24 @@ public class Mdr20 extends Mdr2x {
                        int mapNumber = city.getMapIndex();
 
                        // Only save a single copy of each street name.
-                       if (!citySameByName || mapNumber != lastMapNumber || 
lastName == null || collator.compare(name, lastName) != 0) {
+                       if (!citySameByName || mapNumber != lastMapNumber || 
lastName == null || lastPartialName == null
+                                       || !name.equals(lastName)
+                                       || !partialName.equals(lastPartialName))
+                       {
                                record++;
 
                                streets.add(street);
                                lastName = name;
+                               lastPartialName = partialName;
                        }
 
                        // The mdr20 value changes for each new city name
                        if (citySameByName) {
+                               assert cityRecord!=0;
                                city.setMdr20(cityRecord);
                        } else {
                                // New city name, this marks the start of a new 
section in mdr20
+                               assert cityRecord != 0;
                                cityRecord = record;
                                city.setMdr20(cityRecord);
                                lastCity = city;
@@ -137,6 +145,6 @@ public class Mdr20 extends Mdr2x {
         * Unknown.
         */
        public int getExtraValue() {
-               return isForDevice() ? 0xa : 0x8800;
+               return isForDevice() ? 0xe : 0x8800;
        }
 }
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java 
b/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java
index 379d3b4..afd8a35 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java
@@ -104,7 +104,7 @@ public class Mdr22 extends Mdr2x {
         */
        public int getExtraValue() {
                if (isForDevice())
-                       return 0x600a;
+                       return 0x600e;
                else
                        return 0x11000;
        }
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java 
b/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
index bade6d8..d0c1fdf 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
@@ -16,7 +16,6 @@ import java.util.ArrayList;
 import java.util.List;
 
 import uk.me.parabola.imgfmt.app.ImgFileWriter;
-import uk.me.parabola.imgfmt.app.Label;
 
 /**
  * Common code for 20, 21, 22 which are all lists of streets ordered in
@@ -39,30 +38,45 @@ public abstract class Mdr2x extends MdrMapSection 
implements HasHeaderFlags {
                int size = getSizes().getStreetSizeFlagged();
 
                boolean hasLabel = hasFlag(0x2);
+
+               String lastPartial = null;
                int recordNumber = 0;
                for (Mdr7Record street : streets) {
                        assert street.getMapIndex() == 
street.getCity().getMapIndex() : street.getMapIndex() + "/" + 
street.getCity().getMapIndex();
                        addIndexPointer(street.getMapIndex(), ++recordNumber);
 
                        int index = street.getIndex();
-                       String name = Label.stripGarminCodes(street.getName());
-                       
-                       int flag = 1;
+
+                       String name = street.getName();
+
+                       int repeat = 1;
                        if (name.equals(lastName) && sameGroup(street, prev))
-                               flag = 0;
-                       lastName = name;
-                       prev = street;
+                               repeat = 0;
 
                        if (hasLabel) {
                                putMapIndex(writer, street.getMapIndex());
                                int offset = street.getLabelOffset();
-                               if (flag != 0)
+                               if (repeat != 0)
+                                       offset |= 0x800000;
+
+                               int trailing = 0;
+                               String partialName = street.getPartialName();
+                               if (!partialName.equals(lastPartial)) {
+                                       trailing |= 1;
                                        offset |= 0x800000;
+                               }
+
                                writer.put3(offset);
-                               writer.put((byte) flag);
-                       }
-                       else
-                               putN(writer, size, (index << 1) | flag);
+                               writer.put(street.getOutNameOffset());
+
+                               writer.put((byte) trailing);
+
+                               lastPartial = partialName;
+                       } else
+                               putN(writer, size, (index << 1) | repeat);
+
+                       lastName = name;
+                       prev = street;
                }
        }
 
@@ -78,7 +92,8 @@ public abstract class Mdr2x extends MdrMapSection implements 
HasHeaderFlags {
        public int getItemSize() {
                int size;
                if (isForDevice()) {
-                       size = getSizes().getMapSize() + 3 + 1;
+                       // map-index, label, name-offset, 1byte flag
+                       size = getSizes().getMapSize() + 3 + 1 + 1;
                } else {
                        size = getSizes().getStreetSizeFlagged();
                }
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java 
b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
index 6e43a30..e4f1af6 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
@@ -16,8 +16,10 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import uk.me.parabola.imgfmt.MapFailedException;
 import uk.me.parabola.imgfmt.app.ImgFileWriter;
-import uk.me.parabola.imgfmt.app.Label;
+import uk.me.parabola.imgfmt.app.srt.MultiSortKey;
+import uk.me.parabola.imgfmt.app.srt.Sort;
 import uk.me.parabola.imgfmt.app.srt.SortKey;
 
 /**
@@ -27,69 +29,211 @@ import uk.me.parabola.imgfmt.app.srt.SortKey;
  * @author Steve Ratcliffe
  */
 public class Mdr7 extends MdrMapSection {
+       public static final int MDR7_HAS_STRING = 0x01;
+       public static final int MDR7_HAS_NAME_OFFSET = 0x20;
+       public static final int MDR7_PARTIAL_SHIFT = 6;
+       public static final int MDR7_U1 = 0x2;
+       public static final int MDR7_U2 = 0x4;
+
+       private static final int MAX_NAME_OFFSET = 127;
+
+       private final int codepage;
+       private final boolean isMulti;
+       private final boolean splitName;
+
        private List<Mdr7Record> allStreets = new ArrayList<>();
        private List<Mdr7Record> streets = new ArrayList<>();
 
+       private final int u2size = 1;
+
        public Mdr7(MdrConfig config) {
                setConfig(config);
+               Sort sort = config.getSort();
+               splitName = config.isSplitName();
+               codepage = sort.getCodepage();
+               isMulti = sort.isMulti();
        }
 
        public void addStreet(int mapId, String name, int lblOffset, int 
strOff, Mdr5Record mdrCity) {
+               // Find a name prefix, which is either a shield or a word 
ending 0x1e. We are treating
+               // a shield as a prefix of length one.
+               int prefix = 0;
+               if (name.charAt(0) < 7)
+                       prefix = 1;
+               int sep = name.indexOf(0x1e);
+               if (sep > 0)
+                       prefix = sep + 1;
+
+               // Find a name suffix which begins with 0x1f
+               sep = name.indexOf(0x1f);
+               int suffix = 0;
+               if (sep > 0)
+                       suffix = sep;
+
+               // Large values can't actually work.
+               if (prefix >= MAX_NAME_OFFSET || suffix >= MAX_NAME_OFFSET)
+                       return;
+
                Mdr7Record st = new Mdr7Record();
                st.setMapIndex(mapId);
                st.setLabelOffset(lblOffset);
                st.setStringOffset(strOff);
                st.setName(name);
                st.setCity(mdrCity);
+               st.setPrefixOffset((byte) prefix);
+               st.setSuffixOffset((byte) suffix);
                allStreets.add(st);
+
+               if (!splitName)
+                       return;
+
+               boolean start = false;
+               boolean inWord = false;
+
+               int c;
+               int outOffset = 0;
+
+               int end = Math.min((suffix > 0) ? suffix : name.length() - 
prefix - 1, MAX_NAME_OFFSET);
+               for (int nameOffset = 0; nameOffset < end; nameOffset += 
Character.charCount(c)) {
+                       c = name.codePointAt(prefix + nameOffset);
+
+                       // Don't use any word after a bracket
+                       if (c == '(')
+                               break;
+
+                       if (!Character.isLetterOrDigit(c)) {
+                               start = true;
+                               inWord = false;
+                       } else if (start && Character.isLetterOrDigit(c)) {
+                               inWord = true;
+                       }
+
+                       if (start && inWord && outOffset > 0) {
+                               st = new Mdr7Record();
+                               st.setMapIndex(mapId);
+                               st.setLabelOffset(lblOffset);
+                               st.setStringOffset(strOff);
+                               st.setName(name);
+                               st.setCity(mdrCity);
+                               st.setNameOffset((byte) nameOffset);
+                               st.setOutNameOffset((byte) outOffset);
+                               st.setPrefixOffset((byte) prefix);
+                               st.setSuffixOffset((byte) suffix);
+                               //System.out.println(st.getName() + ": add 
partial " + st.getPartialName());
+                               allStreets.add(st);
+                               start = false;
+                       }
+
+                       outOffset += outSize(c);
+                       if (outOffset > MAX_NAME_OFFSET)
+                               break;
+               }
+       }
+
+       /**
+        * Return the number of bytes that the given character will consume in 
the output encoded
+        * format.
+        */
+       private int outSize(int c) {
+               if (codepage == 65001) {
+                       // For unicode a simple lookup gives the number of 
bytes.
+                       if (c < 0x80) {
+                               return 1;
+                       } else if (c <= 0x7FF) {
+                               return 2;
+                       } else if (c <= 0xFFFF) {
+                               return 3;
+                       } else if (c <= 0x10FFFF) {
+                               return 4;
+                       } else {
+                               throw new 
MapFailedException(String.format("Invalid code point: 0x%x", c));
+                       }
+               } else if (!isMulti) {
+                       // The traditional single byte code-pages, always one 
byte.
+                       return 1;
+               } else {
+                       // Other multi-byte code-pages (eg ms932); can't 
currently create index for these anyway.
+                       return 0;
+               }
        }
 
        /**
         * Since we change the number of records by removing some after sorting,
         * we sort and de-duplicate here.
+        * This is a performance critical part of the index creation process
+        * as it requires a lot of heap to store the sort keys.                 
 
         */
        protected void preWriteImpl() {
-               List<SortKey<Mdr7Record>> sortedStreets = 
MdrUtils.sortList(getConfig().getSort(), allStreets);
+               Sort sort = getConfig().getSort();
+               List<SortKey<Mdr7Record>> sortedStreets = new 
ArrayList<>(allStreets.size());
+               for (Mdr7Record m : allStreets) {
+                       String partialName = m.getPartialName();
+                       String name = m.getName();
+                       SortKey<Mdr7Record> nameKey = sort.createSortKey(m, 
m.getName(), m.getMapIndex());
+                       SortKey<Mdr7Record> partialKey = 
name.equals(partialName) ? nameKey : sort.createSortKey(m, partialName);
+                       MultiSortKey<Mdr7Record> sortKey = new 
MultiSortKey<>(partialKey, nameKey, null);
+                       sortedStreets.add(sortKey);
+               }
+               Collections.sort(sortedStreets);
 
                // De-duplicate the street names so that there is only one entry
                // per map for the same name.
                int recordNumber = 0;
                Mdr7Record last = new Mdr7Record();
-               for (SortKey<Mdr7Record> sk : sortedStreets) {
+               for (int i = 0; i < sortedStreets.size(); i++){ 
+                       SortKey<Mdr7Record> sk = sortedStreets.get(i);
                        Mdr7Record r = sk.getObject();
-                       if (r.getMapIndex() != last.getMapIndex() || 
!r.getName().equals(last.getName())) {
+                       if (r.getMapIndex() == last.getMapIndex()
+                                       && r.getName().equals(last.getName())  
// currently think equals is correct, not collator.compare()
+                                       && 
r.getPartialName().equals(last.getPartialName()))
+                       {
+                               // This has the same name (and map number) as 
the previous one. Save the pointer to that one
+                               // which is going into the file.
+                               r.setIndex(recordNumber);
+                       } else {
                                recordNumber++;
                                last = r;
                                r.setIndex(recordNumber);
                                streets.add(r);
-                       } else {
-                               // This has the same name (and map number) as 
the previous one. Save the pointer to that one
-                               // which is going into the file.
-                               r.setIndex(recordNumber);
                        }
+                       // release memory 
+                       sortedStreets.set(i, null);
                }
        }
 
        public void writeSectData(ImgFileWriter writer) {
                String lastName = null;
-               boolean hasStrings = hasFlag(0x1);
+               String lastPartial = null;
+               boolean hasStrings = hasFlag(MDR7_HAS_STRING);
+               boolean hasNameOffset = hasFlag(MDR7_HAS_NAME_OFFSET);
+
                for (Mdr7Record s : streets) {
                        addIndexPointer(s.getMapIndex(), s.getIndex());
 
                        putMapIndex(writer, s.getMapIndex());
                        int lab = s.getLabelOffset();
-                       String name = Label.stripGarminCodes(s.getName());
-                       int trailingFlags = 0;
+                       String name = s.getName();
                        if (!name.equals(lastName)) {
                                lab |= 0x800000;
                                lastName = name;
-                               trailingFlags = 1;
                        }
+
+                       String partialName = s.getPartialName();
+                       int trailingFlags = 0;
+                       if (!partialName.equals(lastPartial)) {
+                               trailingFlags |= 1;
+                               lab |= 0x800000;  // If it is not a partial 
repeat, then it is not a complete repeat either
+                       }
+                       lastPartial = partialName;
+
                        writer.put3(lab);
                        if (hasStrings)
                                putStringOffset(writer, s.getStringOffset());
-                       
-                       writer.put((byte) trailingFlags);
+
+                       if (hasNameOffset)
+                               writer.put(s.getOutNameOffset());
+
+                       putN(writer, u2size, trailingFlags);
                }
        }
 
@@ -99,9 +243,11 @@ public class Mdr7 extends MdrMapSection {
         */
        public int getItemSize() {
                PointerSizes sizes = getSizes();
-               int size = sizes.getMapSize() + 3 + 1;
+               int size = sizes.getMapSize() + 3 + u2size;
                if (!isForDevice())
                        size += sizes.getStrOffSize();
+               if ((getExtraValue() & MDR7_HAS_NAME_OFFSET) != 0)
+                       size += 1;
                return size;
        }
 
@@ -113,11 +259,12 @@ public class Mdr7 extends MdrMapSection {
         * Value of 3 possibly the existence of the lbl field.
         */
        public int getExtraValue() {
-               int magic = 0x42;
+               int magic = MDR7_U1 | MDR7_HAS_NAME_OFFSET | (u2size << 
MDR7_PARTIAL_SHIFT);
+
                if (isForDevice()) {
-                       magic |= 0x4;
+                       magic |= MDR7_U2;
                } else {
-                       magic |= 0x1; //strings
+                       magic |= MDR7_HAS_STRING;
                }
 
                return magic;
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java 
b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java
index d26af18..6a3562e 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java
@@ -23,6 +23,12 @@ public class Mdr7Record extends RecordBase implements 
NamedRecord {
        private int index;
        private Mdr5Record city;
 
+       // For searching on partial names
+       private byte nameOffset; // offset into the name where matching should 
start
+       private byte outNameOffset; // offset into the encoded output name
+       private byte prefixOffset;  // offset after 0x1e prefix
+       private byte suffixOffset;  // offset just before 0x1f suffix
+
        public int getLabelOffset() {
                return labelOffset;
        }
@@ -63,6 +69,43 @@ public class Mdr7Record extends RecordBase implements 
NamedRecord {
                return city;
        }
 
+       public void setNameOffset(byte nameOffset) {
+               this.nameOffset = nameOffset;
+       }
+
+       public byte getOutNameOffset() {
+               return outNameOffset;
+       }
+
+       public void setOutNameOffset(byte outNameOffset) {
+               this.outNameOffset = outNameOffset;
+       }
+
+       public void setPrefixOffset(byte prefixOffset) {
+               this.prefixOffset = prefixOffset;
+       }
+
+       public void setSuffixOffset(byte suffixOffset) {
+               this.suffixOffset = suffixOffset;
+       }
+
+       /**
+        * Get the name starting at the given nameOffset.
+        *
+        * To avoid creating unnecessary objects, a check is made for an offset 
of zero
+        * and the original name string is returned.
+        *
+        * @return A substring of name, starting at the nameOffset value.
+        */
+       public String getPartialName() {
+               if (nameOffset == 0 && prefixOffset == 0 && suffixOffset == 0)
+                       return name;
+               else if ((suffixOffset & 0xff) > 0)
+                       return name.substring((nameOffset & 0xff) + 
(prefixOffset & 0xff), (suffixOffset & 0xff));
+               else
+                       return name.substring((nameOffset & 0xff) + 
(prefixOffset & 0xff));
+       }
+
        public String toString() {
                return name + " in " + city.getName();
        }
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java 
b/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java
index 893e83f..a3bcf6e 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java
@@ -32,6 +32,7 @@ public class MdrConfig {
        private int headerLen = DEFAULT_HEADER_LEN;
        private Sort sort;
        private File outputDir;
+       private boolean splitName;
 
        /**
         * True if we are creating the file, rather than reading it.
@@ -87,4 +88,12 @@ public class MdrConfig {
                if (outputDir != null)
                        this.outputDir = new File(outputDir);
        }
+
+       public void setSplitName(boolean splitName) {
+               this.splitName = splitName;
+       }
+
+       public boolean isSplitName() {
+               return splitName;
+       }
 }
diff --git a/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java 
b/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java
index f173a2c..8c9005a 100644
--- a/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java
+++ b/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java
@@ -83,6 +83,7 @@ public class GmapsuppBuilder implements Combiner {
        // There is a separate MDR and SRT file for each family id in the 
gmapsupp
        private final Map<Integer, MdrBuilder> mdrBuilderMap = new 
LinkedHashMap<Integer, MdrBuilder>();
        private final Map<Integer, Sort> sortMap = new LinkedHashMap<Integer, 
Sort>();
+       private boolean splitName;
 
 
        public void init(CommandArgs args) {
@@ -90,6 +91,7 @@ public class GmapsuppBuilder implements Combiner {
                mapsetName = args.get("mapset-name", "OSM map set");
                overallDescription = args.getDescription();
                outputDir = args.getOutputDir();
+               splitName = args.get("split-name-index", false);
        }
 
        /**
@@ -106,7 +108,7 @@ public class GmapsuppBuilder implements Combiner {
                        return mdrBuilder;
 
                mdrBuilder = new MdrBuilder();
-               mdrBuilder.initForDevice(sort, outputDir);
+               mdrBuilder.initForDevice(sort, outputDir, splitName);
                mdrBuilderMap.put(familyId, mdrBuilder);
                return mdrBuilder;
        }
diff --git a/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java 
b/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
index 63362bd..487cfc4 100644
--- a/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
+++ b/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
@@ -111,6 +111,7 @@ public class MdrBuilder implements Combiner {
                config.setForDevice(false);
                config.setOutputDir(outputDir);
                config.setSort(sort);
+               config.setSplitName(args.get("split-name-index", false));
 
                // Wrap the MDR channel with the MDRFile object
                mdrFile = new MDRFile(mdrChan, config);
@@ -128,13 +129,14 @@ public class MdrBuilder implements Combiner {
                }
        }
 
-       void initForDevice(Sort sort, String outputDir) {
+       void initForDevice(Sort sort, String outputDir, boolean splitName) {
                // Set the options that we are using for the mdr.
                MdrConfig config = new MdrConfig();
                config.setHeaderLen(568);
                config.setWritable(true);
                config.setForDevice(true);
                config.setSort(sort);
+               config.setSplitName(splitName);
 
                // Wrap the MDR channel with the MDRFile object
                try {
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java 
b/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
index 1d69c56..ff6b4f9 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
@@ -352,28 +352,34 @@ public class RuleFileReader {
                        // Transform ((first | second) & topSecond)
                        // into (first & topSecond) | (second & topSecond)
 
-                       Op first = op1.getFirst();
-                       OrOp orOp = new OrOp();
+                       return distrubute(op1, top.getSecond());
+               } else {
+                       // This shouldn't happen
+                       throw new SyntaxException("X3:" + op1.getType());
+               }
+               return top;
+       }
 
-                       Op topSecond = top.getSecond();
+       private static OrOp distrubute(Op op1, Op topSecond) {
+               Op first = op1.getFirst();
+               OrOp orOp = new OrOp();
 
-                       AndOp and1 = new AndOp();
-                       and1.setFirst(first);
-                       and1.setSecond(topSecond);
+               BinaryOp and1 = new AndOp();
+               and1.setFirst(first);
+               and1.setSecond(topSecond);
 
-                       AndOp and2 = new AndOp();
-                       Op second = rearrangeExpression(op1.getSecond());
+               BinaryOp and2 = new AndOp();
+               Op second = rearrangeExpression(op1.getSecond());
+               if (second.isType(OR)) {
+                       and2 = distrubute(second, topSecond);
+               } else {
                        and2.setFirst(second);
                        and2.setSecond(topSecond);
-
-                       orOp.setFirst(and1);
-                       orOp.setSecond(and2);
-                       return orOp;
-               } else {
-                       // This shouldn't happen
-                       throw new SyntaxException("X3:" + op1.getType());
                }
-               return top;
+               orOp.setFirst(and1);
+               orOp.setSecond(and2);
+
+               return orOp;
        }
 
        /**
diff --git a/src/uk/me/parabola/mkgmap/scan/SyntaxException.java 
b/src/uk/me/parabola/mkgmap/scan/SyntaxException.java
index 66c80da..e533913 100644
--- a/src/uk/me/parabola/mkgmap/scan/SyntaxException.java
+++ b/src/uk/me/parabola/mkgmap/scan/SyntaxException.java
@@ -47,7 +47,7 @@ public class SyntaxException extends RuntimeException {
                if (fileName != null)
                        fmt.format("(%s:%d): ", fileName, lineNumber);
 
-               fmt.format(super.getMessage());
+               fmt.format("%s", super.getMessage());
                return fmt.toString();
        }
 }
diff --git a/test/resources/rules/multi-or-twice.test 
b/test/resources/rules/multi-or-twice.test
new file mode 100644
index 0000000..30e97df
--- /dev/null
+++ b/test/resources/rules/multi-or-twice.test
@@ -0,0 +1,18 @@
+
+WAY
+highway=primary
+name=b
+a=2
+b=5
+
+<<<lines>>>
+
+(highway=secondary | a=2 | b=5) & (highway=service | a=0 | b=5) { set 
name='a${name}' }
+
+highway=* [0x2]
+
+<finalize>
+highway=* {name '${name}' }
+
+<<<results>>>
+WAY 1: Line 0x2, labels=[ab, null, null, null], res=24-24 (1/1),(2/2),
diff --git a/test/resources/rules/multi-or-with-and.test 
b/test/resources/rules/multi-or-with-and.test
new file mode 100644
index 0000000..e9d3267
--- /dev/null
+++ b/test/resources/rules/multi-or-with-and.test
@@ -0,0 +1,19 @@
+
+WAY
+highway=primary
+name=b
+c=60
+d=50
+
+<<<lines>>>
+
+(highway=primary | name=b | d=50) & highway=primary {
+       set name='a${name}'
+}
+
+highway=primary [0x2]
+
+<finalize>
+highway=* {name '${name}'}
+<<<results>>>
+WAY 1: Line 0x2, labels=[ab, null, null, null], res=24-24 (1/1),(2/2),
diff --git a/test/resources/rules/or-at-end.test 
b/test/resources/rules/or-at-end.test
new file mode 100644
index 0000000..3ff0d02
--- /dev/null
+++ b/test/resources/rules/or-at-end.test
@@ -0,0 +1,30 @@
+
+WAY
+highway=tertiary
+name=b
+oneway=1
+cycleway=opposite
+
+WAY 2
+highway=tertiary
+name=b
+oneway=1
+cycleway=opposite_lane
+
+
+<<<lines>>>
+highway ~ 
'(secondary|tertiary|unclassified|residential|minor|living_street|service)'
+       & oneway=*
+       & (cycleway=opposite | cycleway=opposite_lane | cycleway=opposite_track 
)
+       { set name='a${name}' }
+       [0x2 ]
+
+
+<finalize>
+highway=* {name '${name}' }
+
+<<<results>>>
+WAY 1: Line 0x2, labels=[ab, null, null, null], res=24-24 oneway (1/1),(2/2),
+WAY 2: Line 0x2, labels=[ab, null, null, null], res=24-24 oneway (1/1),(2/2),
+
+
diff --git a/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java 
b/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
index c9423b6..99ef40c 100644
--- a/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
+++ b/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
@@ -406,6 +406,7 @@ public class RuleFileReaderTest {
                type = getFirstType(rs, el);
                assertNotNull(type);
 
+               el = el.copy();  // Copy for LinkedOp which remembers the last 
matched element
                el.addTag("cycleway", "opposite_lane");
                type = getFirstType(rs, el);
                assertNotNull(type);

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-grass/mkgmap.git

_______________________________________________
Pkg-grass-devel mailing list
Pkg-grass-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

Reply via email to