Thread: <regex> portability issue

  1. #1
    Registered User Chris87's Avatar
    Join Date
    Dec 2007
    Posts
    139

    <regex> portability issue

    I'm trying to parse a text file written in a certain format to be used in a game. I felt C++11/14's new regex library would be suitable.

    I did a minimal test program. I've not done the functionality in the switch-case clause yet, but rather focused on getting the totals of various elements (monsters/spells/items...) first to see if that works before moving on.

    The code below compiles and works as I intended using GCC 6.1.1 on Linux. However, compiling the same code unaltered with my MinGW cross compiler and running it on WINE, it prints nothing but a line break. I tried compiling the code again in MSVC 2015 with the same result.

    I have no platform specific code, so I'm stumped as to why it behaves differently on MinGW/MSVC compiled EXEs.

    The syntax of the text file goes like this (eg.):
    Code:
    LANGUAGE {English/ANSI}
    ITEMTOT {32}
    INAM1 {sword}
    INAM2 {shield}
    Code:
    #include <fstream>
    #include <iostream>
    #include <regex>
    #include <string>
    
    bool parseScript(const char * filename)
    {
    	std::ifstream scriptFile(filename);
    	std::regex labelSyntax("([A-Z]+)([0-9]*)[ \t]+\\{(.*)\\}[\r\n]");
    	std::string line;
    	
    	while (std::getline(scriptFile, line))
    	{
    		std::smatch m;
    		if (std::regex_match(line, m, labelSyntax))
    		{
    			if (m[1] == "LANGUAGE")
    				std::cout << "Locale set to " << m[3] << std::endl;
    			else if (m[1] == "ITEMTOT")
    				std::cout << "There are " << m[3] << " total items." << std::endl;
    			else if (m[1] == "SPLTOT")
    				std::cout << "There are " << m[3] << " total spells." << std::endl;
    			else if (m[1] == "MOBTOT")
    				std::cout << "There are " << m[3] << " total monsters." << std::endl;
    			else if (m[1] == "WEPTOT")
    				std::cout << "There are " << m[3] << " total weapons." << std::endl;
    			else if (m[1] == "BARTOT")
    				std::cout << "There are " << m[3] << " total barriers." << std::endl;
    			else if (m[1] == "TRPTOT")
    				std::cout << "There are " << m[3] << " total traps." << std::endl;
    			else if (m[1] == "TRETOT")
    				std::cout << "There are " << m[3] << " total treasures." << std::endl;
    			else if (m[1] == "TELTOT")
    				std::cout << "There are " << m[3] << " total teleports." << std::endl;
    			else
    			{
    				switch (m[1].str()[0])
    				{
    					case 'I': // item
    						break;
    					case 'S': // spell
    						break;
    					case 'M': // monster
    						break;
    					case 'W': // weapon
    						break;
    					case 'B': // barrier
    						break;
    					case 'X': // trap
    						break;
    					case 'T': // treasure
    						break;
    					case 'P': // teleport
    						break;
    					case 'L': // level
    						break;
    					default:
    						std::cerr << "Error: Unknown label" << std::endl;
    						return false;
    				}
    			}
    		}
    	}
    	scriptFile.close();
    	return true;
    }
    
    int main(int argc, char ** argv)
    {
    	if (argc != 2)
    	{
    		std::cerr << "Usage: " << argv[0] << " <input file>" << std::endl;
    		return 1;
    	}
    	parseScript(argv[1]);
    	return 0;
    }
    Last edited by Chris87; 06-13-2016 at 01:27 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    I had the same problem some time ago.
    GCC 4.9 was the first version with substantially working regex - https://gcc.gnu.org/gcc-4.9/changes.html

    MinGW might be an old version.
    Even if it isn't, it relies heavily on the Microsoft runtime (which is itself broken).

    You'd have to check the detailed documentation for MSVC to find out what is supported (or when/if it will be supported).
    It might be one of those "pony up some money to get a non-broken compiler".
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User Chris87's Avatar
    Join Date
    Dec 2007
    Posts
    139
    That stinks. Regex's been in the standard for 4-5 years now. Microsoft must be really lazy... I have MinGW's GCC at 6.1.1 as well.

    Boost.Regex yields the same result too, unfortunately. I have no idea what to do... Here's the changed code:

    Code:
    #ifdef _WIN32
    	#include <boost/regex.hpp>
    #else
    	#include <regex>
    #endif // _WIN32
    
    bool parseScript(const char * filename)
    {
    	std::ifstream scriptFile(filename);
    #ifdef _WIN32
    	boost::regex labelSyntax("([A-Z]+)([0-9]*)[ \t]+\\{(.*)\\}[\r\n]");
    #else
    	std::regex labelSyntax("([A-Z]+)([0-9]*)[ \t]+\\{(.*)\\}[\r\n]");
    #endif // _WIN32
    	std::string line;
    	
    	while (std::getline(scriptFile, line))
    	{
    #ifdef _WIN32
    		boost::smatch m;
    		if (boost::regex_match(line, m, labelSyntax))
    #else
    		std::smatch m;
    		if (std::regex_match(line, m, labelSyntax))
    #endif // _WIN32
    Last edited by Chris87; 06-13-2016 at 04:16 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. regex in c (posix regex)
    By baxy in forum C Programming
    Replies: 1
    Last Post: 11-16-2012, 01:15 PM
  2. portability
    By BarryII in forum C Programming
    Replies: 12
    Last Post: 10-02-2008, 08:48 AM
  3. <regex.h> regex syntax in C
    By battersausage in forum C Programming
    Replies: 7
    Last Post: 03-24-2004, 01:35 PM
  4. Program Portability (code portability)
    By Perica in forum C++ Programming
    Replies: 2
    Last Post: 11-10-2002, 10:03 AM
  5. what does portability mean?
    By elad in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 10-03-2002, 02:46 AM

Tags for this Thread