From d882ef3c1786ae4ef39f6aefdc99c85b827fa4fa Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 8 Dec 2025 19:57:51 +0000 Subject: [PATCH 1/8] Codechange: Remove boost/foreach usage in favour of ranged for-loops --- .github/workflows/ci-build.yml | 2 -- .github/workflows/release.yml | 1 - src/info.cpp | 5 +++-- src/mapescapes.cpp | 30 +++++++++++++++--------------- src/mapescapes.h | 3 --- src/nforenum.cpp | 8 +++----- src/pseudo.cpp | 15 +++++++++------ 7 files changed, 30 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index af14967..561a57c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -86,7 +86,6 @@ jobs: ${{ steps.vcpkg.outputs.vcpkg }} install --triplet=${{ matrix.arch }}-osx \ boost-bimap \ boost-date-time \ - boost-foreach \ # EOF - name: Install GCC problem matcher @@ -135,7 +134,6 @@ jobs: "${{ steps.vcpkg.outputs.vcpkg }}" install --triplet=${{ matrix.arch }}-windows-static \ boost-bimap \ boost-date-time \ - boost-foreach \ libpng \ # EOF diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index df68816..90cd665 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,7 +86,6 @@ jobs: "${{ steps.vcpkg.outputs.vcpkg }}" install --triplet=${{ matrix.arch }}-windows-static \ boost-bimap \ boost-date-time \ - boost-foreach \ libpng \ # EOF diff --git a/src/info.cpp b/src/info.cpp index 107ed3a..56c0c57 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -152,13 +152,14 @@ infowriter::infowriter(FILE *info, int useplaintext, const char *directory) fprintf(info,"// (Info version %d)", _useexts ? 32 : 6); if(_useexts) { // (re)insert default escapes - foreach(const esc& e, escapes) + for (const esc &e : escapes) { nfo_escapes.insert(nfe_pair(e.str+1, e.byte)); + } fputs("\n// Escapes:", info); int oldbyte = -1; for (int act = 0; act < 255; act++) { - foreach (const nfe_rpair& p, nfo_escapes.right) { + for (const nfe_rpair &p : nfo_escapes.right) { if (p.second[0] != act) continue; if (p.first == oldbyte) { diff --git a/src/mapescapes.cpp b/src/mapescapes.cpp index 8844344..a6e1458 100644 --- a/src/mapescapes.cpp +++ b/src/mapescapes.cpp @@ -29,33 +29,33 @@ std::string FindEscape(char action, int byte) { // Look for a custom escape - foreach(const nfe_rpair& p, nfo_escapes.right.equal_range(byte)) - if (p.second[0] == action) - return " \\" + p.second; + for (const nfe_rpair &p : nfo_escapes.right.equal_range(byte)) { + if (p.second[0] == action) return " \\" + p.second; + } // Look for a built-in escape - foreach(const esc& e, escapes) - if (e.action==ctoi(action) && e.byte==byte) - return ' ' + std::string(e.str); + for (const esc &e : escapes) { + if (e.action==ctoi(action) && e.byte==byte) return ' ' + std::string(e.str); + } return ""; } std::string FindEscape(char action, int byte, uint offset) { // This time, look for a built-in escape first - foreach(const esc& e, escapes) - if (e.action==ctoi(action) && e.byte==byte && e.pos==offset) - return ' ' + std::string(e.str); + for (const esc &e : escapes) { + if (e.action==ctoi(action) && e.byte==byte && e.pos==offset) return ' ' + std::string(e.str); + } // Look for a custom escape - foreach(const nfe_rpair& p, nfo_escapes.right.equal_range(byte)) - if (p.second[0] == action) - return " \\" + p.second; + for (const nfe_rpair &p : nfo_escapes.right.equal_range(byte)) { + if (p.second[0] == action) return " \\" + p.second; + } return ""; } int FindEscape(std::string str) { - foreach(esc e, escapes) - if(str == e.str+1) - return e.byte; + for (const esc &e : escapes) { + if(str == e.str+1) return e.byte; + } nfe_left_iter ret = nfo_escapes.left.find(str); if(ret == nfo_escapes.left.end()) return -1; diff --git a/src/mapescapes.h b/src/mapescapes.h index f5a36cd..623f281 100644 --- a/src/mapescapes.h +++ b/src/mapescapes.h @@ -24,12 +24,9 @@ * Get boost from http://www.boost.org */ #include #include -#include using namespace boost::bimaps; -#define foreach BOOST_FOREACH - typedef unsigned char U8; #include "escapes.h" diff --git a/src/nforenum.cpp b/src/nforenum.cpp index 0e13bd2..d4af0c6 100644 --- a/src/nforenum.cpp +++ b/src/nforenum.cpp @@ -360,8 +360,7 @@ int process_file(std::istream&in){ // Now remove all defaults. This serves two purposes: // 1) Prevent incorrectly specified defaults from causing problems later. // 2) Allow the beautifier to select custom escapes over built-ins. - foreach(const esc& e, escapes) - nfo_escapes.left.erase(e.str+1); + for (const esc& e : escapes) nfo_escapes.left.erase(e.str+1); } }else{ IssueMessage(0,UNKNOWN_VERSION,1); @@ -477,13 +476,12 @@ int process_file(std::istream&in){ (*real_out)< 6) { // (re)insert default escapes - foreach(const esc& e, escapes) - nfo_escapes.insert(nfe_pair(e.str+1, e.byte)); + for (const esc &e : escapes) nfo_escapes.insert(nfe_pair(e.str+1, e.byte)); (*real_out)<<"// Escapes:"; int oldbyte = -1; for (int act = 0; act < 255; act++) { - foreach (const nfe_rpair& p, nfo_escapes.right) { + for (const nfe_rpair &p : nfo_escapes.right) { if (p.second[0] != act) continue; if (p.first == oldbyte) { diff --git a/src/pseudo.cpp b/src/pseudo.cpp index d81fa50..ee5a387 100644 --- a/src/pseudo.cpp +++ b/src/pseudo.cpp @@ -29,13 +29,11 @@ * properly installed. * Get boost from http://www.boost.org */ #include -#include #include #include #include using namespace boost::gregorian; -#define foreach BOOST_FOREACH #include"nforenum.h" #include"pseudo.h" @@ -711,8 +709,9 @@ std::ostream&PseudoSprite::output(std::ostream&out){ if(buffer.find('\t')!=NPOS){ // Split into columns std::vector > sections; - foreach(const std::string &line, (Tokenize(buffer, '\n'))) + for (const std::string &line : Tokenize(buffer, '\n')) { sections.push_back(Tokenize(line, '\t')); + } // Count the columns uint columns = (uint)std::ranges::max_element(sections, {}, &std::vector::size)->size(); @@ -721,16 +720,20 @@ std::ostream&PseudoSprite::output(std::ostream&out){ for(uint i=0;i §ion, sections) + for (const std::vector §ion : sections) { if(section.size()>i+1) padWidth = std::max(padWidth, section[i].length()+1); + } // and make it that wide. - foreach(std::vector §ion, sections) + for (std::vector §ion : sections) { if(section.size()>i+1) section[i] += std::string(padWidth - section[i].length(), ' '); + } + } // Tabs are expanded, write each line - foreach(const std::vector&line, sections) + for (const std::vector&line : sections) { for_each(line.begin(),line.end(),out< Date: Mon, 8 Dec 2025 19:58:16 +0000 Subject: [PATCH 2/8] Codechange: Remove boost/current_function usage in favour of std::source_location --- src/nforenum.h | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/nforenum.h b/src/nforenum.h index eeb0efc..978d12a 100644 --- a/src/nforenum.h +++ b/src/nforenum.h @@ -23,11 +23,6 @@ #ifndef _RENUM_RENUM_H_INCLUDED_ #define _RENUM_RENUM_H_INCLUDED_ -/* If your compiler errors on the following line, boost is not - * properly installed. - * Get boost from http://www.boost.org */ -#include - /* file handling defs: * dirname contains the name of the sprites directory * foo_ext contains the extention to use for foo @@ -46,32 +41,30 @@ typedef unsigned short ushort; typedef unsigned char uchar; #if defined DEBUG || defined _DEBUG -inline int _FORCE_INT_(int x){return x;} #define verify assert #else #define verify(x) (void(x)) -#define _FORCE_INT_(x) ((int)x) #endif +#include + enum{EOK,EWARN=3,EERROR,EPARSE,EFILE,EDATA,EFATAL}; void SetCode(int); -#define INTERNAL_ERROR(var,val)\ - if(true){\ - IssueMessage(0,INTERNAL_ERROR_TEXT,__FILE__,__LINE__,_spritenum,#var,_FORCE_INT_(val),BOOST_CURRENT_FUNCTION);\ - assert(false);\ - exit(EFATAL);\ - }else\ - ((void)0) +#define INTERNAL_ERROR(var, val) \ + do { \ + const std::source_location location = std::source_location::current(); \ + IssueMessage(0, INTERNAL_ERROR_TEXT, location.file_name(), location.line(), _spritenum, #var, val, location.function_name()); \ + assert(false); \ + exit(EFATAL); \ + } while (false) #define DEFAULT(var)\ default:\ - INTERNAL_ERROR(var,var); + INTERNAL_ERROR(#var,var); #define VERIFY(cond,var)\ - if(!(cond))INTERNAL_ERROR(var,var);\ - else\ - ((void)0) + if(!(cond)) { INTERNAL_ERROR(#var,var); } #define EXPECTED_BYTES(off) (off>>24) #define EXPECTED_LOC(off) (off&0xFFFFFF) From 88e91c9d9e1f90fb7c8afe0e319b377a94bef941 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 8 Dec 2025 20:54:19 +0000 Subject: [PATCH 3/8] Codechange: Remove usage of boost::bimaps --- .github/workflows/ci-build.yml | 2 -- .github/workflows/release.yml | 1 - src/info.cpp | 23 ++++++++-------- src/mapescapes.cpp | 49 +++++++++++++++++++++++++++------- src/mapescapes.h | 25 +++++++---------- src/nforenum.cpp | 29 +++++++++++--------- src/pseudo.cpp | 5 +--- src/readinfo.cpp | 9 +------ 8 files changed, 80 insertions(+), 63 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 561a57c..0dbff7c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -84,7 +84,6 @@ jobs: - name: Prepare vcpkg run: | ${{ steps.vcpkg.outputs.vcpkg }} install --triplet=${{ matrix.arch }}-osx \ - boost-bimap \ boost-date-time \ # EOF @@ -132,7 +131,6 @@ jobs: shell: bash run: | "${{ steps.vcpkg.outputs.vcpkg }}" install --triplet=${{ matrix.arch }}-windows-static \ - boost-bimap \ boost-date-time \ libpng \ # EOF diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 90cd665..99fef0a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -84,7 +84,6 @@ jobs: shell: bash run: | "${{ steps.vcpkg.outputs.vcpkg }}" install --triplet=${{ matrix.arch }}-windows-static \ - boost-bimap \ boost-date-time \ libpng \ # EOF diff --git a/src/info.cpp b/src/info.cpp index 56c0c57..d15cefc 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -26,8 +26,6 @@ int makeint(U8 low, S8 high) void read_file(std::istream&in,int infover,int grfcontversion,std::vector>&sprites); -nfe_map nfo_escapes; - inforeader::inforeader(char *fn, int grfcontversion) { std::ifstream f; @@ -66,7 +64,9 @@ inforeader::inforeader(char *fn, int grfcontversion) if(str == "=") byte--; else if (str[0] == '@') byte = strtol(str.c_str()+1, NULL, 16); - else nfo_escapes.insert(nfe_pair(str, byte++)); + else { + InsertEscape(str, byte++); + } } } getline(f, buffer); // Try again to skip "format: " line @@ -153,25 +153,26 @@ infowriter::infowriter(FILE *info, int useplaintext, const char *directory) if(_useexts) { // (re)insert default escapes for (const esc &e : escapes) { - nfo_escapes.insert(nfe_pair(e.str+1, e.byte)); + InsertEscape(e.str + 1, e.byte); } fputs("\n// Escapes:", info); int oldbyte = -1; for (int act = 0; act < 255; act++) { - for (const nfe_rpair &p : nfo_escapes.right) { - if (p.second[0] != act) continue; + for (const auto &p : nfo_escapes) { + if (p.first[0] != act) continue; - if (p.first == oldbyte) { + if (p.second == oldbyte) { fprintf(info, " ="); --oldbyte; - } else if (p.first < oldbyte) { + } else if (p.second < oldbyte) { fputs("\n// Escapes:", info); oldbyte = -1; } - while (++oldbyte != p.first) - fprintf(info," %s", nfo_escapes.right.begin()->second.c_str()); - fprintf(info, " %s", p.second.c_str()); + while (++oldbyte != p.second) { + fprintf(info," %s", nfo_escapes[0].first.c_str()); + } + fprintf(info, " %s", p.first.c_str()); } } } diff --git a/src/mapescapes.cpp b/src/mapescapes.cpp index a6e1458..34c1b70 100644 --- a/src/mapescapes.cpp +++ b/src/mapescapes.cpp @@ -1,6 +1,6 @@ /* * mapescapes.cpp - * Helper functions for using boost::bimapped escapes + * Helper functions for using escapes * * Copyright 2009 by Dale McCoy. * @@ -19,6 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include @@ -27,10 +28,30 @@ #include "messages.h" #include "mapescapes.h" +nfe_map nfo_escapes; + +void InsertEscape(const std::string &key, int byte) { + auto new_pair = std::make_pair(key, byte); + auto it = std::find(nfo_escapes.begin(), nfo_escapes.end(), new_pair); + if (it == nfo_escapes.end()) { + nfo_escapes.push_back(new_pair); + } +} + +void RemoveEscape(const std::string &key) { + auto it = std::remove_if(nfo_escapes.begin(), nfo_escapes.end(), [key](const auto &p) { + return p.first == key; + }); + nfo_escapes.erase(it, nfo_escapes.end()); +} + std::string FindEscape(char action, int byte) { // Look for a custom escape - for (const nfe_rpair &p : nfo_escapes.right.equal_range(byte)) { - if (p.second[0] == action) return " \\" + p.second; + auto it = std::find_if(nfo_escapes.begin(), nfo_escapes.end(), [action, byte](const auto &p) { + return p.first[0] == action && p.second == byte; + }); + if (it != nfo_escapes.end()) { + return " \\" + it->first; } // Look for a built-in escape @@ -46,18 +67,26 @@ std::string FindEscape(char action, int byte, uint offset) { if (e.action==ctoi(action) && e.byte==byte && e.pos==offset) return ' ' + std::string(e.str); } // Look for a custom escape - for (const nfe_rpair &p : nfo_escapes.right.equal_range(byte)) { - if (p.second[0] == action) return " \\" + p.second; + auto it = std::find_if(nfo_escapes.begin(), nfo_escapes.end(), [action, byte](const auto &p) { + return p.first[0] == action && p.second == byte; + }); + if (it != nfo_escapes.end()) { + return " \\" + it->first; } return ""; } -int FindEscape(std::string str) { +int FindEscape(const std::string &str) { for (const esc &e : escapes) { if(str == e.str+1) return e.byte; } - nfe_left_iter ret = nfo_escapes.left.find(str); - if(ret == nfo_escapes.left.end()) - return -1; - return ret->second; + + const auto &it = std::find_if(nfo_escapes.begin(), nfo_escapes.end(), [str](const auto &p) { + return p.first == str; + }); + if (it != nfo_escapes.end()) { + return it->second; + } + + return -1; } diff --git a/src/mapescapes.h b/src/mapescapes.h index 623f281..d8e6e9c 100644 --- a/src/mapescapes.h +++ b/src/mapescapes.h @@ -1,6 +1,6 @@ /* * mapescapes.h - * Helper definitions for using boost::bimap + * Helper definitions for using NFO escapes * * Copyright 2009 by Dale McCoy. * @@ -19,22 +19,17 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* If your compiler errors on the following lines, boost is not - * properly installed, or your version of boost is too old. - * Get boost from http://www.boost.org */ -#include -#include +#include -using namespace boost::bimaps; - -typedef unsigned char U8; +#include "typesize.h" #include "escapes.h" -typedef bimap > nfe_map; -typedef nfe_map::value_type nfe_pair; -typedef nfe_map::left_value_type nfe_lpair; -typedef nfe_map::right_value_type nfe_rpair; -typedef nfe_map::left_iterator nfe_left_iter; -typedef nfe_map::right_iterator nfe_right_iter; +using nfe_map = std::vector>; + +void InsertEscape(const std::string &key, int val); +void RemoveEscape(const std::string &key); +std::string FindEscape(char action, int byte); +std::string FindEscape(char action, int byte, uint offset); +int FindEscape(const std::string &str); extern nfe_map nfo_escapes; diff --git a/src/nforenum.cpp b/src/nforenum.cpp index d4af0c6..0776e8d 100644 --- a/src/nforenum.cpp +++ b/src/nforenum.cpp @@ -65,8 +65,6 @@ #include "mapescapes.h" #include "data.h" -nfe_map nfo_escapes; - #ifndef _MSC_VER //Cygwin's GCC #defines __cdecl, but other GCCs do not //#undef it to prevent GCC from warning on the #define, @@ -348,7 +346,9 @@ int process_file(std::istream&in){ if (str == "=") byte--; else if (str[0] == '@') byte = strtol(str.c_str()+1,NULL,16); - else nfo_escapes.insert(nfe_pair(str, byte++)); + else { + InsertEscape(str, byte++); + } } else if (strncmp(sprite.c_str(), "// ",3)) { // EEEP! No "Format:" line in this file! IssueMessage(0, APPARENTLY_NOT_NFO); SetCode(EPARSE); @@ -360,7 +360,9 @@ int process_file(std::istream&in){ // Now remove all defaults. This serves two purposes: // 1) Prevent incorrectly specified defaults from causing problems later. // 2) Allow the beautifier to select custom escapes over built-ins. - for (const esc& e : escapes) nfo_escapes.left.erase(e.str+1); + for (const esc& e : escapes) { + RemoveEscape(e.str + 1); + } } }else{ IssueMessage(0,UNKNOWN_VERSION,1); @@ -476,24 +478,27 @@ int process_file(std::istream&in){ (*real_out)< 6) { // (re)insert default escapes - for (const esc &e : escapes) nfo_escapes.insert(nfe_pair(e.str+1, e.byte)); + for (const esc &e : escapes) { + InsertEscape(e.str + 1, e.byte); + } (*real_out)<<"// Escapes:"; int oldbyte = -1; for (int act = 0; act < 255; act++) { - for (const nfe_rpair &p : nfo_escapes.right) { - if (p.second[0] != act) continue; + for (const auto &p : nfo_escapes) { + if (p.first[0] != act) continue; - if (p.first == oldbyte) { + if (p.second == oldbyte) { (*real_out)<<" ="; --oldbyte; - } else if (p.first < oldbyte) { + } else if (p.second < oldbyte) { (*real_out)<<"\n// Escapes:"; oldbyte = -1; } - while (++oldbyte != p.first) - (*real_out)<<" "<second; - (*real_out)<<" "< #include - -// grfcodec requires boost::date_time for its processing of the \wYMD and -// \wDMY formats. Get boost from www.boost.org -#include -using namespace boost::gregorian; - +#include"mapescapes.h" #include"nfosprite.h" #include"inlines.h" @@ -285,8 +280,6 @@ std::string GetUtf8Encode(uint ch){ #undef CHAR -int FindEscape(std::string); - Pseudo::Pseudo(size_t num,int infover,int grfcontversion,const std::string&sprite,int claimed_size){ std::istringstream in(sprite); std::ostringstream out; From 88145bc6317392bec14a1b57723dca416003e60a Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 8 Dec 2025 21:34:03 +0000 Subject: [PATCH 4/8] Codechange: Replace boost::gregorian usage with std::chrono --- src/pseudo.cpp | 40 ++++++++++++++++------------------------ src/readinfo.cpp | 21 +++++++-------------- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/pseudo.cpp b/src/pseudo.cpp index 639e2b7..3576c67 100644 --- a/src/pseudo.cpp +++ b/src/pseudo.cpp @@ -22,19 +22,17 @@ #include #include #include +#include #include #include /* If your compiler errors on the following lines, boost is not * properly installed. * Get boost from http://www.boost.org */ -#include #include #include #include -using namespace boost::gregorian; - #include"nforenum.h" #include"mapescapes.h" #include"pseudo.h" @@ -52,6 +50,10 @@ bool TrySetVersion(int); //QEXT: \Uxxxx, usually. enum{HEX,TEXT,UTF8,ENDQUOTE,QESC,QEXT,NQEXT,NOBREAK=0x80}; +using namespace std::chrono; + +constexpr year_month_day SINCE_1920{year(1920), month(1), day(1)}; + #define cur_pos() ((uint)out.str().length()-1) #define next_pos() ((uint)out.str().length()) @@ -309,9 +311,9 @@ PseudoSprite&PseudoSprite::SetDate(uint i, uint num) { case 1: return SetEscape(i, false, mysprintf(" \\b%d", 1920+ExtractByte(i)), 1); case 2:{ - date::ymd_type ymd = (date(1920,1,1) + days(ExtractWord(i))).year_month_day(); - ushort y = ymd.year, m = ymd.month, d = ymd.day; - return SetEscape(i, false, mysprintf(" \\w%d/%d/%d", y, m, d), 2); + auto ymd = year_month_day(static_cast(SINCE_1920) + static_cast(ExtractWord(i))); + std::string formatted_date = mysprintf(" \\w%d/%u/%u", static_cast(ymd.year()), static_cast(ymd.month()), static_cast(ymd.day())); + return SetEscape(i, false, formatted_date, 2); } case 4: { const int min = 511340, // == PseudoSprite("\\d1400-1-1", 0).ExtractDword(0) max = 3652424, // == PseudoSprite("\\d9999-12-31", 0).ExtractDword(0) @@ -326,9 +328,9 @@ PseudoSprite&PseudoSprite::SetDate(uint i, uint num) { val -= 365*400 + 97; yearmod += 400; } - date::ymd_type ymd = (date(1920,1,1) + days(val-base)).year_month_day(); - uint y = ymd.year+yearmod, m = ymd.month, d = ymd.day; - return SetEscape(i, false, mysprintf(" \\d%d/%d/%d", y, m, d), 4); + auto ymd = year_month_day(static_cast(SINCE_1920) + static_cast(val - base)); + std::string formatted_date = mysprintf(" \\d%d/%u/%u", static_cast(ymd.year()) + yearmod, static_cast(ymd.month()), static_cast(ymd.day())); + return SetEscape(i, false, formatted_date, 4); }} return SetDec(i, num); } @@ -832,24 +834,14 @@ uint PseudoSprite::ReadValue(std::istream& in, width w) { else if (y>31 && y<100) y+=1900; } else if (w == _D_) { // dword date - extra = 701265; + extra = 1920 * 365; if (d >= 32) std::swap(y, d); // Try DMY instead - // Boost doesn't support years out of the range 1400..9999 - while (y>9999) { - y -= 400; - extra += 365*400 + 97; // 97 leap years every 400 years. - } - while (y<1400) { - y += 400; - extra -= 365*400 + 97; - } } else goto fail; // I can't read a date of that width. - try { - return (date((ushort)y, (ushort)m, (ushort)d) - date(1920, 1, 1)).days() + extra; - } catch (std::out_of_range&) { - // Fall through to fail - } + auto ymd = year_month_day(static_cast(y), static_cast(m), static_cast(d)); + if (!ymd.ok()) goto fail; + int day_count = (static_cast(ymd) - static_cast(SINCE_1920)).count(); + return static_cast(day_count + extra); } fail: // Nothing worked diff --git a/src/readinfo.cpp b/src/readinfo.cpp index 52173da..49cc35e 100644 --- a/src/readinfo.cpp +++ b/src/readinfo.cpp @@ -33,6 +33,7 @@ Version 6: Add binary includes Version 7: Add backslash escapes */ +#include #include #include #include @@ -46,6 +47,9 @@ Version 7: Add backslash escapes #include"nfosprite.h" #include"inlines.h" +using namespace std::chrono; +constexpr year_month_day SINCE_1920{year(1920), month(1), day(1)}; + extern int _quiet; const char *zoom_levels[ZOOM_LEVELS] = { "normal", "zi4", "zi2", "zo2", "zo4", "zo8" }; const char *depths[DEPTHS] = { "8bpp", "32bpp", "mask" }; @@ -449,22 +453,11 @@ uint Pseudo::ReadValue(std::istream& in, width w) // dword date extra = 701265; if (d >= 32) std::swap(y, d); // Try DMY instead - // Boost doesn't support years out of the range 1400..9999 - while (y>9999) { - y -= 400; - extra += 365*400 + 97; // 97 leap years every 400 years. - } - while (y<1400) { - y += 400; - extra -= 365*400 + 97; - } } else goto fail; // I can't read a date of that width. - try { - return (date((ushort)y, (ushort)m, (ushort)d) - date(1920, 1, 1)).days() + extra; - } catch (std::out_of_range&) { - // Fall through to fail - } + return uint(static_cast(year_month_day(static_cast(y), static_cast(m), static_cast(d))) + - static_cast(SINCE_1920) + + static_cast(extra)); } fail: From 3986d8cb3ff342b302002ba87cb3430fc3fc08ce Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 8 Dec 2025 22:40:59 +0000 Subject: [PATCH 5/8] Codechange: Replace preprocessor-generator sequential access classes with inheritance --- src/CMakeLists.txt | 1 - src/pseudo.cpp | 52 ++++++++++++++++++++++ src/pseudo.h | 73 ++++++++++++++++++++----------- src/pseudo_seq.cpp | 107 --------------------------------------------- 4 files changed, 100 insertions(+), 133 deletions(-) delete mode 100644 src/pseudo_seq.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fc60884..f0bec50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,7 +56,6 @@ target_sources(nforenum PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/messages.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nforenum.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pseudo.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/pseudo_seq.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rangedint.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sanity.cpp ${CMAKE_CURRENT_SOURCE_DIR}/strings.cpp diff --git a/src/pseudo.cpp b/src/pseudo.cpp index 3576c67..14050ef 100644 --- a/src/pseudo.cpp +++ b/src/pseudo.cpp @@ -54,6 +54,49 @@ using namespace std::chrono; constexpr year_month_day SINCE_1920{year(1920), month(1), day(1)}; +uint PseudoSprite::Byte::val() const { + return this->p->ExtractByte(this->read_len(this->offs)); +} + +uint PseudoSprite::Word::val() const { + return this->p->ExtractWord(this->read_len(this->offs)); +} + +uint PseudoSprite::ExtByte::val() const { + return this->p->ExtractExtended(this->read_len(this->offs)); +} + +uint PseudoSprite::Dword::val() const { + return this->p->ExtractDword(this->read_len(this->offs)); +} + +uint PseudoSprite::BaseSeqAccess::loc() const { + return offs; +} + +PseudoSprite::Byte& PseudoSprite::Byte::set(uint u) { + p->SetByteAt(offs, u); + return *this; +} + +PseudoSprite::Word& PseudoSprite::Word::set(uint u) { + p->SetByteAt(offs, u&0xFF); + p->SetByteAt(offs, u>>8); + return *this; +} + +PseudoSprite& PseudoSprite::operator >>(PseudoSprite::BaseSeqAccess &b) { + b.p = this; + b.offs = extract_offs; + extract_offs += b.read_len(extract_offs); + return *this; +} + +PseudoSprite& PseudoSprite::Extract(PseudoSprite::BaseSeqAccess &b, uint off) { + b.p = this; + b.offs = off; + return *this; +} #define cur_pos() ((uint)out.str().length()-1) #define next_pos() ((uint)out.str().length()) @@ -848,3 +891,12 @@ uint PseudoSprite::ReadValue(std::istream& in, width w) { in.clear(std::ios::badbit); return (uint)-1; } + +uint PseudoSprite::BytesRemaining() const { + return (uint)packed.length() - extract_offs; +} + +PseudoSprite& PseudoSprite::seek(uint off) { + extract_offs = off; + return *this; +} diff --git a/src/pseudo.h b/src/pseudo.h index 610dd90..00dc5cb 100644 --- a/src/pseudo.h +++ b/src/pseudo.h @@ -25,7 +25,6 @@ #include #include"ExpandingArray.h" - class PseudoSprite{ public: //PseudoSprite(); @@ -134,30 +133,54 @@ class PseudoSprite{ // Support for sequential access public: -#define PS_LOC_REF(size) \ - class size; \ - PseudoSprite& operator >>(size&); \ - PseudoSprite& Extract(size&, uint); \ - class size { \ - public: \ - size(); \ - size& set(uint); \ - uint val() const; \ - uint loc() const; \ - operator uint() const {return val();} \ - friend PseudoSprite& PseudoSprite::operator >>(size&); \ - friend PseudoSprite& PseudoSprite::Extract(size&, uint); \ - private: \ - PseudoSprite *p; \ - uint offs; \ - }; \ - - PS_LOC_REF(Byte) - PS_LOC_REF(Word) - PS_LOC_REF(ExtByte) - PS_LOC_REF(Dword) - -#undef PS_LOC_REF + class BaseSeqAccess; + PseudoSprite &operator>>(PseudoSprite::BaseSeqAccess &); + PseudoSprite &Extract(PseudoSprite::BaseSeqAccess &, uint); + class BaseSeqAccess { + public: + BaseSeqAccess() = default; + virtual uint val() const = 0; + uint loc() const; + operator uint() const { + return this->val(); + } + friend PseudoSprite &PseudoSprite::operator>>(PseudoSprite::BaseSeqAccess &); + friend PseudoSprite &PseudoSprite::Extract(PseudoSprite::BaseSeqAccess &, uint); + protected: + virtual uint read_len(uint) const = 0; + PseudoSprite *p; + uint offs; + }; + + class Byte : public BaseSeqAccess { + public: + uint val() const override; + Byte &set(uint u); + private: + uint read_len(uint) const override { return 1; }; + }; + + class Word : public BaseSeqAccess { + public: + uint val() const override; + Word &set(uint u); + private: + uint read_len(uint) const override { return 2; }; + }; + + class ExtByte : public BaseSeqAccess { + public: + uint val() const override; + private: + uint read_len(uint off) const override { return this->p->ExtendedLen(off); }; + }; + + class Dword : public BaseSeqAccess { + public: + uint val() const override; + private: + uint read_len(uint) const override { return 4; }; + }; uint BytesRemaining() const; PseudoSprite& seek(uint); diff --git a/src/pseudo_seq.cpp b/src/pseudo_seq.cpp deleted file mode 100644 index 8b4612f..0000000 --- a/src/pseudo_seq.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * pseudo_seq.cpp - * Sequential access implementation for the PseudoSprite classes. - * Separated due to preprocessor magic. - * - * Copyright 2009 by Dale McCoy. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDING - -#include - -#include "nforenum.h" -#include "pseudo.h" - -#define INCLUDING -#define FOR_CLASS Byte -#define WIDTH(x) 1 -#include "pseudo_seq.cpp" - -#define FOR_CLASS ExtByte -#define EXTRACT Extended -#define WIDTH(x) ExtendedLen(x) -#include "pseudo_seq.cpp" - -#define FOR_CLASS Word -#define WIDTH(x) 2 -#include "pseudo_seq.cpp" - -#define FOR_CLASS Dword -#define WIDTH(x) 4 -#include "pseudo_seq.cpp" - -#undef INCLUDING - -uint PseudoSprite::BytesRemaining() const { - return (uint)packed.length() - extract_offs; -} - -PseudoSprite& PseudoSprite::seek(uint off) { - extract_offs = off; - return *this; -} - -PseudoSprite::Byte& PseudoSprite::Byte::set(uint u) { - p->SetByteAt(offs, u); - return *this; -} - -PseudoSprite::Word& PseudoSprite::Word::set(uint u) { - p->SetByteAt(offs, u&0xFF); - p->SetByteAt(offs, u>>8); - return *this; -} - -#else // INCLUDING - -#ifndef EXTRACT -# define EXTRACT FOR_CLASS -#endif - -PseudoSprite::FOR_CLASS::FOR_CLASS() : - p(NULL) -{} - - -uint PseudoSprite::FOR_CLASS::val() const { - return p->BOOST_PP_CAT(Extract, EXTRACT(offs)); -} - -uint PseudoSprite::FOR_CLASS::loc() const { - return offs; -} - -PseudoSprite& PseudoSprite::operator >>(PseudoSprite::FOR_CLASS& b) { - b.p = this; - b.offs = extract_offs; - extract_offs += WIDTH(extract_offs); - return *this; -} - -PseudoSprite& PseudoSprite::Extract(PseudoSprite::FOR_CLASS& b, uint off) { - b.p = this; - b.offs = off; - return *this; -} - -#undef FOR_CLASS -#undef EXTRACT -#undef WIDTH - - -#endif //INCLUDING From db2f024b40d049ba96fce4b689b85fe6dfb52d92 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 8 Dec 2025 22:46:51 +0000 Subject: [PATCH 6/8] Fix: Output of newlines when printing PseudoSprites --- src/pseudo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pseudo.cpp b/src/pseudo.cpp index 14050ef..cd7a8ad 100644 --- a/src/pseudo.cpp +++ b/src/pseudo.cpp @@ -774,7 +774,10 @@ std::ostream&PseudoSprite::output(std::ostream&out){ // Tabs are expanded, write each line for (const std::vector&line : sections) { - for_each(line.begin(),line.end(),out< Date: Mon, 8 Dec 2025 22:51:13 +0000 Subject: [PATCH 7/8] Remove: Last remnants of boost from the build --- .devzone/build/grfcodec.spec | 1 - .github/workflows/ci-build.yml | 5 ++-- .github/workflows/release.yml | 1 - 0compile.txt | 46 ---------------------------------- CMakeLists.txt | 3 --- src/pseudo.cpp | 8 +----- 6 files changed, 3 insertions(+), 61 deletions(-) delete mode 100644 0compile.txt diff --git a/.devzone/build/grfcodec.spec b/.devzone/build/grfcodec.spec index d6f378f..0b8896d 100644 --- a/.devzone/build/grfcodec.spec +++ b/.devzone/build/grfcodec.spec @@ -10,7 +10,6 @@ Source0: %{name}-%{dz_version}.tar BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot BuildRequires: gcc-c++ -BuildRequires: boost-devel > 1.36 BuildRequires: libpng-devel Provides: nforenum = %{version} diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 0dbff7c..727785e 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -36,7 +36,7 @@ jobs: echo "::group::Install dependencies" sudo apt-get install -y --no-install-recommends \ - libboost-dev \ + libpng-dev \ # EOF echo "::endgroup::" env: @@ -84,7 +84,7 @@ jobs: - name: Prepare vcpkg run: | ${{ steps.vcpkg.outputs.vcpkg }} install --triplet=${{ matrix.arch }}-osx \ - boost-date-time \ + libpng \ # EOF - name: Install GCC problem matcher @@ -131,7 +131,6 @@ jobs: shell: bash run: | "${{ steps.vcpkg.outputs.vcpkg }}" install --triplet=${{ matrix.arch }}-windows-static \ - boost-date-time \ libpng \ # EOF diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 99fef0a..4b89851 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -84,7 +84,6 @@ jobs: shell: bash run: | "${{ steps.vcpkg.outputs.vcpkg }}" install --triplet=${{ matrix.arch }}-windows-static \ - boost-date-time \ libpng \ # EOF diff --git a/0compile.txt b/0compile.txt deleted file mode 100644 index e993ccd..0000000 --- a/0compile.txt +++ /dev/null @@ -1,46 +0,0 @@ -How to compile the GRF development tools ------------------------ - -Compiling the GRF development tools is pretty straightforward. It can be -done, with varying quantities of automation, with Cygwin's gcc (using -Makefile for a cygwin-dependant binary, any Linux gcc (using Makefile, -for a Linux binary). - -GRFCodec and NFORenum require Boost 1.36 or higher. The make system does -not check the Boost version, so compiling with a lower version of Boost -will result in compile failures. - -GRFCodec and NFORenum can optionally be compiled with PNG support. -This requires libpng and zlib to be available. - - -Compiling with make -=================== - -The Makefile will attempt to auto-detect: -- Whether you are building on Cygwin or Linux (ISCYGWIN) -- The location of your boost includes (BOOST_INCLUDE) - -If it gets these wrong, modify Makefile.local appropriately, or set the above -mentioned controlling variables. -ISCYGWIN: 1 on cygwin and 0 on Linux. -BOOST_INCLUDE is the directory where your boost headers can be found. - - -Targets -------- - -The following are the most intersting targets. Other targets exist, but are -less useful. - -all Compile grfcodec, grfid, grfstrip and nforenum - -grfcodec -grfid -grfstrip -nforenum Compile the program in question, using gcc. - -release Compile all programs, then strip and upx them (if enabled) - -clean Delete all compiled files -remake Equivalent of "make clean all" diff --git a/CMakeLists.txt b/CMakeLists.txt index 873c0b3..729a80a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,6 @@ endif() find_package(PNG) -find_package(Boost CONFIG REQUIRED) include(CheckCXXSymbolExists) @@ -120,13 +119,11 @@ add_dependencies(grfstrip version_header) # Create nforenum add_executable(nforenum) add_dependencies(nforenum palettes_header version_header) -target_link_libraries(nforenum Boost::boost) # Create grfcodec add_executable(grfcodec) add_dependencies(grfcodec palettes_header version_header) -target_link_libraries(grfcodec Boost::boost) if(PNG_FOUND) set_target_properties(grfcodec PROPERTIES COMPILE_FLAGS -DWITH_PNG) target_link_libraries(grfcodec PNG::PNG) diff --git a/src/pseudo.cpp b/src/pseudo.cpp index cd7a8ad..c260e62 100644 --- a/src/pseudo.cpp +++ b/src/pseudo.cpp @@ -19,6 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include #include @@ -26,13 +27,6 @@ #include #include -/* If your compiler errors on the following lines, boost is not - * properly installed. - * Get boost from http://www.boost.org */ -#include -#include -#include - #include"nforenum.h" #include"mapescapes.h" #include"pseudo.h" From b30fe41c6f57eaa6c7a5fd61aca0397b2e17df6d Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 8 Dec 2025 22:51:27 +0000 Subject: [PATCH 8/8] Remove: OTTDC devzone config --- .devzone/build/files | 2 - .devzone/build/grfcodec.spec | 53 ----------------------- .devzone/build/nightlies/cleanup_days | 1 - .devzone/build/nightlies/cleanup_releases | 1 - .devzone/build/nightlies/enable | 1 - .devzone/build/type | 1 - 6 files changed, 59 deletions(-) delete mode 100644 .devzone/build/files delete mode 100644 .devzone/build/grfcodec.spec delete mode 100644 .devzone/build/nightlies/cleanup_days delete mode 100644 .devzone/build/nightlies/cleanup_releases delete mode 100644 .devzone/build/nightlies/enable delete mode 100644 .devzone/build/type diff --git a/.devzone/build/files b/.devzone/build/files deleted file mode 100644 index dd25643..0000000 --- a/.devzone/build/files +++ /dev/null @@ -1,2 +0,0 @@ -R;%{RPMBUILDDIR}/RPMS/%{ARCH}/*.%{ARCH}.rpm -5;%{RPMBUILDDIR}/SRPMS/*.src.rpm diff --git a/.devzone/build/grfcodec.spec b/.devzone/build/grfcodec.spec deleted file mode 100644 index 0b8896d..0000000 --- a/.devzone/build/grfcodec.spec +++ /dev/null @@ -1,53 +0,0 @@ -Name: %{dz_repo} -Version: 999.%{dz_version} -Release: %{_vendor}%{?suse_version} -Summary: A suite of programs to develop NewGRFs -Group: Development/Tools/Building -License: GPLv2+ -URL: http://dev.openttdcoop.org/projects/grfcodec -Source0: %{name}-%{dz_version}.tar - -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot - -BuildRequires: gcc-c++ -BuildRequires: libpng-devel - -Provides: nforenum = %{version} -Obsoletes: nforenum < %{version} - -#We need Mercurial for auto version detection: (not needed with source tarball) -BuildRequires: mercurial - -%description -A suite of programs to modify Transport Tycoon Deluxe's GRF files. -Contains GRFCodec for encoding and decoding the actual GRF files, -GRFID for extracting the (unique) NewGRF identifier and NFORenum, -a format correcter and linter for the NFO language. NFO and PCX -or PNG files are encoded to form GRF files. - -%prep -%setup -qn %{name} - -%build -make %{?_smp_mflags} - -%install -make install DESTDIR=%{buildroot} prefix=%{_prefix} - -%clean - -%files -%defattr(-,root,root,-) -%{_bindir}/grfcodec -%{_bindir}/grfid -%{_bindir}/grfstrip -%{_bindir}/nforenum -%dir %{_datadir}/doc/grfcodec -%doc %{_datadir}/doc/grfcodec/COPYING -%doc %{_datadir}/doc/grfcodec/*.txt -%{_mandir}/man1/grfcodec.1* -%{_mandir}/man1/grfid.1* -%{_mandir}/man1/grfstrip.1* -%{_mandir}/man1/nforenum.1* - -%changelog diff --git a/.devzone/build/nightlies/cleanup_days b/.devzone/build/nightlies/cleanup_days deleted file mode 100644 index 573541a..0000000 --- a/.devzone/build/nightlies/cleanup_days +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/.devzone/build/nightlies/cleanup_releases b/.devzone/build/nightlies/cleanup_releases deleted file mode 100644 index d00491f..0000000 --- a/.devzone/build/nightlies/cleanup_releases +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/.devzone/build/nightlies/enable b/.devzone/build/nightlies/enable deleted file mode 100644 index 30c33ac..0000000 --- a/.devzone/build/nightlies/enable +++ /dev/null @@ -1 +0,0 @@ -libpng diff --git a/.devzone/build/type b/.devzone/build/type deleted file mode 100644 index 916f55d..0000000 --- a/.devzone/build/type +++ /dev/null @@ -1 +0,0 @@ -rpm