FreeOrion

Forums for the FreeOrion project
It is currently Thu May 23, 2013 12:58 pm

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: StringTable, [[KEY]] Expansion
PostPosted: Wed Oct 08, 2008 8:10 am 
Offline
Space Floater

Joined: Sun Sep 28, 2008 3:05 pm
Posts: 31
Location: Horten, Norway
Added [[KEY]] Expansion in values on stringtable load. It works (c), but loop checks remains.

Code:
Index: StringTable.cpp
===================================================================
--- StringTable.cpp   (revision 2680)
+++ StringTable.cpp   (working copy)
@@ -60,6 +60,8 @@
           (("'''" >> MULTI_LINE_VALUE >> "'''" >> _n) | SINGLE_LINE_VALUE >> _n));
     const sregex REFERENCE =
         "[[" >> *space >> (s1 = IDENTIFIER) >> +space >> (s2 = IDENTIFIER) >> *space >> "]]";
+    const sregex KEYEXPANSION =
+        "[[" >> *space >> (s1 = IDENTIFIER) >> *space >> "]]";

     smatch matches;
     if (regex_search(file_contents, matches, FILE_)) {
@@ -108,6 +110,24 @@
                 }
             }
         }
+      for (std::map<std::string, std::string>::iterator map_it = m_strings.begin(); map_it != m_strings.end(); ++map_it)
+        {
+            sregex_iterator it(map_it->second.begin(), map_it->second.end(), KEYEXPANSION);
+            sregex_iterator end;
+            std::size_t offset = 0;
+         for (; it != end; ) {
+                const smatch& match = *it;
+                std::map<std::string, std::string>::iterator map_lookup_it = m_strings.find(match[1]);
+                if (map_lookup_it != m_strings.end()) {
+                    std::string substitution = map_lookup_it->second;
+                    map_it->second.replace(match.position() + offset, match.length(), substitution);
+                    offset = match.position() + substitution.length();
+                    it = sregex_iterator(map_it->second.begin() + offset,
+                                         map_it->second.end(),
+                                         KEYEXPANSION);
+                }
+            }
+        }
     } else {
         Logger().errorStream() << "StringTable file \"" << m_filename << "\" is malformed";
     }


Top
 Profile  
 
 Post subject: Re: StringTable, [[KEY]] Expansion
PostPosted: Wed Oct 08, 2008 8:23 am 
Offline
Programming, Design, and De Facto Lead
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 7891
Location: Vancouver, BC
What do you mean by "It works (c), but loop checks remains." ?

Does the order of strings matter? In particular, can a string refer to another string defined after it in the stringtable?

What happens if a string references another string which itself references another string? (Again, does order matter?)

Are circular references resolved somehow?

Does this definitely not interfere with tagged string references like [[tech TECH_NAME_STRINGTABLE_ENTRY]] that are replaced with in-UI links?


Top
 Profile  
 
 Post subject: Re: StringTable, [[KEY]] Expansion
PostPosted: Wed Oct 08, 2008 9:00 am 
Offline
Space Floater

Joined: Sun Sep 28, 2008 3:05 pm
Posts: 31
Location: Horten, Norway
Geoff the Medio wrote:
What do you mean by "It works (c), but loop checks remains." ?

Does the order of strings matter? In particular, can a string refer to another string defined after it in the stringtable?

What happens if a string references another string which itself references another string? (Again, does order matter?)

Are circular references resolved somehow?

Does this definitely not interfere with tagged string references like [[tech TECH_NAME_STRINGTABLE_ENTRY]] that are replaced with in-UI links?


Code is executed after all keys is loaded, and "tagged string references" resolved. Regex looks for [[singleword]] in values and replaces with expanded value of that key (single word found). sregex_iterator is reinitialized after replacement, which means resultstring is reevaluated until resolved. Order does not matter, references to keys that contains references also works well.

This problem remains to be solved:
TEST1
Bla bla bla [[TEST2]]
TEST2
Bla bla blah [[TEST1]]

I've considered pushing the KEY being resolved onto some stack, check for roundtrips, and make a graceful exit. But... quite honestly my Boost lib skills aren't that adequate yet :)


Top
 Profile  
 
 Post subject: Re: StringTable, [[KEY]] Expansion
PostPosted: Wed Oct 08, 2008 11:52 am 
Offline
Space Floater

Joined: Sun Sep 28, 2008 3:05 pm
Posts: 31
Location: Horten, Norway
Ok... I read up on std::set, cyclic reference problem fixed:

Code:
Index: StringTable.cpp
===================================================================
--- StringTable.cpp   (revision 2680)
+++ StringTable.cpp   (working copy)
@@ -60,6 +60,8 @@
           (("'''" >> MULTI_LINE_VALUE >> "'''" >> _n) | SINGLE_LINE_VALUE >> _n));
     const sregex REFERENCE =
         "[[" >> *space >> (s1 = IDENTIFIER) >> +space >> (s2 = IDENTIFIER) >> *space >> "]]";
+    const sregex KEYEXPANSION =
+        "[[" >> *space >> (s1 = IDENTIFIER) >> *space >> "]]";

     smatch matches;
     if (regex_search(file_contents, matches, FILE_)) {
@@ -108,6 +110,33 @@
                 }
             }
         }
+      for (std::map<std::string, std::string>::iterator map_it = m_strings.begin(); map_it != m_strings.end(); ++map_it)
+        {
+            sregex_iterator it(map_it->second.begin(), map_it->second.end(), KEYEXPANSION);
+            sregex_iterator end;
+            std::size_t offset = 0;
+         std::set<std::string> cyclic_reference_check;
+         bool cyclic_reference_error = false;
+         cyclic_reference_check.insert(map_it->first);
+         while(it != end && !cyclic_reference_error) {
+            const smatch& match = *it;
+            if (cyclic_reference_check.find(match[1]) == cyclic_reference_check.end()) {
+               cyclic_reference_check.insert(match[1]);
+               std::map<std::string, std::string>::iterator map_lookup_it = m_strings.find(match[1]);
+               if (map_lookup_it != m_strings.end()) {
+                  std::string substitution = map_lookup_it->second;
+                  map_it->second.replace(match.position() + offset, match.length(), substitution);
+                  offset = match.position() + substitution.length();
+                  it = sregex_iterator(map_it->second.begin() + offset,
+                                  map_it->second.end(),
+                                  KEYEXPANSION);
+               }
+            } else {
+               cyclic_reference_error = true;
+               Logger().errorStream() << "While parsing stringtable, expanding key " << match[1] << ": Cyclic referense found. File: '" << m_filename << "'.  Skipping expansion.";
+            }
+            }
+        }
     } else {
         Logger().errorStream() << "StringTable file \"" << m_filename << "\" is malformed";
     }


Top
 Profile  
 
 Post subject: Re: StringTable, [[KEY]] Expansion
PostPosted: Thu Oct 09, 2008 1:58 am 
Offline
Programming, Design, and De Facto Lead
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 7891
Location: Vancouver, BC
Sounds good; I'll check it out when I have some time.

Before then, could you send me a private messge with your name for the credits? Standard format is

Real Name (Alias) - Contribution Type(s)

as can be seen on the credits that scroll when the button on the main splash screen is clicked.


Top
 Profile  
 
 Post subject: Re: StringTable, [[KEY]] Expansion
PostPosted: Wed Dec 03, 2008 3:54 am 
Offline
Programming Lead Emeritus
User avatar

Joined: Thu Jun 26, 2003 1:33 pm
Posts: 1092
Nice work. I made one slight modification that allows recursive substitutions. Here's how I modified the English stringtable:

[code]#Button names####

INTRO_BTN_SINGLE_PLAYER
Single Player

INTRO_BTN_MULTI_PLAYER
Multi Player

INTRO_BTN_LOAD_GAME
Load Game

INTRO_BTN_OPTIONS
Options [[INTRO_BTN_SINGLE_PLAYER]]

INTRO_BTN_ABOUT
About [[INTRO_BTN_OPTIONS]]

INTRO_BTN_CREDITS
Credits [[INTRO_BTN_ABOUT]]

INTRO_BTN_EXIT
Exit
[code]

With your original patch, INTRO_BTN_ABOUT read "About Options [[INTRO_BTN_SINGLE_PLAYER]]". I changed the new location of the sregex_iterator from just-after the substitution to right at it. Now INTRO_BTN_ABOUT expands to "About Options Single Player".


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group