- Fixed: The C code in AltSoundRenderer::CopyAndClip() did not shift the sample

data enough (2 bits instead of 8), so it was super loud and aliased.
- Fixes for GCC 4.1: Several type-punned pointer warnings, but more
  importantly, declaring a friend function inside a class body is no longer
  enough to declare that function globally; you must declare it again outside
  the class.
- Upgraded FArchive::SerializePointer so that it can store 32-bit indices.
- ACS printing pcodes now build their string in an FSttring instead of a fixed
  sized buffer on the stack.


SVN r145 (trunk)
This commit is contained in:
Randy Heit 2006-05-26 04:38:22 +00:00
parent 43abfba723
commit 90b5130db0
29 changed files with 327 additions and 269 deletions

View file

@ -23,24 +23,14 @@ CXXFLAGS = $(LOC) $(DEFINES) -O2 -Wall
NASM = nasmw
NASMFLAGS = -d OBJ_FORMAT_win32 -f win32
LD = $(CC)
LDFLAGS = $(LOC) -s
AR = ar
ARFLAGS = rcs
RC = windres
RCFLAGS = --define GCC_WINDRES
OBJS = cpu_asm.o fixed_asm.o lpc_asm.o \
bitbuffer.o bitmath.o cpu.o crc.o fixed.o format.o lpc.o memory.o stream_decoder.o stream_decoder_pp.o
all: $(STATICLIB)
test: example minigzip
./example
echo hello world | minigzip | minigzip -d
.c.o:
$(CCDV) $(CC) $(CFLAGS) -c -o $@ $<
@ -63,7 +53,7 @@ fixed_asm.o: ia32/fixed_asm.nasm
$(CCDV) $(NASM) -o $@ $(NASMFLAGS) $<
lpc_asm.o: ia32/lpc_asm.nasm
$(CCDV) $(NASM) -o $@ $(NASMFLAGS) $<
butbuffer.o: bitbuffer.c
bitbuffer.o: bitbuffer.c
bitmath.o: bitmath.c
cpu.o: cpu.c
crc.o: crc.c

View file

@ -46,6 +46,8 @@ ifdef FMODDIR
LDFLAGS += -L$(FMODDIR)/api/lib
endif
CFLAGS += -fno-strict-aliasing
ifeq ($(CONFIG),Debug)
OBJDIR = $(DEBUGOBJDIR)
CFLAGS += $(CPPFLAGS) -Wall -Wno-unused -g3

View file

@ -89,15 +89,11 @@ static void DumpFormattedOutput()
return;
}
spaces[0] = ' ';
spaces[1] = ' ';
spaces[2] = ' ';
spaces[3] = ' ';
spaces[4] = ' ';
spaces[5] = ' ';
spaces[6] = ' ';
spaces[7] = ' ';
spaces[8] = '\0';
for(i = 0; i < 8; ++i)
{
spaces[i] = ' ';
}
spaces[i] = '\0';
color = info.wAttributes & ~(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
curcol = 0;
@ -473,8 +469,11 @@ void mainCRTStartup(void)
}
else if((extlen == 2 &&
(lstrcmpi(gAction+8, "cc") == 0 ||
lstrcmpi(gAction+8, "cl") == 0)) ||
(extlen == 3 && lstrcmpi(gAction+8, "gcc") == 0))
lstrcmpi(gAction+8, "cl") == 0 ||
lstrcmpi(gAction+8, "ld") == 0)) ||
(extlen == 3 &&
(lstrcmpi(gAction+8, "gcc") == 0 ||
lstrcmpi(gAction+8, "g++") == 0)))
{
gcc = 1;
}
@ -522,7 +521,9 @@ void mainCRTStartup(void)
{
yy++;
}
else if(CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ".nas", 4, ext, -1) == CSTR_EQUAL)
else if((ext[0] == '.' && ext[1] == 'n' && ext[2] == 'a' && ext[3] == 's') ||
(ext[0] == '.' && ext[1] == 'a' && ext[2] == 's' && ext[3] == 'm') ||
(ext[0] == '.' && ext[1] == 's'))
{
lstrcpy(gAction, "Assembling");
SetTarget(&gTarget, arg, arglen);

View file

@ -1,6 +1,17 @@
May 25, 2006
- Fixed: The C code in AltSoundRenderer::CopyAndClip() did not shift the sample
data enough (2 bits instead of 8), so it was super loud and aliased.
- Fixes for GCC 4.1: Several type-punned pointer warnings, but more
importantly, declaring a friend function inside a class body is no longer
enough to declare that function globally; you must declare it again outside
the class.
- Upgraded FArchive::SerializePointer so that it can store 32-bit indices.
- ACS printing pcodes now build their string in an FSttring instead of a fixed
sized buffer on the stack.
May 24, 2006
- Modified ccdv-win32 to show "Generating X" messages when running lemon and
re2c.
re2c instead of "Linking X".
- Updated lemon and re2c to the latest versions and ported dehsupp to use them
for code generation. (Xlatcc is next.)
- Added function level linking for Makefile.mingw.

View file

@ -137,7 +137,7 @@ bool DCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle)
if (vangle == 0)
return false; //Looker seems to be blind.
return abs (R_PointToAngle2 (from->x, from->y, to->x, to->y) - from->angle) <= vangle/2;
return (angle_t)abs (R_PointToAngle2 (from->x, from->y, to->x, to->y) - from->angle) <= vangle/2;
}
//-------------------------------------

View file

@ -354,7 +354,8 @@ bool DCajunMaster::SpawnBot (const char *name, int color)
void DCajunMaster::DoAddBot (int bnum, char *info)
{
D_ReadUserInfoStrings (bnum, (byte **)&info, false);
byte *infob = (byte *)info;
D_ReadUserInfoStrings (bnum, &infob, false);
if (!deathmatch && playerstarts[bnum].type == 0)
{
Printf ("%s tried to join, but there was no player %d start\n",

View file

@ -73,8 +73,13 @@ int ReadLong (byte **stream)
float ReadFloat (byte **stream)
{
int fakeint = ReadLong (stream);
return *((float *)&fakeint);
union
{
int i;
float f;
} fakeint;
fakeint.i = ReadLong (stream);
return fakeint.f;
}
void WriteString (const char *string, byte **stream)
@ -114,7 +119,13 @@ void WriteLong (int v, byte **stream)
void WriteFloat (float v, byte **stream)
{
WriteLong (*((int *)&v), stream);
union
{
int i;
float f;
} fakeint;
fakeint.f = v;
WriteLong (fakeint.i, stream);
}
// Returns the number of bytes read

View file

@ -969,31 +969,30 @@ FArchive &FArchive::operator<< (FName &n)
FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize)
{
WORD w;
DWORD w;
if (m_Storing)
{
if (*ptr)
if (*(void **)ptr)
{
w = SWAP_WORD((*ptr - (byte *)ptrbase) / elemSize);
w = DWORD(((size_t)*ptr - (size_t)ptrbase) / elemSize);
}
else
{
w = 0xffff;
w = ~0u;
}
Write (&w, sizeof(WORD));
WriteCount (w);
}
else
{
Read (&w, sizeof(WORD));
w = SWAP_WORD (w);
if (w != 0xffff)
w = ReadCount ();
if (w != ~0u)
{
*ptr = (byte *)ptrbase + w * elemSize;
*(void **)ptr = (byte *)ptrbase + w * elemSize;
}
else
{
*ptr = NULL;
*(void **)ptr = NULL;
}
}
return *this;

View file

@ -1708,7 +1708,7 @@ void G_DoLoadGame ()
}
G_ReadSnapshots (png);
P_ReadRNGState (png);
FRandom::StaticReadRNGState (png);
P_ReadACSDefereds (png);
// load a base level
@ -2024,7 +2024,7 @@ void G_DoSaveGame (bool okForQuicksave)
}
G_WriteSnapshots (stdfile);
P_WriteRNGState (stdfile);
FRandom::StaticWriteRNGState (stdfile);
P_WriteACSDefereds (stdfile);
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));

View file

@ -38,6 +38,9 @@ private:
const PClass *Weapons[MAX_WEAPONS_PER_SLOT];
};
AWeapon *PickNextWeapon (player_s *player);
AWeapon *PickPrevWeapon (player_s *player);
// FWeaponSlots::AddDefaultWeapon return codes
enum ESlotDef
{

View file

@ -46,16 +46,21 @@ void ASectorAction::Destroy ()
{
// Remove ourself from this sector's list of actions
AActor *probe = Sector->SecActTarget;
AActor **prev = reinterpret_cast<AActor **>(&Sector->SecActTarget);
union
{
AActor **act;
ASectorAction **secact;
} prev;
prev.secact = &Sector->SecActTarget;
while (probe && probe != this)
{
prev = &probe->tracer;
prev.act = &probe->tracer;
probe = probe->tracer;
}
if (probe != NULL)
{
*prev = probe->tracer;
*prev.act = probe->tracer;
}
Super::Destroy ();

View file

@ -199,7 +199,7 @@ DWORD FRandom::StaticSumSeeds ()
return pr_spawnmobj.Seed + pr_acs.Seed + pr_chase.Seed + pr_lost.Seed + pr_slam.Seed;
}
void P_WriteRNGState (FILE *file)
void FRandom::StaticWriteRNGState (FILE *file)
{
FRandom *rng;
const DWORD seed = rngseed*2+1;
@ -217,7 +217,7 @@ void P_WriteRNGState (FILE *file)
}
}
void P_ReadRNGState (PNGHandle *png)
void FRandom::StaticReadRNGState (PNGHandle *png)
{
FRandom *rng;

View file

@ -75,6 +75,8 @@ public:
static void StaticClearRandom ();
static DWORD StaticSumSeeds ();
static void StaticReadRNGState (PNGHandle *png);
static void StaticWriteRNGState (FILE *file);
#ifdef _DEBUG
static void StaticPrintSeeds ();
@ -90,9 +92,6 @@ private:
#endif
static FRandom *RNGList;
friend void P_ReadRNGState (PNGHandle *png);
friend void P_WriteRNGState (FILE *file);
};
extern DWORD rngseed; // The starting seed (not part of state)

View file

@ -2125,7 +2125,8 @@ int DLevelScript::RunScript ()
ACSFormat fmt = activeBehavior->GetFormat();
int runaway = 0; // used to prevent infinite loops
int pcd;
char workreal[4096], *const work = workreal+2, *workwhere = work;
//char workreal[4096], *const work = workreal+2, *workwhere = work;
FString work;
const char *lookup;
int optstart = -1;
int temp;
@ -2348,6 +2349,11 @@ int DLevelScript::RunScript ()
case PCD_CALL:
case PCD_CALLDISCARD:
{
union
{
CallReturn *ret;
SDWORD *retsp;
};
int funcnum;
int i;
ScriptFunction *func;
@ -2377,11 +2383,12 @@ int DLevelScript::RunScript ()
Stack[sp+i] = 0;
}
sp += i;
((CallReturn *)&Stack[sp])->ReturnAddress = activeBehavior->PC2Ofs (pc);
((CallReturn *)&Stack[sp])->ReturnFunction = activeFunction;
((CallReturn *)&Stack[sp])->ReturnModule = activeBehavior;
((CallReturn *)&Stack[sp])->ReturnLocals = mylocals;
((CallReturn *)&Stack[sp])->bDiscardResult = (pcd == PCD_CALLDISCARD);
retsp = &Stack[sp];
ret->ReturnAddress = activeBehavior->PC2Ofs (pc);
ret->ReturnFunction = activeFunction;
ret->ReturnModule = activeBehavior;
ret->ReturnLocals = mylocals;
ret->bDiscardResult = (pcd == PCD_CALLDISCARD);
sp += sizeof(CallReturn)/sizeof(int);
pc = module->Ofs2PC (func->Address);
activeFunction = func;
@ -2394,7 +2401,11 @@ int DLevelScript::RunScript ()
case PCD_RETURNVAL:
{
int value;
union
{
SDWORD *retsp;
CallReturn *retState;
};
if (pcd == PCD_RETURNVAL)
{
@ -2405,7 +2416,7 @@ int DLevelScript::RunScript ()
value = 0;
}
sp -= sizeof(CallReturn)/sizeof(int);
retState = (CallReturn *)&Stack[sp];
retsp = &Stack[sp];
sp = locals - Stack;
pc = retState->ReturnModule->Ofs2PC (retState->ReturnAddress);
activeFunction = retState->ReturnFunction;
@ -3201,8 +3212,7 @@ int DLevelScript::RunScript ()
break;
case PCD_BEGINPRINT:
workwhere = work;
work[0] = 0;
work = "";
break;
case PCD_PRINTSTRING:
@ -3214,25 +3224,23 @@ int DLevelScript::RunScript ()
}
if (lookup != NULL)
{
workwhere += sprintf (workwhere, "%s", lookup);
work += lookup;
}
--sp;
break;
case PCD_PRINTNUMBER:
workwhere += sprintf (workwhere, "%ld", STACK(1));
work.AppendFormat ("%ld", STACK(1));
--sp;
break;
case PCD_PRINTCHARACTER:
workwhere[0] = STACK(1);
workwhere[1] = 0;
workwhere++;
work += (char)STACK(1);
--sp;
break;
case PCD_PRINTFIXED:
workwhere += sprintf (workwhere, "%g", FIXED2FLOAT(STACK(1)));
work.AppendFormat ("%g", FIXED2FLOAT(STACK(1)));
--sp;
break;
@ -3255,21 +3263,21 @@ int DLevelScript::RunScript ()
}
else
{
workwhere += sprintf (workwhere, "Player %ld", STACK(1));
work.AppendFormat ("Player %ld", STACK(1));
sp--;
break;
}
if (player)
{
workwhere += sprintf (workwhere, "%s", player->userinfo.netname);
work += player->userinfo.netname;
}
else if (activator)
{
workwhere += sprintf (workwhere, "%s", RUNTIME_TYPE(activator)->TypeName.GetChars());
work += RUNTIME_TYPE(activator)->TypeName.GetChars();
}
else
{
workwhere += sprintf (workwhere, " ");
work += ' ';
}
sp--;
}
@ -3280,8 +3288,9 @@ int DLevelScript::RunScript ()
{
int a = *(activeBehavior->MapVars[STACK(1)]);
int offset = STACK(2);
while((workwhere[0] = activeBehavior->GetArrayVal (a, offset)) != '\0') {
workwhere++;
int c;
while((c = activeBehavior->GetArrayVal (a, offset)) != '\0') {
work += (char)c;
offset++;
}
sp-=2;
@ -3293,8 +3302,9 @@ int DLevelScript::RunScript ()
{
int a = STACK(1);
int offset = STACK(2);
while((workwhere[0] = ACS_WorldArrays[a].GetVal (offset)) != '\0') {
workwhere++;
int c;
while((c = ACS_WorldArrays[a].GetVal (offset)) != '\0') {
work += (char)c;
offset++;
}
sp-=2;
@ -3306,8 +3316,9 @@ int DLevelScript::RunScript ()
{
int a = STACK(1);
int offset = STACK(2);
while((workwhere[0] = ACS_GlobalArrays[a].GetVal (offset)) != '\0') {
workwhere++;
int c;
while((c = ACS_GlobalArrays[a].GetVal (offset)) != '\0') {
work += (char)c;
offset++;
}
sp-=2;
@ -3318,10 +3329,12 @@ int DLevelScript::RunScript ()
case PCD_ENDPRINTBOLD:
case PCD_MOREHUDMESSAGE:
case PCD_ENDLOG:
strbin (work);
strbin (work.LockBuffer());
work.Truncate ((long)strlen(work));
work.UnlockBuffer();
if (pcd == PCD_ENDLOG)
{
Printf ("%s\n", work);
Printf ("%s\n", work.GetChars());
}
else if (pcd != PCD_MOREHUDMESSAGE)
{
@ -3409,16 +3422,19 @@ int DLevelScript::RunScript ()
static const char bar[] = TEXTCOLOR_ORANGE "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
"\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_NORMAL "\n";
static const char logbar[] = "\n<------------------------------->\n";
char consolecolor[3];
workreal[0] = '\x1c';
workreal[1] = color >= CR_BRICK && color <= CR_YELLOW ? color + 'A' : '-';
consolecolor[0] = '\x1c';
consolecolor[1] = color >= CR_BRICK && color <= CR_YELLOW ? color + 'A' : '-';
consolecolor[2] = '\0';
AddToConsole (-1, bar);
AddToConsole (-1, workreal);
AddToConsole (-1, consolecolor);
AddToConsole (-1, work);
AddToConsole (-1, bar);
if (Logfile)
{
fputs (logbar, Logfile);
fputs (workreal, Logfile);
fputs (work, Logfile);
fputs (logbar, Logfile);
fflush (Logfile);
}

View file

@ -394,18 +394,24 @@ protected:
friend void ThrustMobj (AActor *actor, seg_t *seg, polyobj_t *po);
};
void ThrustMobj (AActor *actor, seg_t *seg, polyobj_t *po);
class DRotatePoly : public DPolyAction
{
DECLARE_CLASS (DRotatePoly, DPolyAction)
public:
DRotatePoly (int polyNum);
void Tick ();
protected:
friend bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, BOOL overRide);
private:
DRotatePoly ();
friend bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, BOOL overRide);
};
bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, BOOL overRide);
bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, BOOL overRide);
class DMovePoly : public DPolyAction
{
DECLARE_CLASS (DMovePoly, DPolyAction)
@ -422,6 +428,8 @@ protected:
friend bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, BOOL overRide);
};
bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, BOOL overRide);
class DPolyDoor : public DMovePoly
{
DECLARE_CLASS (DPolyDoor, DMovePoly)
@ -442,6 +450,8 @@ private:
DPolyDoor ();
};
bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type);
// [RH] Data structure for P_SpawnMapThing() to keep track
// of polyobject-related things.
typedef struct polyspawns_s

View file

@ -138,6 +138,8 @@ protected:
friend BOOL PIT_PushThing (AActor *thing);
};
BOOL PIT_PushThing (AActor *thing);
inline FArchive &operator<< (FArchive &arc, DPusher::EPusher &type)
{
BYTE val = (BYTE)type;
@ -448,6 +450,11 @@ private:
friend void P_ActivateInStasis (int tag);
};
bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type,
int height, int speed, int delay, int lip, int change);
void EV_StopPlat (int tag);
void P_ActivateInStasis (int tag);
inline FArchive &operator<< (FArchive &arc, DPlat::EPlatType &type)
{
BYTE val = (BYTE)type;
@ -559,6 +566,12 @@ private:
};
bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
int tag, int speed, int delay, int lock,
int lightTag);
void P_SpawnDoorCloseIn30 (sector_t *sec);
void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor &type)
{
BYTE val = (BYTE)type;
@ -611,6 +624,8 @@ private:
DAnimatedDoor ();
};
bool EV_SlidingDoor (line_t *line, AActor *thing, int tag, int speed, int delay);
//
// P_CEILNG
//
@ -687,6 +702,12 @@ private:
friend void P_ActivateInStasisCeiling (int tag);
};
bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
int tag, fixed_t speed, fixed_t speed2, fixed_t height,
int crush, int silent, int change);
bool EV_CeilingCrushStop (int tag);
void P_ActivateInStasisCeiling (int tag);
inline FArchive &operator<< (FArchive &arc, DCeiling::ECeiling &type)
{
BYTE val = (BYTE)type;
@ -785,6 +806,14 @@ private:
DFloor ();
};
bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials);
bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change);
bool EV_FloorCrushStop (int tag);
bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed);
inline FArchive &operator<< (FArchive &arc, DFloor::EFloor &type)
{
BYTE val = (BYTE)type;
@ -827,6 +856,9 @@ private:
DElevator ();
};
bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed,
fixed_t height, int tag);
inline FArchive &operator<< (FArchive &arc, DElevator::EElevator &type)
{
BYTE val = (BYTE)type;
@ -860,6 +892,9 @@ protected:
DWaggleBase ();
};
bool EV_StartWaggle (int tag, int height, int speed,
int offset, int timer, bool ceiling);
class DFloorWaggle : public DWaggleBase
{
DECLARE_CLASS (DFloorWaggle, DWaggleBase)

View file

@ -234,7 +234,11 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
{
FTexture *out = NULL;
enum { t_patch, t_raw, t_imgz, t_png } type = t_patch;
DWORD first4bytes=0;
union
{
DWORD dw;
WORD w[2];
} first4bytes;
// Must check the length of the lump. Zero length flat markers (F1_START etc.) will come through here.
// 13 is the minimum length of andthing valid (i.e a 1x1 pixel Doom patch.)
@ -246,12 +250,12 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
{
FWadLump data = Wads.OpenLumpNum (lumpnum);
data >> first4bytes;
if (first4bytes == MAKE_ID('I','M','G','Z'))
data >> first4bytes.dw;
if (first4bytes.dw == MAKE_ID('I','M','G','Z'))
{
type = t_imgz;
}
else if (first4bytes == MAKE_ID(137,'P','N','G'))
else if (first4bytes.dw == MAKE_ID(137,'P','N','G'))
{
DWORD width, height;
BYTE bitdepth, colortype, compression, filter, interlace;
@ -259,12 +263,12 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
// This is most likely a PNG, but make sure. (Note that if the
// first 4 bytes match, but later bytes don't, we assume it's
// a corrupt PNG.)
data >> first4bytes;
if (first4bytes != MAKE_ID(13,10,26,10)) return -1;
data >> first4bytes;
if (first4bytes != MAKE_ID(0,0,0,13)) return -1;
data >> first4bytes;
if (first4bytes != MAKE_ID('I','H','D','R')) return -1;
data >> first4bytes.dw;
if (first4bytes.dw != MAKE_ID(13,10,26,10)) return -1;
data >> first4bytes.dw;
if (first4bytes.dw != MAKE_ID(0,0,0,13)) return -1;
data >> first4bytes.dw;
if (first4bytes.dw != MAKE_ID('I','H','D','R')) return -1;
// The PNG looks valid so far. Check the IHDR to make sure it's a
// type of PNG we support.
@ -282,11 +286,11 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
// Just for completeness, make sure the PNG has something more than an
// IHDR.
data >> first4bytes >> first4bytes;
if (first4bytes == 0)
data >> first4bytes.dw >> first4bytes.dw;
if (first4bytes.dw == 0)
{
data >> first4bytes;
if (first4bytes == MAKE_ID('I','E','N','D'))
data >> first4bytes.dw;
if (first4bytes.dw == MAKE_ID('I','E','N','D'))
{
return -1;
}
@ -369,8 +373,8 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
{
default:
{ // Check patch sizes for sanity
WORD width = LittleShort(*(WORD *)&first4bytes);
WORD height = LittleShort(*((WORD *)&first4bytes + 1));
WORD width = LittleShort(first4bytes.w[0]);
WORD height = LittleShort(first4bytes.w[1]);
if (width <= 2048 && height <= 2048)
{

View file

@ -68,6 +68,8 @@ private:
friend void SN_StopAllSequences (void);
};
void SN_StopAllSequences (void);
struct FSoundSequence
{
FName SeqName;

View file

@ -102,8 +102,11 @@ void SC_Open (const char *name)
void SC_OpenFile (const char *name)
{
byte *filebuf;
SC_Close ();
ScriptSize = M_ReadFile (name, (byte **)&ScriptBuffer);
ScriptSize = M_ReadFile (name, &filebuf);
ScriptBuffer = (char *)filebuf;
ScriptName = name; // This is used for error messages so the full file name is preferable
//ExtractFileBase (name, ScriptName);
FreeScript = true;

View file

@ -1036,7 +1036,7 @@ looper: mov eax, [esi+ecx*8]
#endif
for (; count; --count)
{
SDWORD val = *from++ >> 2;
SDWORD val = *from++ >> 8;
if (val > 32767)
{
val = 32767;

View file

@ -937,22 +937,17 @@ void V_Init (void)
void V_Shutdown()
{
FreeCanvasChain();
if (screen != NULL)
{
delete screen;
screen = NULL;
}
while (FFont::FirstFont != NULL)
{
delete FFont::FirstFont;
}
}
void FreeCanvasChain ()
{
if (screen != NULL)
{
delete screen;
}
screen = NULL;
}
EXTERN_CVAR (Bool, vid_tft)
// Tries to guess the physical dimensions of the screen based on the

View file

@ -187,8 +187,6 @@ private:
// Keep track of canvases, for automatic destruction at exit
DCanvas *Next;
static DCanvas *CanvasChain;
friend void FreeCanvasChain ();
};
// A canvas in system memory.

View file

@ -1745,20 +1745,20 @@ static void MouseRead_DI ()
/* Look at the element to see what happened */
// GCC does not like putting the DIMOFS_ macros in case statements,
// so use ifs instead.
if (od.dwOfs == DIMOFS_X)
if (od.dwOfs == (DWORD)DIMOFS_X)
{
dx += od.dwData;
}
else if (od.dwOfs == DIMOFS_Y)
else if (od.dwOfs == (DWORD)DIMOFS_Y)
{
dy += od.dwData;
}
else if (od.dwOfs == DIMOFS_Z)
else if (od.dwOfs == (DWORD)DIMOFS_Z)
{
WheelMove += od.dwData;
WheelMoved ();
}
else if (od.dwOfs >= DIMOFS_BUTTON0 && od.dwOfs <= DIMOFS_BUTTON7)
else if (od.dwOfs >= (DWORD)DIMOFS_BUTTON0 && od.dwOfs <= (DWORD)DIMOFS_BUTTON7)
{
/* [RH] Mouse button events mimic keydown/up events */
if (!GUICapture)

View file

@ -509,25 +509,29 @@ namespace StringFormat
#define FP_EXPONENT_MASK (2047llu<<52)
#define FP_FRACTION_MASK ((1llu<<52)-1)
#endif
double number = va_arg (arglist, double);
union
{
double d;
uint64_t i64;
} number;
number.d = va_arg (arglist, double);
if (precision < 0) precision = 6;
flags |= F_SIGNED;
int64arg = *(uint64_t*)&number;
if ((int64arg & FP_EXPONENT_MASK) == FP_EXPONENT_MASK)
if ((number.i64 & FP_EXPONENT_MASK) == FP_EXPONENT_MASK)
{
if (int64arg & FP_SIGN_MASK)
if (number.i64 & FP_SIGN_MASK)
{
flags |= F_NEGATIVE;
}
if ((int64arg & FP_FRACTION_MASK) == 0)
if ((number.i64 & FP_FRACTION_MASK) == 0)
{
obuff = "Infinity";
bufflen = 8;
}
else if ((int64arg & ((FP_FRACTION_MASK+1)>>1)) == 0)
else if ((number.i64 & ((FP_FRACTION_MASK+1)>>1)) == 0)
{
obuff = "NaN";
bufflen = 3;
@ -542,7 +546,7 @@ namespace StringFormat
// Converting a binary floating point number to an ASCII decimal
// representation is non-trivial, so I'm not going to do it myself.
// (At least for now.)
len += fmt_fp (output, outputData, flags, precision, width, number, type);
len += fmt_fp (output, outputData, flags, precision, width, number.d, type);
continue;
}
}

View file

@ -194,6 +194,14 @@ void FString::Format (const char *fmt, ...)
va_end (arglist);
}
void FString::AppendFormat (const char *fmt, ...)
{
va_list arglist;
va_start (arglist, fmt);
StringFormat::VWorker (FormatHelper, this, fmt, arglist);
va_end (arglist);
}
void FString::VFormat (const char *fmt, va_list arglist)
{
Data()->Release();
@ -201,6 +209,11 @@ void FString::VFormat (const char *fmt, va_list arglist)
StringFormat::VWorker (FormatHelper, this, fmt, arglist);
}
void FString::VAppendFormat (const char *fmt, va_list arglist)
{
StringFormat::VWorker (FormatHelper, this, fmt, arglist);
}
int FString::FormatHelper (void *data, const char *cstr, int len)
{
FString *str = (FString *)data;

View file

@ -166,7 +166,9 @@ public:
void Substitute (const char *oldstr, const char *newstr, size_t oldstrlen, size_t newstrlen);
void Format (const char *fmt, ...);
void AppendFormat (const char *fmt, ...);
void VFormat (const char *fmt, va_list arglist);
void VAppendFormat (const char *fmt, va_list arglist);
bool IsInt () const;
bool IsFloat () const;

View file

@ -7,12 +7,11 @@
#ifndef NDEBUG
#include <string.h>
#endif
#line 1 "parse.y"
#line 1 "..\\dehsupp\\parse.y"
#include <malloc.h>
#include "dehsupp.h"
#line 16 "parse.c"
#include "parse.h"
#line 16 "..\\dehsupp\\parse.c"
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
@ -23,42 +22,6 @@
**
** Each symbol here is a terminal symbol in the grammar.
*/
#if INTERFACE
#define OR 1
#define XOR 2
#define AND 3
#define MINUS 4
#define PLUS 5
#define MULTIPLY 6
#define DIVIDE 7
#define NEG 8
#define EOI 9
#define PRINT 10
#define LPAREN 11
#define RPAREN 12
#define COMMA 13
#define STRING 14
#define ENDL 15
#define NUM 16
#define Actions 17
#define LBRACE 18
#define RBRACE 19
#define SEMICOLON 20
#define SYM 21
#define OrgHeights 22
#define ActionList 23
#define RBARCE 24
#define CodePConv 25
#define OrgSprNames 26
#define StateMap 27
#define FirstState 28
#define SpawnState 29
#define DeathState 30
#define SoundMap 31
#define InfoNames 32
#define ThingBits 33
#define RenderStyles 34
#endif
/* Make sure the INTERFACE macro is defined.
*/
#ifndef INTERFACE
@ -100,21 +63,17 @@
#define YYCODETYPE unsigned char
#define YYNOCODE 68
#define YYACTIONTYPE unsigned char
#if INTERFACE
#define ParseTOKENTYPE struct Token
#endif
typedef union {
ParseTOKENTYPE yy0;
int yy62;
int yy135;
} YYMINORTYPE;
#define YYSTACKDEPTH 100
#if INTERFACE
#define ParseARG_SDECL
#define ParseARG_PDECL
#define ParseARG_FETCH
#define ParseARG_STORE
#endif
#define YYNSTATE 140
#define YYNRULE 77
#define YYERRORSYMBOL 35
@ -527,9 +486,9 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
case 32:
case 33:
case 34:
#line 8 "parse.y"
#line 8 "..\\dehsupp\\parse.y"
{ if ((yypminor->yy0).string) free((yypminor->yy0).string); }
#line 534 "parse.c"
#line 493 "..\\dehsupp\\parse.c"
break;
default: break; /* If no destructor action specified: do nothing */
}
@ -829,205 +788,205 @@ static void yy_reduce(
** break;
*/
case 14:
#line 37 "parse.y"
#line 37 "..\\dehsupp\\parse.y"
{
printf ("\n");
yy_destructor(10,&yymsp[-3].minor);
yy_destructor(11,&yymsp[-2].minor);
yy_destructor(12,&yymsp[0].minor);
}
#line 841 "parse.c"
#line 800 "..\\dehsupp\\parse.c"
break;
case 18:
#line 45 "parse.y"
#line 45 "..\\dehsupp\\parse.y"
{ printf ("%s", yymsp[0].minor.yy0.string); }
#line 846 "parse.c"
#line 805 "..\\dehsupp\\parse.c"
break;
case 19:
#line 46 "parse.y"
#line 46 "..\\dehsupp\\parse.y"
{ printf ("%d", yymsp[0].minor.yy62); }
#line 851 "parse.c"
#line 810 "..\\dehsupp\\parse.c"
break;
case 20:
#line 47 "parse.y"
#line 47 "..\\dehsupp\\parse.y"
{ printf ("\n"); yy_destructor(15,&yymsp[0].minor);
}
#line 857 "parse.c"
#line 816 "..\\dehsupp\\parse.c"
break;
case 21:
#line 50 "parse.y"
#line 50 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[0].minor.yy0.val; }
#line 862 "parse.c"
#line 821 "..\\dehsupp\\parse.c"
break;
case 22:
#line 51 "parse.y"
#line 51 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 + yymsp[0].minor.yy62; yy_destructor(5,&yymsp[-1].minor);
}
#line 868 "parse.c"
#line 827 "..\\dehsupp\\parse.c"
break;
case 23:
#line 52 "parse.y"
#line 52 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 - yymsp[0].minor.yy62; yy_destructor(4,&yymsp[-1].minor);
}
#line 874 "parse.c"
#line 833 "..\\dehsupp\\parse.c"
break;
case 24:
#line 53 "parse.y"
#line 53 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 * yymsp[0].minor.yy62; yy_destructor(6,&yymsp[-1].minor);
}
#line 880 "parse.c"
#line 839 "..\\dehsupp\\parse.c"
break;
case 25:
#line 54 "parse.y"
#line 54 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 / yymsp[0].minor.yy62; yy_destructor(7,&yymsp[-1].minor);
}
#line 886 "parse.c"
#line 845 "..\\dehsupp\\parse.c"
break;
case 26:
#line 55 "parse.y"
#line 55 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 | yymsp[0].minor.yy62; yy_destructor(1,&yymsp[-1].minor);
}
#line 892 "parse.c"
#line 851 "..\\dehsupp\\parse.c"
break;
case 27:
#line 56 "parse.y"
#line 56 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 & yymsp[0].minor.yy62; yy_destructor(3,&yymsp[-1].minor);
}
#line 898 "parse.c"
#line 857 "..\\dehsupp\\parse.c"
break;
case 28:
#line 57 "parse.y"
#line 57 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-2].minor.yy62 ^ yymsp[0].minor.yy62; yy_destructor(2,&yymsp[-1].minor);
}
#line 904 "parse.c"
#line 863 "..\\dehsupp\\parse.c"
break;
case 29:
#line 58 "parse.y"
#line 58 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = -yymsp[0].minor.yy62; yy_destructor(4,&yymsp[-1].minor);
}
#line 910 "parse.c"
#line 869 "..\\dehsupp\\parse.c"
break;
case 30:
#line 59 "parse.y"
#line 59 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = yymsp[-1].minor.yy62; yy_destructor(11,&yymsp[-2].minor);
yy_destructor(12,&yymsp[0].minor);
}
#line 917 "parse.c"
#line 876 "..\\dehsupp\\parse.c"
break;
case 33:
#line 65 "parse.y"
#line 65 "..\\dehsupp\\parse.y"
{ AddAction (yymsp[0].minor.yy0.string); }
#line 922 "parse.c"
#line 881 "..\\dehsupp\\parse.c"
break;
case 34:
#line 66 "parse.y"
#line 66 "..\\dehsupp\\parse.y"
{ AddAction (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
}
#line 928 "parse.c"
#line 887 "..\\dehsupp\\parse.c"
break;
case 37:
#line 72 "parse.y"
#line 72 "..\\dehsupp\\parse.y"
{ AddHeight (yymsp[0].minor.yy62); }
#line 933 "parse.c"
#line 892 "..\\dehsupp\\parse.c"
break;
case 38:
#line 73 "parse.y"
#line 73 "..\\dehsupp\\parse.y"
{ AddHeight (yymsp[0].minor.yy62); yy_destructor(13,&yymsp[-1].minor);
}
#line 939 "parse.c"
#line 898 "..\\dehsupp\\parse.c"
break;
case 41:
#line 79 "parse.y"
#line 79 "..\\dehsupp\\parse.y"
{ AddActionMap (yymsp[0].minor.yy0.string); }
#line 944 "parse.c"
#line 903 "..\\dehsupp\\parse.c"
break;
case 42:
#line 80 "parse.y"
#line 80 "..\\dehsupp\\parse.y"
{ AddActionMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
}
#line 950 "parse.c"
#line 909 "..\\dehsupp\\parse.c"
break;
case 45:
#line 86 "parse.y"
#line 86 "..\\dehsupp\\parse.y"
{ AddCodeP (yymsp[0].minor.yy62); }
#line 955 "parse.c"
#line 914 "..\\dehsupp\\parse.c"
break;
case 46:
#line 87 "parse.y"
#line 87 "..\\dehsupp\\parse.y"
{ AddCodeP (yymsp[0].minor.yy62); yy_destructor(13,&yymsp[-1].minor);
}
#line 961 "parse.c"
#line 920 "..\\dehsupp\\parse.c"
break;
case 49:
#line 93 "parse.y"
#line 93 "..\\dehsupp\\parse.y"
{ AddSpriteName (yymsp[0].minor.yy0.string); }
#line 966 "parse.c"
#line 925 "..\\dehsupp\\parse.c"
break;
case 50:
#line 94 "parse.y"
#line 94 "..\\dehsupp\\parse.y"
{ AddSpriteName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
}
#line 972 "parse.c"
#line 931 "..\\dehsupp\\parse.c"
break;
case 55:
#line 103 "parse.y"
#line 103 "..\\dehsupp\\parse.y"
{ AddStateMap (yymsp[-4].minor.yy0.string, yymsp[-2].minor.yy62, yymsp[0].minor.yy62); yy_destructor(13,&yymsp[-3].minor);
yy_destructor(13,&yymsp[-1].minor);
}
#line 979 "parse.c"
#line 938 "..\\dehsupp\\parse.c"
break;
case 56:
#line 106 "parse.y"
#line 106 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = 0; yy_destructor(28,&yymsp[0].minor);
}
#line 985 "parse.c"
#line 944 "..\\dehsupp\\parse.c"
break;
case 57:
#line 107 "parse.y"
#line 107 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = 1; yy_destructor(29,&yymsp[0].minor);
}
#line 991 "parse.c"
#line 950 "..\\dehsupp\\parse.c"
break;
case 58:
#line 108 "parse.y"
#line 108 "..\\dehsupp\\parse.y"
{ yygotominor.yy62 = 2; yy_destructor(30,&yymsp[0].minor);
}
#line 997 "parse.c"
#line 956 "..\\dehsupp\\parse.c"
break;
case 61:
#line 114 "parse.y"
#line 114 "..\\dehsupp\\parse.y"
{ AddSoundMap (yymsp[0].minor.yy0.string); }
#line 1002 "parse.c"
#line 961 "..\\dehsupp\\parse.c"
break;
case 62:
#line 115 "parse.y"
#line 115 "..\\dehsupp\\parse.y"
{ AddSoundMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
}
#line 1008 "parse.c"
#line 967 "..\\dehsupp\\parse.c"
break;
case 65:
#line 121 "parse.y"
#line 121 "..\\dehsupp\\parse.y"
{ AddInfoName (yymsp[0].minor.yy0.string); }
#line 1013 "parse.c"
#line 972 "..\\dehsupp\\parse.c"
break;
case 66:
#line 122 "parse.y"
#line 122 "..\\dehsupp\\parse.y"
{ AddInfoName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
}
#line 1019 "parse.c"
#line 978 "..\\dehsupp\\parse.c"
break;
case 71:
#line 131 "parse.y"
#line 131 "..\\dehsupp\\parse.y"
{ AddThingBits (yymsp[0].minor.yy0.string, yymsp[-4].minor.yy62, yymsp[-2].minor.yy62); yy_destructor(13,&yymsp[-3].minor);
yy_destructor(13,&yymsp[-1].minor);
}
#line 1026 "parse.c"
#line 985 "..\\dehsupp\\parse.c"
break;
case 76:
#line 140 "parse.y"
#line 140 "..\\dehsupp\\parse.y"
{ AddRenderStyle (yymsp[0].minor.yy0.string, yymsp[-2].minor.yy62); yy_destructor(13,&yymsp[-1].minor);
}
#line 1032 "parse.c"
#line 991 "..\\dehsupp\\parse.c"
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;

View file

@ -27,7 +27,7 @@
#define MAXRHS 1000
#endif
char *msort();
void *msort(void *list, void *next, int (*cmp)());
/******** From the file "action.h" *************************************/
struct action *Action_new();
@ -370,7 +370,7 @@ struct action *ap2;
struct action *Action_sort(ap)
struct action *ap;
{
ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp);
ap = (struct action *)msort(ap,&ap->next,actioncmp);
return ap;
}
@ -1228,14 +1228,14 @@ struct lemon *lemp;
/* Sort the configuration list */
void Configlist_sort(){
current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp);
current = (struct config *)msort(current,&(current->next),Configcmp);
currentend = 0;
return;
}
/* Sort the basis configuration list */
void Configlist_sortbasis(){
basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp);
basis = (struct config *)msort(current,&(current->bp),Configcmp);
basisend = 0;
return;
}
@ -1315,9 +1315,9 @@ int max;
void ErrorMsg(const char *filename, int lineno, const char *format, ...){
char errmsg[ERRMSGSIZE];
char prefix[PREFIXLIMIT+10];
int errmsgsize;
int prefixsize;
int availablewidth;
size_t errmsgsize;
size_t prefixsize;
size_t availablewidth;
va_list ap;
int end, restart, base;
@ -1559,7 +1559,7 @@ char **argv;
/*
** Return a pointer to the next structure in the linked list.
*/
#define NEXT(A) (*(char**)(((unsigned long)A)+offset))
#define NEXT(A) (*(void**)(((size_t)A)+offset))
/*
** Inputs:
@ -1576,11 +1576,7 @@ char **argv;
** The "next" pointers for elements in the lists a and b are
** changed.
*/
static char *merge(a,b,cmp,offset)
char *a;
char *b;
int (*cmp)();
int offset;
static void *merge(void *a,void *b,int (*cmp)(),size_t offset)
{
char *ptr, *head;
@ -1628,16 +1624,13 @@ int offset;
** The "next" pointers for elements in list are changed.
*/
#define LISTSIZE 30
char *msort(list,next,cmp)
char *list;
char **next;
int (*cmp)();
void *msort(void *list,void *next,int (*cmp)())
{
unsigned long offset;
size_t offset;
char *ep;
char *set[LISTSIZE];
int i;
offset = (unsigned long)next - (unsigned long)list;
offset = (size_t)next - (size_t)list;
for(i=0; i<LISTSIZE; i++) set[i] = 0;
while( list ){
ep = list;
@ -1669,7 +1662,8 @@ int n;
int k;
FILE *err;
{
int spcnt, i;
int i;
size_t spcnt;
if( argv[0] ) fprintf(err,"%s",argv[0]);
spcnt = strlen(argv[0]) + 1;
for(i=1; i<n && argv[i]; i++){
@ -1787,7 +1781,7 @@ FILE *err;
if( *end ){
if( err ){
fprintf(err,"%sillegal character in floating-point argument.\n",emsg);
errline(i,((unsigned long)end)-(unsigned long)argv[i],err);
errline(i,((size_t)end)-(size_t)argv[i],err);
}
errcnt++;
}
@ -1798,7 +1792,7 @@ FILE *err;
if( *end ){
if( err ){
fprintf(err,"%sillegal character in integer argument.\n",emsg);
errline(i,((unsigned long)end)-(unsigned long)argv[i],err);
errline(i,((size_t)end)-(size_t)argv[i],err);
}
errcnt++;
}
@ -1893,7 +1887,7 @@ int n;
void OptPrint(){
int i;
int max, len;
size_t max, len;
max = 0;
for(i=0; op[i].label; i++){
len = strlen(op[i].label) + 1;
@ -2453,6 +2447,7 @@ struct lemon *gp;
char *cp, *nextcp;
int startline = 0;
memset(&ps, 0, sizeof ps);
ps.gp = gp;
ps.filename = gp->filename;
ps.errorcnt = 0;
@ -2714,7 +2709,7 @@ struct lemon *lemp;
maxlen = 10;
for(i=0; i<lemp->nsymbol; i++){
sp = lemp->symbols[i];
len = strlen(sp->name);
len = (int)strlen(sp->name);
if( len>maxlen ) maxlen = len;
}
ncolumns = 76/(maxlen+5);
@ -3158,7 +3153,7 @@ PRIVATE char *append_str(char *zText, int n, int p1, int p2, int bNoSubst){
used += n;
assert( used>=0 );
}
n = strlen(zText);
n = (int)strlen(zText);
}
if( n+sizeof(zInt)*2+used >= (size_t)alloced ){
alloced = n + sizeof(zInt)*2 + used + 200;
@ -3171,7 +3166,7 @@ PRIVATE char *append_str(char *zText, int n, int p1, int p2, int bNoSubst){
sprintf(zInt, "%d", p1);
p1 = p2;
strcpy(&z[used], zInt);
used += strlen(&z[used]);
used += (int)strlen(&z[used]);
zText++;
n--;
}else{
@ -3320,13 +3315,13 @@ int mhflag; /* True if generating makeheaders output */
for(i=0; i<arraysize; i++) types[i] = 0;
maxdtlength = 0;
if( lemp->vartype ){
maxdtlength = strlen(lemp->vartype);
maxdtlength = (int)strlen(lemp->vartype);
}
for(i=0; i<lemp->nsymbol; i++){
int len;
struct symbol *sp = lemp->symbols[i];
if( sp->datatype==0 ) continue;
len = strlen(sp->datatype);
len = (int)strlen(sp->datatype);
if( len>maxdtlength ) maxdtlength = len;
}
stddt = (char*)malloc( maxdtlength*2 + 1 );
@ -3522,7 +3517,7 @@ int mhflag; /* Output in makeheaders format if true */
}
name = lemp->name ? lemp->name : "Parse";
if( lemp->arg && lemp->arg[0] ){
int i;
size_t i;
i = strlen(lemp->arg);
while( i>=1 && isspace(lemp->arg[i-1]) ) i--;
while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;