From e8f4b20d1d0c896c77a27c8ba3f1f8413067d511 Mon Sep 17 00:00:00 2001 From: Kp Date: Sun, 7 Sep 2014 19:48:10 +0000 Subject: [PATCH] Use special type for PHYSFSX_fgets --- common/include/physfsx.h | 58 +++++++++++++++++++++++++++++++++++++ common/ui/keypad.cpp | 8 ++--- common/ui/menubar.cpp | 2 +- d1x-rebirth/main/bmread.cpp | 4 +-- d2x-rebirth/main/bmread.cpp | 4 +-- similar/editor/med.cpp | 2 +- similar/main/config.cpp | 11 ++++--- similar/main/credits.cpp | 2 +- similar/main/endlevel.cpp | 3 +- similar/main/mission.cpp | 16 ++++++---- similar/main/piggy.cpp | 6 ++-- similar/main/playsave.cpp | 14 ++++----- similar/main/songs.cpp | 2 +- similar/misc/args.cpp | 2 +- 14 files changed, 98 insertions(+), 36 deletions(-) diff --git a/common/include/physfsx.h b/common/include/physfsx.h index ed032924f..7b355662d 100644 --- a/common/include/physfsx.h +++ b/common/include/physfsx.h @@ -277,8 +277,66 @@ static inline int PHYSFSX_fseek(PHYSFS_file *fp, long int offset, int where) return !c; } +template +struct PHYSFSX_gets_line_t +{ + PHYSFSX_gets_line_t() = default; + PHYSFSX_gets_line_t(const PHYSFSX_gets_line_t &) = delete; + struct line_t + { + char buf[N]; + }; +#ifdef DXX_HAVE_POISON + /* Force onto heap to improve checker accuracy */ + std::unique_ptr m_line; + decltype(line_t::buf) &line() { return m_line->buf; } + decltype(line_t::buf) &next() + { + m_line.reset(new line_t); + return line(); + } +#else + line_t m_line; + decltype(line_t::buf) &line() { return m_line.buf; } + decltype(line_t::buf) &next() { return line(); } +#endif + operator decltype(line_t::buf) &() { return line(); } + operator const decltype(line_t::buf) &() const { return line(); } + std::size_t size() const { return N; } +}; + +template <> +struct PHYSFSX_gets_line_t<0> +{ + std::unique_ptr m_line; + std::size_t m_length; + PHYSFSX_gets_line_t(std::size_t n) : + m_line(new char[n]), + m_length(n) + { + } + char *line() { return m_line.get(); } + char *next() + { +#ifdef DXX_HAVE_POISON + m_line.reset(new char[m_length]); +#endif + return line(); + } + std::size_t size() const { return m_length; } + operator const char *() const { return m_line.get(); } + const char *begin() const { return *this; } + const char *end() const { return begin() + m_length; } +}; + char *PHYSFSX_fgets(char *buf, size_t n, PHYSFS_file *const fp); +template +static inline char * PHYSFSX_fgets(PHYSFSX_gets_line_t &buf, PHYSFS_file *const fp, std::size_t offset = 0) +{ + return PHYSFSX_fgets(buf.next() + offset, buf.size() - offset, fp); +} + template static inline char * PHYSFSX_fgets(char (&buf)[n], PHYSFS_file *const fp) { diff --git a/common/ui/keypad.cpp b/common/ui/keypad.cpp index e0c11764d..2a3599102 100644 --- a/common/ui/keypad.cpp +++ b/common/ui/keypad.cpp @@ -306,9 +306,7 @@ void ui_pad_goto_prev() void ui_pad_read( int n, const char * filename ) { char * ptr; - char buffer[100]; char text[100]; - char line_buffer[200]; PHYSFS_file * infile; int linenumber = 0; int i; @@ -334,6 +332,7 @@ void ui_pad_read( int n, const char * filename ) KeyPad[n]->function_number[i] = 0; } + PHYSFSX_gets_line_t<100> buffer; while ( linenumber < 22) { PHYSFSX_fgets( buffer, infile ); @@ -511,14 +510,15 @@ void ui_pad_read( int n, const char * filename ) // Get the keycodes... + PHYSFSX_gets_line_t<200> line_buffer; while (PHYSFSX_fgets(line_buffer, infile)) { - sscanf(line_buffer, " %s %s ", text, buffer); + sscanf(line_buffer, " %s %99s ", text, buffer.line()); keycode = DecodeKeyText(text); functionnumber = func_get_index(buffer); if (functionnumber==-1) { - Error( "Unknown function, %s, in %s\n", buffer, filename ); + Error( "Unknown function, %s, in %s\n", buffer.line(), filename ); } else if (keycode==-1) { Error( "Unknown keystroke, %s, in %s\n", text, filename ); diff --git a/common/ui/menubar.cpp b/common/ui/menubar.cpp index aa5c55d0e..d36191f64 100644 --- a/common/ui/menubar.cpp +++ b/common/ui/menubar.cpp @@ -742,7 +742,6 @@ void menubar_init( const char * file ) int i,j, np; int aw, w, h; PHYSFS_file * infile; - char buffer[200]; char buf1[200]; char buf2[200]; int menu, item; @@ -760,6 +759,7 @@ void menubar_init( const char * file ) if (!infile) return; + PHYSFSX_gets_line_t<200> buffer; while ( PHYSFSX_fgets( buffer, infile) != NULL ) { if ( buffer[0] == ';' ) continue; diff --git a/d1x-rebirth/main/bmread.cpp b/d1x-rebirth/main/bmread.cpp index beda53c44..f2b13412b 100644 --- a/d1x-rebirth/main/bmread.cpp +++ b/d1x-rebirth/main/bmread.cpp @@ -333,7 +333,6 @@ int gamedata_read_tbl(int pc_shareware) { std::string dest_bm; PHYSFS_file * InfoFile; - char inputline[LINEBUF_SIZE]; int i, have_bin_tbl; ObjType[0] = OL_PLAYER; @@ -391,6 +390,7 @@ int gamedata_read_tbl(int pc_shareware) PHYSFSX_fseek( InfoFile, 0L, SEEK_SET); + PHYSFSX_gets_line_t inputline; while (PHYSFSX_fgets(inputline, InfoFile)) { int l; char *temp_ptr; @@ -406,7 +406,7 @@ int gamedata_read_tbl(int pc_shareware) inputline[l-2] = ' '; //add one l++; } - PHYSFSX_fgets(inputline+l-2,LINEBUF_SIZE-(l-2), InfoFile); + PHYSFSX_fgets(inputline,InfoFile,l-2); linenum++; } } diff --git a/d2x-rebirth/main/bmread.cpp b/d2x-rebirth/main/bmread.cpp index 9186d0421..746a95896 100644 --- a/d2x-rebirth/main/bmread.cpp +++ b/d2x-rebirth/main/bmread.cpp @@ -378,7 +378,6 @@ static int get_texture(char *name) int gamedata_read_tbl(int pc_shareware) { PHYSFS_file * InfoFile; - char inputline[LINEBUF_SIZE]; int i, have_bin_tbl; // Open BITMAPS.TBL for reading. @@ -442,6 +441,7 @@ int gamedata_read_tbl(int pc_shareware) PHYSFSX_fseek( InfoFile, 0L, SEEK_SET); + PHYSFSX_gets_line_t inputline; while (PHYSFSX_fgets(inputline, InfoFile)) { int l; char *temp_ptr; @@ -465,7 +465,7 @@ int gamedata_read_tbl(int pc_shareware) inputline[l-2] = ' '; //add one l++; } - PHYSFSX_fgets(inputline+l-2,LINEBUF_SIZE-(l-2), InfoFile); + PHYSFSX_fgets(inputline,InfoFile,l-2); linenum++; } } diff --git a/similar/editor/med.cpp b/similar/editor/med.cpp index b663e9a04..3c9f5ae85 100644 --- a/similar/editor/med.cpp +++ b/similar/editor/med.cpp @@ -280,7 +280,6 @@ static void medkey_init() { PHYSFS_file * keyfile; char keypress[100]; - char line_buffer[200]; int key; int i; //, size; int np; @@ -292,6 +291,7 @@ static void medkey_init() keyfile = PHYSFSX_openReadBuffered( "GLOBAL.KEY" ); if (keyfile) { + PHYSFSX_gets_line_t<200> line_buffer; while (PHYSFSX_fgets(line_buffer, keyfile)) { sscanf(line_buffer, " %s %s ", keypress, LispCommand); diff --git a/similar/main/config.cpp b/similar/main/config.cpp index d013f3e8a..5a4c1abd1 100644 --- a/similar/main/config.cpp +++ b/similar/main/config.cpp @@ -81,7 +81,6 @@ static const char GrabinputStr[] ="GrabInput"; int ReadConfigFile() { PHYSFS_file *infile; - char *ptr; const char *token, *value; // set defaults @@ -144,11 +143,11 @@ int ReadConfigFile() return 1; } - std::size_t max_len = PHYSFS_fileLength(infile) + 1; // to be fully safe, assume the whole cfg consists of one big line - for (auto line = make_unique(max_len); !PHYSFS_eof(infile);) + // to be fully safe, assume the whole cfg consists of one big line + for (PHYSFSX_gets_line_t<0> line(PHYSFS_fileLength(infile) + 1); !PHYSFS_eof(infile);) { - PHYSFSX_fgets(line.get(), max_len, infile); - ptr = &(line[0]); + PHYSFSX_fgets(line, infile); + char *ptr = line.line(); while (isspace(*ptr)) ptr++; if (*ptr != '\0') { @@ -213,7 +212,7 @@ int ReadConfigFile() gr_palette_set_gamma( GameCfg.GammaLevel ); } else if (!strcmp(token, LastPlayerStr)) { - GameCfg.LastPlayer.copy_lower(value, std::distance(value, std::find(value, const_cast(line.get()) + max_len, 0))); + GameCfg.LastPlayer.copy_lower(value, std::distance(value, std::find(value, line.end(), 0))); } else if (!strcmp(token, LastMissionStr)) { char * p; diff --git a/similar/main/credits.cpp b/similar/main/credits.cpp index 2f784583c..6f81d1021 100644 --- a/similar/main/credits.cpp +++ b/similar/main/credits.cpp @@ -69,7 +69,7 @@ struct credits : ignore_window_pointer_t { PHYSFS_file * file; int have_bin_file; - char buffer[NUM_LINES][80]; + array, NUM_LINES> buffer; int buffer_line; int first_line_offset; int extra_inc; diff --git a/similar/main/endlevel.cpp b/similar/main/endlevel.cpp index 9e065f957..621fcdcfe 100644 --- a/similar/main/endlevel.cpp +++ b/similar/main/endlevel.cpp @@ -1396,7 +1396,7 @@ static int convert_ext(d_fname &dest, const char (&ext)[4]) void load_endlevel_data(int level_num) { d_fname filename; - char line[LINE_LEN],*p; + char *p; PHYSFS_file *ifile; int var,sidenum; int exit_side = 0; @@ -1453,6 +1453,7 @@ try_again: var = 0; + PHYSFSX_gets_line_t line; while (PHYSFSX_fgets(line,ifile)) { if (have_binary) diff --git a/similar/main/mission.cpp b/similar/main/mission.cpp index d2434c175..118e08129 100644 --- a/similar/main/mission.cpp +++ b/similar/main/mission.cpp @@ -319,7 +319,7 @@ static char *get_value(char *buf) } //reads a line, returns ptr to value of passed parm. returns NULL if none -static char *get_parm_value(char (&buf)[80], const char *parm,PHYSFS_file *f) +static char *get_parm_value(PHYSFSX_gets_line_t<80> &buf, const char *parm,PHYSFS_file *f) { if (!PHYSFSX_fgets(buf,f)) return NULL; @@ -368,7 +368,7 @@ static int read_mission_file(mission_list &mission_list, const char *filename, e mission->filename = next(begin(mission->path), p - temp); mission->location = location; - char buf[80]; + PHYSFSX_gets_line_t<80> buf; p = get_parm_value(buf, "name",mfile); #if defined(DXX_BUILD_DESCENT_II) @@ -405,6 +405,8 @@ static int read_mission_file(mission_list &mission_list, const char *filename, e return 0; } + { + PHYSFSX_gets_line_t<4096> temp; if (PHYSFSX_fgets(temp,mfile)) { if (istok(temp,"type")) @@ -415,6 +417,7 @@ static int read_mission_file(mission_list &mission_list, const char *filename, e mission->anarchy_only_flag = istok(p,"anarchy"); } } + } PHYSFS_close(mfile); @@ -796,7 +799,8 @@ static int load_mission(const mle *mission) Ending_text_filename = Briefing_text_filename; } - while (PHYSFSX_fgets(buf,mfile)) { + for (PHYSFSX_gets_line_t<4096> buf; PHYSFSX_fgets(buf,mfile);) + { #if defined(DXX_BUILD_DESCENT_II) if (istok(buf,"name") && !Current_mission->enhanced) { Current_mission->enhanced = 0; @@ -837,7 +841,7 @@ static int load_mission(const mle *mission) for (i=0;iLast_level) break; @@ -897,7 +901,7 @@ static int load_mission(const mle *mission) con_printf(CON_URGENT, "Mission %s has no HAM.", Current_mission->path.c_str()); } else { - con_printf(CON_URGENT, "Mission %s uses unsupported critical directive \"%s\".", Current_mission->path.c_str(), buf); + con_printf(CON_URGENT, "Mission %s uses unsupported critical directive \"%s\".", Current_mission->path.c_str(), buf.line()); Last_level = 0; break; } diff --git a/similar/main/piggy.cpp b/similar/main/piggy.cpp index ee05aac47..9db2a9815 100644 --- a/similar/main/piggy.cpp +++ b/similar/main/piggy.cpp @@ -1949,7 +1949,6 @@ static void read_d1_tmap_nums_from_hog(PHYSFS_file *d1_pig) #define LINEBUF_SIZE 600 int reading_textures = 0; short texture_count = 0; - char inputline[LINEBUF_SIZE]; PHYSFS_file * bitmaps; int bitmaps_tbl_is_binary = 0; int i; @@ -1968,14 +1967,15 @@ static void read_d1_tmap_nums_from_hog(PHYSFS_file *d1_pig) d1_tmap_nums = make_unique(); d1_tmap_nums->fill(-1); - while (PHYSFSX_fgets (inputline, bitmaps)) { + for (PHYSFSX_gets_line_t inputline; PHYSFSX_fgets (inputline, bitmaps);) + { char *arg; if (bitmaps_tbl_is_binary) decode_text_line((inputline)); else while (inputline[(i=strlen(inputline))-2]=='\\') - PHYSFSX_fgets(inputline+i-2,LINEBUF_SIZE-(i-2), bitmaps); // strip comments + PHYSFSX_fgets(inputline,bitmaps,i-2); // strip comments REMOVE_EOL(inputline); if (strchr(inputline, ';')!=NULL) REMOVE_COMMENTS(inputline); if (strlen(inputline) == LINEBUF_SIZE-1) { diff --git a/similar/main/playsave.cpp b/similar/main/playsave.cpp index 2382d1187..423ca6598 100644 --- a/similar/main/playsave.cpp +++ b/similar/main/playsave.cpp @@ -283,7 +283,6 @@ static int read_player_dxx(const char *filename) { PHYSFS_file *f; int rc = 0; - char line[50]; plyr_read_stats(); @@ -292,7 +291,7 @@ static int read_player_dxx(const char *filename) if(!f || PHYSFS_eof(f)) return errno; - while(PHYSFSX_fgets(line,f) && !PHYSFS_eof(f)) + for (PHYSFSX_gets_line_t<50> line; PHYSFSX_fgets(line,f) && !PHYSFS_eof(f);) { #if defined(DXX_BUILD_DESCENT_I) if (!strcmp(line, WEAPON_REORDER_HEADER_TEXT)) @@ -538,7 +537,7 @@ static void plyr_read_stats_v(int *k, int *d) if(f) { - char line[256]; + PHYSFSX_gets_line_t<256> line; if(!PHYSFS_eof(f)) { PHYSFSX_fgets(line,f); @@ -1054,10 +1053,11 @@ int read_player_file() strcpy(PlayerCfg.GuidebotNameReal,PlayerCfg.GuidebotName); { - char buf[128]; - if (player_file_version >= 24) + { + PHYSFSX_gets_line_t<128> buf; PHYSFSX_fgets(buf, file); // Just read it in fpr DPS. + } } #endif @@ -1331,7 +1331,7 @@ static int get_lifetime_checksum (int a,int b) // read stored values from ngp file to netgame_info void read_netgame_profile(netgame_info *ng) { - char filename[PATH_MAX], line[50], *token, *ptr; + char filename[PATH_MAX], *token, *ptr; PHYSFS_file *file; snprintf(filename, sizeof(filename), PLAYER_DIRECTORY_STRING("%.8s.ngp"), static_cast(Players[Player_num].callsign)); @@ -1346,7 +1346,7 @@ void read_netgame_profile(netgame_info *ng) // NOTE that we do not set any defaults here or even initialize netgame_info. For flexibility, leave that to the function calling this. while (!PHYSFS_eof(file)) { - memset(line, 0, 50); + PHYSFSX_gets_line_t<50> line; PHYSFSX_fgets(line, file); ptr = &(line[0]); while (isspace(*ptr)) diff --git a/similar/main/songs.cpp b/similar/main/songs.cpp index a87eac7b7..853bde36f 100644 --- a/similar/main/songs.cpp +++ b/similar/main/songs.cpp @@ -74,7 +74,6 @@ void songs_set_volume(int volume) static void songs_init() { int i = 0; - char inputline[80+1]; PHYSFS_file * fp = NULL; Songs_initialized = 0; @@ -115,6 +114,7 @@ static void songs_init() } else { + PHYSFSX_gets_line_t<81> inputline; while (!PHYSFS_eof(fp) && PHYSFSX_fgets(inputline, fp)) { if ( strlen( inputline ) ) diff --git a/similar/misc/args.cpp b/similar/misc/args.cpp index 866ef7633..21601a158 100644 --- a/similar/misc/args.cpp +++ b/similar/misc/args.cpp @@ -72,7 +72,7 @@ static void AppendIniArgs(void) f = PHYSFSX_openReadBuffered(INI_FILENAME); if(f) { - char line[1024]; + PHYSFSX_gets_line_t<1024> line; while(!PHYSFS_eof(f) && Args.size() < MAX_ARGS && PHYSFSX_fgets(line, f)) { static const char separator[] = " ";