Looks like a good tool. Just 1 stupid question... if M_SPACE is 50, why is M_SUBSET 54? to me it looks like it should be 52, 54 should be pointing to the E. SPACE\000Main Menu\000\ #define M_SPACE 50 --- #define M_SUBSET 54 ----- Original Message ----- From: "Rolf" To: Sent: Thursday, January 05, 2006 12:08 PM Subject: [PIC] C18 / Java tool for those who want it > Hi all. > > Been messing around with a lot of LCD Character display messages > recently. C18 seems to be pretty good at dealing with things, but the > combination of my poor C knowledge, and C18 produces HEX files that are > too large for my PIC. > > In order to rationalize, I put together a system where I declared just > one string constant (const rom char[]) that contains all the messages > seperated by a null character. Then all my LCD code references this > array at a given "defined" offset, and outputs the message till the next > null characer. This reduced the HEX file size by 40% (and gave me some > more room). > > Keeping track of the "pointers" manually in the code is a real pain > though, so I wrote this Java program to do the grunt work. For those who > want it, feel free. (It is Java 1.5). > > The code will "optimize" the string usage by "overlaying" strings where > it can. Thus, the input can declare the same string many times (with > different names), and it will only use one copy from rom memory. > Additionally, it will identify where ne string is the "tail" of another, > and it will offset the pointer to be only the tail part of another > string... i.e. it takes no more memory to store "ACE" if "SPACE" is also > declared. > > C18 then uses table reads to get the data out, so the data is packed > 2bytes per program word, and is most (space) efficient. > > The first part of the output is the concatenated strings. The second > part are defines that give "pointers" in to the concatenated string. The > third part is a double-check to make sure that the data comes out right > at the end (and so that in the code you can see (easily) what the > strings are.. > > There is a disclaimer..... I just finished the Java code and I don't > have C18 with me right now. Although I am confident that it all works, > there may be some formatting problems or something... but, you should be > able to just paste the output at the top of you code. A little playing > with the Java and I am sure it could produce a useful c and h file to > #include if easier. > > By way of example: The "input" file looks like: > ==========Start============= > M_NULL= > M_MAIN=Main Menu > M_A=AAAA > M_B=BBBB > M_C=CCCC > M_SPACE= SPACE > M_CRAZY=!@#$% > M_LONG=AbcdEfgHijkLmnopQrstUvwZyz > M_SUBSET=ACE > M_SUPERSET=CCAAAA > ==========End============= > > The Output from the program looks like: > ==========Start============= > const rom char strings[] = "\ > CCAAAA\000AbcdEfgHijkLmnopQrstUvwZyz\000CCCC\000!@#$%\000BBBB\000\ > SPACE\000Main Menu\000\ > "; > > #define M_NULL 67 > #define M_MAIN 58 > #define M_A 2 > #define M_B 45 > #define M_C 34 > #define M_SPACE 50 > #define M_CRAZY 39 > #define M_LONG 7 > #define M_SUBSET 54 > #define M_SUPERSET 0 > > // M_NULL-> > // M_MAIN->Main Menu > // M_A->AAAA > // M_B->BBBB > // M_C->CCCC > // M_SPACE-> SPACE > // M_CRAZY->!@#$% > // M_LONG->AbcdEfgHijkLmnopQrstUvwZyz > // M_SUBSET->ACE > // M_SUPERSET->CCAAAA > > > ==========End============ > > You will notice that it "optimizes" the strings so that if any string > appears at the end of another string it will "double up" that string > value (AAAA is a subset of CCAAAA). > > To use this code it becomes a "simple" case of: > > void LCDPrintString(int pos) > { > while (strings[pos]) > LCDWriteChar(strings[pos++]); > } > > ..... > LCDPrintString(M_MENU); > LCDPrintString(M_SUPERSET); > .... > > > Perhaps this will buy me some lee-way when asking dumb questions later... > > Rolf > > ---------------------------------------------------------------------------- ---- > > > import java.io.*; > import java.util.*; > > > public class StringFormat { > > public static class StringReference { > private final int i_offset; > private final String i_string; > > public StringReference(int offset, String string) { > super(); > // TODO Auto-generated constructor stub > i_offset = offset; > i_string = string; > } > > public int getOffset() { > return i_offset; > } > > > public String getString() { > return i_string; > } > > } > > /** > * @param args > */ > public static void main(String[] args) throws IOException { > InputStream is = System.in; > HashMap stringrefs = new HashMap(); > LinkedList keyorder = new LinkedList(); > > if (args.length > 0) { > is = new FileInputStream(args[0]); > } > BufferedReader br = new BufferedReader(new InputStreamReader(is)); > String line; > while ((line = br.readLine()) != null) { > String[] parts = line.split("=", 2); > if (parts.length == 2) { > String key = parts[0]; > String value = parts[1]; > keyorder.add(key); > if (stringrefs.containsKey(key)) { > throw new IllegalStateException("Already declared key '" + key + "' in file."); > } > StringReference toadd = null; > for (Map.Entry entry : stringrefs.entrySet()) { > String ref = entry.getValue().getString(); > if (ref.endsWith(value)) { > int offset = ref.length() - value.length(); > toadd = new StringReference(offset, ref); > break; > } else if (value.endsWith(ref)) { > toadd = new StringReference(0, value); > StringReference replacement = new StringReference(value.length() - ref.length(), value); > entry.setValue(replacement); > } > } > if (toadd == null) { > toadd = new StringReference(0, value); > } > stringrefs.put(key, toadd); > } > } > // right, all named pairs accounted for. > HashMap done = new HashMap(); > TreeMap references = new TreeMap(); > StringBuilder sb = new StringBuilder(); > StringBuilder test = new StringBuilder(); > sb.append("const rom char strings[] = \"\\\n"); > int last = 0; > int len = 0; > for (Map.Entry entry : stringrefs.entrySet()) { > int cursor = last; > if (!done.containsKey(entry.getValue().getString())) { > if (len > 60) { > len = 0; > sb.append("\\\n"); > } > sb.append(entry.getValue().getString()); > sb.append("\\000"); > test.append(entry.getValue().getString()); > test.append('\0'); > int elen = entry.getValue().getString().length() + 1; > len += elen + 3; > > done.put(entry.getValue().getString(), last); > last += elen; > } > cursor = done.get(entry.getValue().getString()); > cursor += entry.getValue().getOffset(); > references.put(entry.getKey(), cursor); > } > sb.append("\\\n\";\n"); > System.out.print(sb.toString()); > System.out.print('\n'); > for (String key : keyorder) { > System.out.print("#define " + key + " " + references.get(key) + "\n"); > } > > System.out.print('\n'); > char[] chars = test.toString().toCharArray(); > for (String key : keyorder) { > int pos = references.get(key); > System.out.print("// " + key + "->"); > while (chars[pos] != 0) { > System.out.print(chars[pos++]); > } > System.out.println(); > } > } > } > ---------------------------------------------------------------------------- ---- > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist