src/lib/INIReader.cpp
branchv_0
changeset 2 f031a4dc7c52
parent 1 3876a9c56a66
child 3 4313e91da50b
equal deleted inserted replaced
1:3876a9c56a66 2:f031a4dc7c52
    38 		for (INIContentHandler* handler : handlers) handler->startDocument();
    38 		for (INIContentHandler* handler : handlers) handler->startDocument();
    39 
    39 
    40 		std::regex whitespacePattrern("\\s*");
    40 		std::regex whitespacePattrern("\\s*");
    41 		std::regex commentPattrern("\\s*(;|#)\\s*(.*)");
    41 		std::regex commentPattrern("\\s*(;|#)\\s*(.*)");
    42 		std::regex sectionPattrern("\\s*\\[\\s*([^\\]]+)\\s*\\]\\s*");
    42 		std::regex sectionPattrern("\\s*\\[\\s*([^\\]]+)\\s*\\]\\s*");
    43 		std::regex entryQuotesPattrern("\\s*([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?\\s*=\\s*\"([^']+)\"\\s*((;|#)\\s*(.*))?");
    43 		std::regex entryQuotesPattrern(/***/"\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*\"([^']+)\"\\s*((;|#)\\s*(.*))?");
    44 		std::regex entryApostrophesPattrern("\\s*([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?\\s*=\\s*'([^']+)'\\s*((;|#)\\s*(.*))?");
    44 		std::regex entryApostrophesPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*'([^']+)'\\s*((;|#)\\s*(.*))?");
    45 		std::regex entryPlainPattrern("\\s*([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?\\s*=\\s*(.*)");
    45 		std::regex entryPlainPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*(.*)");
    46 
    46 
    47 		std::smatch match;
    47 		std::smatch match;
    48 		std::string section;
    48 		bool inSection = false;
    49 		std::string line;
    49 		std::string line;
       
    50 		int lineNumber = 0;
       
    51 		int eventNumber = 0;
       
    52 
    50 
    53 
    51 		while (std::getline(input, line)) {
    54 		while (std::getline(input, line)) {
       
    55 			lineNumber++;
    52 
    56 
    53 			if (std::regex_match(line, match, whitespacePattrern)) {
    57 			if (std::regex_match(line, match, whitespacePattrern)) {
    54 				// TODO: support also whitespace
    58 				// TODO: support also whitespace
    55 			} else if (std::regex_match(line, match, commentPattrern)) {
    59 			} else if (std::regex_match(line, match, commentPattrern)) {
    56 				// TODO: support also comments + emit also the comment style (;/#)
    60 				// TODO: support also comments + emit also the comment style (;/#)
    57 			} else if (std::regex_match(line, match, sectionPattrern)) {
    61 			} else if (std::regex_match(line, match, sectionPattrern)) {
    58 				if (section.size()) for (INIContentHandler* handler : handlers) handler->endSection();
    62 				if (inSection) for (INIContentHandler* handler : handlers) handler->endSection();
    59 				section = match[1];
    63 				INIContentHandler::SectionStartEvent event;
    60 				for (INIContentHandler* handler : handlers) handler->startSection(section);
    64 				event.lineNumber = lineNumber;
    61 			} else if (std::regex_match(line, match, entryQuotesPattrern) || std::regex_match(line, match, entryApostrophesPattrern)) {
    65 				event.eventNumber = ++eventNumber;
       
    66 				event.name = match[1];
    62 				// TODO: support also comments + emit also the comment style (;/#)
    67 				// TODO: support also comments + emit also the comment style (;/#)
       
    68 				for (INIContentHandler* handler : handlers) handler->startSection(event);
       
    69 			} else if (std::regex_match(line, match, entryQuotesPattrern) || std::regex_match(line, match, entryApostrophesPattrern) || std::regex_match(line, match, entryPlainPattrern)) {
       
    70 				INIContentHandler::EntryEvent event;
       
    71 				event.lineNumber = lineNumber;
       
    72 				event.eventNumber = ++eventNumber;
       
    73 				event.key = match[2];
       
    74 				event.subKey = match[4];
       
    75 				event.fullKey = match[1];
       
    76 				event.value = match[5];
       
    77 				if (match.size() == 9) event.comment = match[8];
    63 				// TODO: emit also the quote style ('/"/) and surrounding whitespace
    78 				// TODO: emit also the quote style ('/"/) and surrounding whitespace
    64 				for (INIContentHandler* handler : handlers) handler->entry(match[1], match[3], match[4]);
    79 				for (INIContentHandler* handler : handlers) handler->entry(event);
    65 			} else if (std::regex_match(line, match, entryPlainPattrern)) {
       
    66 				for (INIContentHandler* handler : handlers) handler->entry(match[1], match[3], match[4]);
       
    67 			} else {
    80 			} else {
    68 				// TODO: warning, error, or support unknown content
    81 				// TODO: warning, error, or support unknown content
    69 			}
    82 			}
    70 
    83 
    71 			// TODO: probably switch to state-machine approach instead of regular expressions
    84 			// TODO: probably switch to state-machine approach instead of regular expressions
    75 			// TODO: support also escaped characters
    88 			// TODO: support also escaped characters
    76 			// TODO: support also Java .properties and manifest.mf formats?
    89 			// TODO: support also Java .properties and manifest.mf formats?
    77 			// TODO: support also nested sections – hierarchy
    90 			// TODO: support also nested sections – hierarchy
    78 			// TODO: support also option for alternative key-value separator (: instead of =)
    91 			// TODO: support also option for alternative key-value separator (: instead of =)
    79 			// TODO: support also other encodings (currently only UTF-8 is supported)
    92 			// TODO: support also other encodings (currently only UTF-8 is supported)
    80 			// TODO: emit line numbers and/or event order?
       
    81 		}
    93 		}
    82 
    94 
    83 		if (section.size()) for (INIContentHandler* handler : handlers) handler->endSection();
    95 		if (inSection) for (INIContentHandler* handler : handlers) handler->endSection();
    84 
    96 
    85 		for (INIContentHandler* handler : handlers) handler->endDocument();
    97 		for (INIContentHandler* handler : handlers) handler->endDocument();
    86 	}
    98 	}
    87 };
    99 };
    88 
   100