Skip to content

Commit

Permalink
Merge pull request #85 from bmorel/stl_explodelist
Browse files Browse the repository at this point in the history
std::vector based explodelist
  • Loading branch information
TheAssassin authored Jul 25, 2020
2 parents 6b1a475 + 96e6f83 commit 60da7b1
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 71 deletions.
10 changes: 10 additions & 0 deletions src/engine/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// is largely backwards compatible with the quake console language.

#include <vector>
#include <algorithm>
#include <string>
using std::swap;
#include "engine.h"

bool interactive = false;

hashnameset<ident> idents; // contains ALL vars/commands/aliases
Expand Down Expand Up @@ -2762,6 +2765,13 @@ void explodelist(const char *s, vector<char *> &elems, int limit)
elems.add(newstring(start, end-start));
}

void explodelist(const char *s, std::vector<std::string> &elems, int limit)
{
const char *start, *end;
while((limit < 0 || elems.size() < limit) && parselist(s, start, end))
elems.emplace_back(std::string(start, end-start));
}

char *indexlist(const char *s, int pos)
{
loopi(pos) if(!parselist(s)) return newstring("");
Expand Down
16 changes: 8 additions & 8 deletions src/engine/rendertext.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <vector>
#include <string>
#include <algorithm>
using std::swap;
#include "engine.h"
Expand Down Expand Up @@ -709,26 +711,25 @@ float key_widthf(const char *str)
{
const char *keyn = str;
if(*str == '=') keyn = gettklp(++str);
vector<char *> list;
std::vector<std::string> list;
explodelist(keyn, list);
float width = 0, scale = curfont->maxh*curfont->scale/float(curfont->defaulth)*curtextscale*textkeyimagescale;
loopv(list)
{
if(i && textkeyseps) width += text_widthf("|");
if(textkeyimages)
{
textkey *t = findtextkey(list[i]);
textkey *t = findtextkey(list[i].c_str());
if(t && t->tex)
{
width += (t->tex->w*scale)/float(t->tex->h);
continue;
}
// fallback if not found
}
defformatkey(keystr, list[i]);
defformatkey(keystr, list[i].c_str());
width += text_widthf(keystr);
}
list.deletearrays();
return width;
}

Expand All @@ -737,14 +738,14 @@ static int draw_key(Texture *&tex, const char *str, float sx, float sy)
Texture *oldtex = tex;
const char *keyn = str;
if(*str == '=') keyn = gettklp(++str);
vector<char *> list;
std::vector<std::string> list;
explodelist(keyn, list);
float width = 0, sh = curfont->maxh*curfont->scale/float(curfont->defaulth)*curtextscale, h = sh*textkeyimagescale;
loopv(list)
{
if(textkeyimages)
{
textkey *t = findtextkey(list[i]);
textkey *t = findtextkey(list[i].c_str());
if(t && t->tex)
{
if(tex != t->tex)
Expand All @@ -769,11 +770,10 @@ static int draw_key(Texture *&tex, const char *str, float sx, float sy)
tex = oldtex;
glBindTexture(GL_TEXTURE_2D, tex->id);
}
defformatkey(keystr, list[i]);
defformatkey(keystr, list[i].c_str());
draw_text(keystr, sx + width, sy, 255, 255, 255, 255, 0, -1, -1, 1, -1);
width += text_widthf(keystr);
}
list.deletearrays();
return width;
}

Expand Down
7 changes: 3 additions & 4 deletions src/engine/skelmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -1810,17 +1810,16 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes

part *p = (part *)MDL::loading->parts.last();

vector<char *> bonestrs;
std::vector<std::string> bonestrs;
explodelist(maskstr, bonestrs);
vector<ushort> bonemask;
loopv(bonestrs)
{
char *bonestr = bonestrs[i];
char const *bonestr = bonestrs[i].c_str();
int bone = p->meshes ? ((meshgroup *)p->meshes)->skel->findbone(bonestr[0]=='!' ? bonestr+1 : bonestr) : -1;
if(bone<0) { conoutf("\frcould not find bone %s for anim part mask [%s]", bonestr, maskstr); bonestrs.deletearrays(); return; }
if(bone<0) { conoutf("\frcould not find bone %s for anim part mask [%s]", bonestr, maskstr); return; }
bonemask.add(bone | (bonestr[0]=='!' ? BONEMASK_NOT : 0));
}
bonestrs.deletearrays();
bonemask.sort();
if(bonemask.length()) bonemask.add(BONEMASK_END);

Expand Down
9 changes: 5 additions & 4 deletions src/engine/world.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// world.cpp: core map management stuff
#include <algorithm>
#include <string>
using std::swap;

#include "engine.h"
Expand Down Expand Up @@ -776,12 +777,12 @@ int newentity(int type, const attrvector &attrs)

void entattrs(const char *str, attrvector &attrs)
{
static vector<char *> buf;
static std::vector<std::string> buf;
explodelist(str, buf, MAXENTATTRS);
attrs.setsize(0);
attrs.add(0, buf.length());
loopv(buf) attrs[i] = parseint(buf[i]);
buf.deletearrays();
attrs.add(0, buf.size());
loopv(buf) attrs[i] = parseint(buf[i].c_str());
buf.clear();
}

void newent(char *what, char *attr)
Expand Down
27 changes: 13 additions & 14 deletions src/game/client.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <vector>
#include <string>
#include <algorithm>
using std::swap;
#include "game.h"
Expand Down Expand Up @@ -396,11 +398,10 @@ namespace client

void updateserversort()
{
vector<char *> styles;
std::vector<std::string> styles;
explodelist(serversort, styles, SINFO_MAX);
serversortstyles.setsize(0);
loopv(styles) serversortstyles.add(parseint(styles[i]));
styles.deletearrays();
serversortstyles.clear();
loopv(styles) serversortstyles.emplace_back(parseint(styles[i].c_str()));
}

void getvitem(gameent *d, int n, int v)
Expand Down Expand Up @@ -469,15 +470,14 @@ namespace client
vector<int> items;
if(list && *list)
{
vector<char *> chunk;
std::vector<std::string> chunk;
explodelist(list, chunk);
loopv(chunk)
{
if(!chunk[i] || !*chunk[i] || !isnumeric(*chunk[i])) continue;
int v = parseint(chunk[i]);
items.add(v >= W_OFFSET && v < W_ITEM ? v : 0);
if(chunk[i].empty() || !isnumeric(chunk[i][0])) continue;
int v = parseint(chunk[i].c_str());
items.emplace_back(v >= W_OFFSET && v < W_ITEM ? v : 0);
}
chunk.deletearrays();
}
game::player1.loadweap.shrink(0);
loopv(items) if(game::player1.loadweap.find(items[i]) < 0)
Expand All @@ -494,15 +494,14 @@ namespace client
vector<int> items;
if(list && *list)
{
vector<char *> chunk;
std::vector<std::string> chunk;
explodelist(list, chunk);
loopv(chunk)
{
if(!chunk[i] || !*chunk[i] || !isnumeric(*chunk[i])) continue;
int v = parseint(chunk[i]);
items.add(v ? 1 : 0);
if(chunk[i].empty() || !isnumeric(chunk[i][0])) continue;
int v = parseint(chunk[i].c_str());
items.emplace_back(v != 0 ? 1 : 0);
}
chunk.deletearrays();
}
game::player1.randweap.shrink(0);
loopv(items)
Expand Down
16 changes: 8 additions & 8 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <algorithm>
#include <vector>
#include <string>
using std::swap;
#include <vector>
#define GAMEWORLD 1
Expand Down Expand Up @@ -409,12 +411,11 @@ namespace game
void vanitybuild(gameent *d)
{
if(!*d->vanity) return; // not needed
vector<char *> vanitylist;
std::vector<std::string> vanitylist;
explodelist(d->vanity, vanitylist);
loopv(vanitylist) if(vanitylist[i] && *vanitylist[i])
loopvk(vanities) if(!strcmp(vanities[k].ref, vanitylist[i]))
loopv(vanitylist) if(!vanitylist[i].empty())
loopvk(vanities) if(!strcmp(vanities[k].ref, vanitylist[i].c_str()))
d->vitems.add(k);
vanitylist.deletearrays();
}

const char *vanitymodel(gameent *d)
Expand Down Expand Up @@ -3415,12 +3416,11 @@ namespace game
int idx = third == 1 && (d->state == CS_DEAD || d->state == CS_WAITING) && d->headless && !nogore && headlessmodels ? 3 : third;
if(d->vitems.empty())
{
vector<char *> vanitylist;
std::vector<std::string> vanitylist;
explodelist(d->vanity, vanitylist);
loopv(vanitylist) if(vanitylist[i] && *vanitylist[i])
loopvk(vanities) if(!strcmp(vanities[k].ref, vanitylist[i]))
loopv(vanitylist) if(!vanitylist[i].empty())
loopvk(vanities) if(vanitylist[i] == vanities[k].ref)
d->vitems.add(k);
vanitylist.deletearrays();
}
int found[VANITYMAX] = {0};
loopvk(d->vitems) if(vanities.inrange(d->vitems[k]))
Expand Down
52 changes: 23 additions & 29 deletions src/game/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
// each modification must be approved and will be done on a case-by-case basis.

#include <algorithm>
#include <vector>
#include <string>
using std::swap;

#define GAMESERVER 1
Expand Down Expand Up @@ -1058,29 +1060,27 @@ namespace server
if(!map || !*map) map = choosemap(suggest, mode, muts, G(rotatemaps), true);
else if(strchr(map, ' '))
{
static string defaultmap;
defaultmap[0] = '\0';
vector<char *> maps;
static std::string defaultmap;
std::vector<std::string> maps;
explodelist(map, maps);
if(*sv_previousmaps)
{
vector<char *> prev;
std::vector<std::string> prev;
explodelist(sv_previousmaps, prev);
loopvj(prev) loopvrev(maps) if(strcmp(prev[j], maps[i]))
loopvj(prev) loopvrev(maps) if(prev[j] != maps[i])
{
delete[] maps[i];
maps.remove(i);
if(maps.length() <= 1) break;
maps.erase( maps.begin() + i );
if(maps.size() <= 1) break;
}
prev.deletearrays();
prev.clear();
}
if(!maps.empty())
{
int r = rnd(maps.length());
copystring(defaultmap, maps[r]);
int r = rnd(maps.size());
defaultmap = maps[r];
}
maps.deletearrays();
map = *defaultmap ? defaultmap : choosemap(suggest, mode, muts, G(rotatemaps), true);
maps.clear();
map = !defaultmap.empty() ? defaultmap.c_str() : choosemap(suggest, mode, muts, G(rotatemaps), true);
}
}
return map && *map ? map : "maps/untitled";
Expand Down Expand Up @@ -3377,33 +3377,27 @@ namespace server

if(!demoplayback && m_play(gamemode) && numclients())
{
vector<char> buf;
buf.put(smapname, strlen(smapname));
std::string buf = smapname;
if(*sv_previousmaps && G(maphistory))
{
vector<char *> prev;
std::vector<std::string> prev;
explodelist(sv_previousmaps, prev);
loopvrev(prev) if(!strcmp(prev[i], smapname))
loopvrev(prev) if(prev[i] == smapname)
{
delete[] prev[i];
prev.remove(i);
prev.erase( prev.begin() + i );
}
while(prev.length() >= G(maphistory))
while(prev.size() >= G(maphistory))
{
int last = prev.length()-1;
delete[] prev[last];
prev.remove(last);
prev.pop_back();
}
loopv(prev)
{
buf.add(' ');
buf.put(prev[i], strlen(prev[i]));
buf += ' ';
buf += prev[i];
}
prev.deletearrays();
prev.clear();
}
buf.add(0);
const char *str = buf.getbuf();
if(*str) setmods(sv_previousmaps, str);
if(!buf.empty()) setmods(sv_previousmaps, buf.c_str());
}
else setmods(sv_previousmaps, "");

Expand Down
12 changes: 8 additions & 4 deletions src/game/weapons.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <vector>
#include <string>
#include <algorithm>
using std::swap;
#include "game.h"
Expand All @@ -21,22 +23,24 @@ namespace weapons
vector<int> weaplist;
void buildweaplist(const char *str)
{
vector<char *> list;
std::vector<std::string> list;
explodelist(str, list);
weaplist.shrink(0);
loopv(list)
{
int weap = -1;
if(isnumeric(list[i][0])) weap = atoi(list[i]);
else loopj(W_ALL) if(!strcasecmp(weaptype[j].name, list[i]))
if(isnumeric(list[i][0]))
{
weap = atoi(list[i].c_str());
}
else loopj(W_ALL) if(!strcasecmp(weaptype[j].name, list[i].c_str()))
{
weap = j;
break;
}
if(isweap(weap) && weaplist.find(weap) < 0)
weaplist.add(weap);
}
list.deletearrays();
loopi(W_ALL) if(weaplist.find(i) < 0) weaplist.add(i); // make sure all weapons have a slot
changedkeys = lastmillis;
}
Expand Down
15 changes: 15 additions & 0 deletions src/shared/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define COMMAND_H
// script binding functionality

#include <vector>
#include <string>
enum { VAL_NULL = 0, VAL_INT, VAL_FLOAT, VAL_STR, VAL_ANY, VAL_CODE, VAL_MACRO, VAL_IDENT };

enum
Expand Down Expand Up @@ -348,7 +350,20 @@ extern const char *escapeid(const char *s);
static inline const char *escapeid(ident &id) { return escapeid(id.name); }
extern bool validateblock(const char *s);
extern char *parsetext(const char *&p);

/**
* \brief explodes a string according to some unclear syntax rules
*
* this *may* be used as a tokenizer, somehow
*
* \s[in] C string to explode.
* \elems[in,out] result. Is *not* cleared before filling.
* \limit[in] is the maximum number of elements to add.
* \deprecated use the new, safer std::vector implementation for new and modified code
*/
extern void explodelist(const char *s, vector<char *> &elems, int limit = -1);
extern void explodelist(const char *s, std::vector<std::string> &elems, int limit = -1);

extern int listlen(const char *s);
extern char *indexlist(const char *s, int pos);
extern const char *indexlist(const char *s, int pos, int &len);
Expand Down

0 comments on commit 60da7b1

Please sign in to comment.