예제 #1
0
void SendResponseMessage(const char* message, const char mode) {
    int sent_bytes, total_sent_bytes = 0;

#if !defined(WIN32)
#if defined(__APPLE__)
    int flag;
    if (mode == 1 || mode == 3) // Set TCP cork
    {
        flag = 1;
        if (setsockopt(interfaceSocket, IPPROTO_TCP, TCP_NOPUSH, (char*) & flag, sizeof (flag)) == -1) {
            fprintf(stderr, "src/socket.c: SendResponseMessage setsockopt TCP_CORK.\n");
            ExitFatal(-1);
        }
    }
#else
    int flag;
    if (mode == 1 || mode == 3) // Set TCP cork
    {
        flag = 1;
        if (setsockopt(interfaceSocket, IPPROTO_TCP, TCP_CORK, (char*) & flag, sizeof (flag)) == -1) {
            fprintf(stderr, "src/socket.c: SendResponseMessage setsockopt TCP_CORK.\n");
            ExitFatal(-1);
        }
    }
#endif
#endif

    while (total_sent_bytes < (int) strlen(message)) {
        sent_bytes = NetSendTCP(interfaceSocket, message + total_sent_bytes, strlen(message) - total_sent_bytes);
        if (sent_bytes == -1) {
            fprintf(stderr, "src/socket.cpp: unable to send bytes in SendResponseMessage().\n");
            ExitFatal(-1);
        }

        total_sent_bytes += sent_bytes;
    }

#if !defined(WIN32)
#if defined(__APPLE__)
    if (mode == 2 || mode == 3) // Unset TCP cork
    {
        flag = 0;
        if (setsockopt(interfaceSocket, IPPROTO_TCP, TCP_NOPUSH, (char*) & flag, sizeof (flag)) == -1) {
            fprintf(stderr, "src/socket.c: SendResponseMessage setsockopt TCP_CORK.\n");
            ExitFatal(-1);
        }
    }
#else
    if (mode == 2 || mode == 3) // Unset TCP cork
    {
        flag = 0;
        if (setsockopt(interfaceSocket, IPPROTO_TCP, TCP_CORK, (char*) & flag, sizeof (flag)) == -1) {
            fprintf(stderr, "src/socket.c: SendResponseMessage setsockopt TCP_CORK.\n");
            ExitFatal(-1);
        }
    }
#endif
#endif
}
예제 #2
0
/**
**  Parse flags list in animation frame.
**
**  @param unit       Unit of the animation.
**  @param parseflag  Flag list to parse.
**
**  @return The parsed value.
*/
int ParseAnimFlags(const CUnit &unit, const char *parseflag)
{
	char s[100];
	int flags = 0;

	strcpy(s, parseflag);
	char *cur = s;
	char *next = s;
	while (next && *next) {
		next = strchr(cur, '.');
		if (next) {
			*next = '\0';
			++next;
		}
		if (unit.Anim.Anim->Type == AnimationSpawnMissile) {
			if (!strcmp(cur, "none")) {
				flags = SM_None;
				return flags;
			} else if (!strcmp(cur, "damage")) {
				flags |= SM_Damage;
			} else if (!strcmp(cur, "totarget")) {
				flags |= SM_ToTarget;
			} else if (!strcmp(cur, "pixel")) {
				flags |= SM_Pixel;
			} else if (!strcmp(cur, "reltarget")) {
				flags |= SM_RelTarget;
			} else if (!strcmp(cur, "ranged")) {
				flags |= SM_Ranged;
			}  else if (!strcmp(cur, "setdirection")) {
				flags |= SM_SetDirection;
			} else {
				fprintf(stderr, "Unknown animation flag: %s\n", cur);
				ExitFatal(1);
			}
		} else if (unit.Anim.Anim->Type == AnimationSpawnUnit) {
			if (!strcmp(cur, "none")) {
				flags = SU_None;
				return flags;
			} else if (!strcmp(cur, "summoned")) {
				flags |= SU_Summoned;
			} else if (!strcmp(cur, "jointoai")) {
				flags |= SU_JoinToAIForce;
			} else {
				fprintf(stderr, "Unknown animation flag: %s\n", cur);
				ExitFatal(1);
			}
		}
		cur = next;
	}
	return flags;
}
예제 #3
0
/**
**  Load a file into a buffer
*/
static void LuaLoadBuffer(const std::string &file, std::string &buffer)
{
	CFile fp;
	int size;
	int oldsize;
	int location;
	int read;
	char *buf;

	buffer.clear();

	if (fp.open(file.c_str(), CL_OPEN_READ) == -1) {
		fprintf(stderr, "Can't open file '%s': %s\n",
			file.c_str(), strerror(errno));
		return;
	}

	size = 10000;
	buf = new char[size];
	if (!buf) {
		fprintf(stderr, "Out of memory\n");
		ExitFatal(-1);
	}
	location = 0;
	for (;;) {
		read = fp.read(&buf[location], size - location);
		if (read != size - location) {
			location += read;
			break;
		}
		location += read;
		oldsize = size;
		size = size * 2;
		char *newb = new char[size];
		if (!newb) {
			fprintf(stderr, "Out of memory\n");
			ExitFatal(-1);
		}
		memcpy(newb, buf, oldsize);
		delete[] buf;
		buf = newb;
	}
	fp.close();

	buffer.assign(buf, location);
	delete[] buf;
}
예제 #4
0
static mng_bool MNG_DECL my_processheader(mng_handle handle, mng_uint32 width,
	mng_uint32 height)
{
	Uint32 Rmask;
	Uint32 Gmask;
	Uint32 Bmask;
	mng_imgtype type;
	Mng *mng;
#ifdef USE_OPENGL
	unsigned w;
	unsigned h;
#endif

	type = mng_get_sigtype(handle);
	if (type != mng_it_mng) {
		return TRUE;
	}

	mng = (Mng *)mng_get_userdata(handle);

#ifdef USE_OPENGL
	for (w = 1; w < width; w <<= 1) {
	}
	for (h = 1; h < height; h <<= 1) {
	}
	mng->texture_width = (float)width / w;
	mng->texture_height = (float)height / h;
	glGenTextures(1, &mng->texture_name);
	glBindTexture(GL_TEXTURE_2D, mng->texture_name);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
#endif

	// Allocate the SDL surface to hold the image
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
	Rmask = 0x000000FF;
	Gmask = 0x0000FF00;
	Bmask = 0x00FF0000;
#else
	Rmask = 0xFF000000 >> 8;
	Gmask = 0x00FF0000 >> 8;
	Bmask = 0x0000FF00 >> 8;
#endif

	mng->buffer = new unsigned char[width * height * 3];
	memset(mng->buffer, width * height * 3, sizeof(unsigned char));

	mng->surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
		8 * 3, Rmask, Gmask, Bmask, 0);
	if (mng->surface == NULL) {
		fprintf(stderr, "Out of memory");
		ExitFatal(1);
	}

	return MNG_TRUE;
}
예제 #5
0
int CVideo::initialize()
{
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		fprintf(stderr, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
		ExitFatal(1);
		return 1;
	}
	mainWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, SDL_WINDOW_SHOWN);
	if (mainWindow == NULL) {
		fprintf(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError());
		ExitFatal(1);
		return 1;
	}
	surface = SDL_GetWindowSurface(mainWindow);




	return 0;
}
예제 #6
0
void exPush( TARGET *targ, DEPEND *dep, DEPEND *impDep )
/*************************************************************/
{
    if( exStackP == MAX_EXSTACK ) {
        PrtMsg( FTL | PERCENT_MAKE_DEPTH );
        ExitFatal();
    }
    exStack[exStackP].targ   = targ;
    exStack[exStackP].dep    = dep;
    exStack[exStackP].impDep = impDep;
    ++exStackP;
}
예제 #7
0
STATIC bool checkMacro( STRM_T s )
/*********************************
 * returns: true    if the line WAS a macro defn
 *          false   if it wasn't
 * recognizes:      {macc}+{ws}*"="{ws}*{defn}*"\n"
 *                  {macc}+{ws}*"+="{ws}*{defn}*"\n"
 * second gets translated from "macro += defn" to "macro=$+$(macro)$- defn"
 */
{
    char        mac[MAX_MAC_NAME];
    unsigned    pos;
    bool        ws;

    pos = 0;
    while( pos < MAX_MAC_NAME && sismacc( s ) ) {
        mac[pos++] = s;
        s = PreGetCHR();
    }
    if( pos == MAX_MAC_NAME ) {
        PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_MAC_NAME - 1 );
        ExitFatal();
        // never return
    }
    mac[pos] = NULLCHAR;
    ws = sisws( s );
    while( sisws( s ) ) {
        s = PreGetCHR();
    }
    if( s == '=' ) {
        DefMacro( mac );
        return( true );          /* go around again */
    } else if( s == '+' ) {
        s = PreGetCHR();
        if( s == '=' ) {
            InsString( ")$-", false );
            InsString( mac, false );
            InsString( "$+$(", false );
            DefMacro( mac );
            return( true );     /* go around again */
        }
        UnGetCHR( s );
        s = '+';
    }

    UnGetCHR( s );           /* not a macro line, put everything back*/
    if( ws ) {
        UnGetCHR( ' ' );
    }
    InsString( StrDupSafe( mac + 1 ), true );
    return( false );
}
예제 #8
0
STATIC TOKEN_T lexFileName( STRM_T s )
/*************************************
 * Now we need two ways of taking file names if the filename needs special
 * characters then use "filename"  this will ignore all the different
 * characters except for the quote which can be specified as \t
 */
{
    char        file[_MAX_PATH];
    unsigned    pos;

    assert( sisfilec( s ) || s == '\"' ||
       ( (Glob.compat_nmake || Glob.compat_posix) && s == SPECIAL_TMP_DOLLAR ) );

    if( s == '\"' ) {
        return( lexLongFilePathName( s, TOK_FILENAME ) );
    }

    pos = 0;
    while( pos < _MAX_PATH && (sisfilec( s ) ||
            ( s == SPECIAL_TMP_DOLLAR && (Glob.compat_nmake || Glob.compat_posix) ) ) ) {
        file[pos++] = s;
        s = PreGetCHR();
    }
    if( pos == _MAX_PATH ) {
        PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
        ExitFatal();
        // never return
    }
    file[pos] = NULLCHAR;
    UnGetCHR( s );

    /* if it is a file, we have to check last position for a ':', and
     * trim it off if it's there */
    if( pos > 1 && file[pos - 1] == ':' ) {
        file[pos - 1] = NULLCHAR;   /* trim a trailing colon */
        UnGetCHR( ':' );            /* push back the colon */
        --pos;
    }
    /*
     * try to do the trim twice because if file ends with a double colon
     * it means its a double colon explicit rule
     */
    if( pos > 1 && file[pos - 1] == ':' ) {
        file[pos - 1] = NULLCHAR;   /* trim a trailing colon */
        UnGetCHR( ':' );            /* push back the colon */
    }

    CurAttr.u.ptr = StrDupSafe( file );
    return( TOK_FILENAME );
}
예제 #9
0
STATIC TOKEN_T lexLongFilePathName( STRM_T s, TOKEN_T tok )
/**********************************************************
 * This will enable taking in of special filenames
 * it takes long file names or long path names
 */
{
    char    file[_MAX_PATH];
    int     pos;

    assert( s == '\"' );

    pos = 0;

    s = PreGetCHR();

    /* \" is considered a double quote character                         */
    /* and if a double quote is found again then we break out as the end */
    /* of the filename                                                   */
    while( pos < _MAX_PATH && s != '\"' && s != '\n' && s != STRM_END ) {
        file[pos++] = s;
        s = PreGetCHR();
        if( s == '\\' ) {
            if( pos >= _MAX_PATH ) {
                break;
            }
            s = PreGetCHR();
            if( s == '\"' ) {
                file[pos++] = s;
                s = PreGetCHR();
            } else {
                file[pos++] = '\\';
            }
        }
    }

    if( pos >= _MAX_PATH ) {
        PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
        ExitFatal();
        // never return
    }
    file[pos] = NULLCHAR;

    if( s != '\"' ) {
        UnGetCHR( s );
    }

    CurAttr.u.ptr = StrDupSafe( file );
    return( tok );
}
예제 #10
0
/**
**  Allocate an empty unit-type slot.
**
**  @param ident  Identifier to identify the slot (malloced by caller!).
**
**  @return       New allocated (zeroed) unit-type pointer.
*/
CUnitType *NewUnitTypeSlot(const std::string &ident)
{
	CUnitType *type;

	type = new CUnitType;
	if (!type) {
		fprintf(stderr, "Out of memory\n");
		ExitFatal(-1);
	}
	type->Slot = UnitTypes.size();
	type->Ident = ident;
	type->Variable = new CVariable[UnitTypeVar.NumberVariable];
	memcpy(type->Variable, UnitTypeVar.Variable,
		UnitTypeVar.NumberVariable * sizeof(*type->Variable));

	UnitTypes.push_back(type);
	UnitTypeMap[type->Ident] = type;
	return type;
}
예제 #11
0
/**
**  Load stratagus config file.
*/
void LoadCcl(void)
{
	char buf[PATH_MAX];

	//
	//  Load and evaluate configuration file
	//
	CclInConfigFile = 1;
	LibraryFileName(CclStartFile.c_str(), buf, sizeof(buf));
	if (access(buf, R_OK)) {
		fprintf(stderr, "Maybe you need to specify another gamepath with '-d /path/to/datadir'?\n");
		ExitFatal(-1);
	}

	ShowLoadProgress("Script %s\n", buf);
	LuaLoadFile(buf);
	CclInConfigFile = 0;
	CclGarbageCollect(0);  // Cleanup memory after load
}
예제 #12
0
/**
**  Allocate an empty unit-type slot.
**
**  @param ident  Identifier to identify the slot (malloced by caller!).
**
**  @return       New allocated (zeroed) unit-type pointer.
*/
CUnitType *NewUnitTypeSlot(const std::string &ident)
{
	size_t new_bool_size = UnitTypeVar.GetNumberBoolFlag();
	CUnitType *type = new CUnitType;

	if (!type) {
		fprintf(stderr, "Out of memory\n");
		ExitFatal(-1);
	}
	type->Slot = UnitTypes.size();
	type->Ident = ident;
	type->BoolFlag.resize(new_bool_size);

	type->DefaultStat.Variables = new CVariable[UnitTypeVar.GetNumberVariable()];
	for (unsigned int i = 0; i < UnitTypeVar.GetNumberVariable(); ++i) {
		type->DefaultStat.Variables[i] = UnitTypeVar.Variable[i];
	}
	UnitTypes.push_back(type);
	UnitTypeMap[type->Ident] = type;
	return type;
}
예제 #13
0
파일: game.cpp 프로젝트: k1643/StratagusAI
/**
**  Load any map.
**
**  @param filename  map filename
**  @param map       map loaded
*/
static void LoadMap(const char *filename, CMap *map)
{
	const char *tmp;

	tmp = strrchr(filename, '.');
	if (tmp) {
#ifdef USE_ZLIB
		if (!strcmp(tmp, ".gz")) {
			while (tmp - 1 > filename && *--tmp != '.') {
			}
		}
#endif
#ifdef USE_BZ2LIB
		if (!strcmp(tmp, ".bz2")) {
			while (tmp - 1 > filename && *--tmp != '.') {
			}
		}
#endif
		if (!strcmp(tmp, ".smp")
#ifdef USE_ZLIB
				|| !strcmp(tmp, ".smp.gz")
#endif
#ifdef USE_BZ2LIB
				|| !strcmp(tmp, ".smp.bz2")
#endif
		) {
			if (map->Info.Filename.empty()) {
				// The map info hasn't been loaded yet => do it now
				LoadStratagusMapInfo(filename);
			}
			Assert(!map->Info.Filename.empty());
			map->Create();
			LoadStratagusMap(filename, map->Info.Filename.c_str(), map);
			return;
		}
	}

	fprintf(stderr, "Unrecognized map format\n");
	ExitFatal(-1);
}
예제 #14
0
파일: game.cpp 프로젝트: k1643/StratagusAI
/**
**  Save a Stratagus map.
**
**  @param mapname   map filename
**  @param map       map to save
**  @param writeTerrain   write the tiles map in the .sms
*/
int SaveStratagusMap(const std::string &mapname, CMap *map, int writeTerrain)
{
	char mapsetup[PATH_MAX];
	char *extension;

	if (!map->Info.MapWidth || !map->Info.MapHeight) {
		fprintf(stderr, "%s: invalid Stratagus map\n", mapname.c_str());
		ExitFatal(-1);
	}

	strcpy_s(mapsetup, sizeof(mapsetup), mapname.c_str());
	extension = strstr(mapsetup, ".smp");
	if (!extension) {
		fprintf(stderr, "%s: invalid Statagus map filename\n", mapname.c_str());
	}
	memcpy(extension, ".sms", 4 * sizeof(char));

	if (WriteMapPresentation(mapname, map, mapsetup) == -1) {
		return -1;
	}

	return WriteMapSetup(mapsetup, map, writeTerrain);
}
예제 #15
0
/**
**  Initialize the video part for SDL.
*/
void InitVideoSdl(void)
{
	Uint32 flags;

	if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
		if (SDL_Init(
#ifdef DEBUG
				SDL_INIT_NOPARACHUTE |
#endif
				SDL_INIT_AUDIO | SDL_INIT_VIDEO |
				SDL_INIT_TIMER) < 0 ) {
			fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
			ExitFatal(1);
		}

		// Clean up on exit

		atexit(SDL_Quit);

		// If debug is enabled, Stratagus disable SDL Parachute.
		// So we need gracefully handle segfaults and aborts.
#if defined(DEBUG) && !defined(USE_WIN32)
		signal(SIGSEGV, CleanExit);
		signal(SIGABRT, CleanExit);
#endif
		// Set WindowManager Title
		SDL_WM_SetCaption("Stratagus", "Stratagus");
	}

	// Initialize the display

	flags = 0;
	// Sam said: better for windows.
	/* SDL_HWSURFACE|SDL_HWPALETTE | */
	if (Video.FullScreen) {
		flags |= SDL_FULLSCREEN;
	}
#ifdef USE_OPENGL
	flags |= SDL_OPENGL;
#endif

	if (!Video.Width || !Video.Height) {
		Video.Width = 640;
		Video.Height = 480;
	}

	TheScreen = SDL_SetVideoMode(Video.Width, Video.Height, Video.Depth, flags);
	if (TheScreen && (TheScreen->format->BitsPerPixel != 16 &&
			TheScreen->format->BitsPerPixel != 32)) {
		// Only support 16 and 32 bpp, default to 16
		TheScreen = SDL_SetVideoMode(Video.Width, Video.Height, 16, flags);
	}
	if (TheScreen == NULL) {
		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
			Video.Width, Video.Height, Video.Depth, SDL_GetError());
		ExitFatal(1);
	}

	Video.FullScreen = (TheScreen->flags & SDL_FULLSCREEN) ? 1 : 0;
	Video.Depth = TheScreen->format->BitsPerPixel;

	// Turn cursor off, we use our own.
	SDL_ShowCursor(0);

	// Make default character translation easier
	SDL_EnableUNICODE(1);

#ifdef USE_OPENGL
	InitOpenGL();
#endif

	InitKey2Str();

	ColorBlack = Video.MapRGB(TheScreen->format, 0, 0, 0);
	ColorDarkGreen = Video.MapRGB(TheScreen->format, 48, 100, 4);
	ColorBlue = Video.MapRGB(TheScreen->format, 0, 0, 252);
	ColorOrange = Video.MapRGB(TheScreen->format, 248, 140, 20);
	ColorWhite = Video.MapRGB(TheScreen->format, 252, 248, 240);
	ColorGray = Video.MapRGB(TheScreen->format, 128, 128, 128);
	ColorRed = Video.MapRGB(TheScreen->format, 252, 0, 0);
	ColorGreen = Video.MapRGB(TheScreen->format, 0, 252, 0);
	ColorYellow = Video.MapRGB(TheScreen->format, 252, 252, 0);

	UI.MouseWarpX = UI.MouseWarpY = -1;
}
예제 #16
0
RET_T Update( TARGET *targ )
/*********************************/
{
    DEPEND      *curdep;
    UINT32      startcount;
    bool        target_exists;
    RET_T       ret;

    CheckForBreak();
    if( targ->error ) {
        return( RET_ERROR );
    }
    if( targ->updated ) {
        return( RET_SUCCESS );
    }
    if( targ->special ) {
        PrtMsg( FTL | ATTEMPT_MAKE_SPECIAL, targ->node.name );
        ExitFatal();
    }
    if( targ->busy ) {
        PrtMsg( FTL | RECURSIVE_DEFINITION, targ->node.name );
        ExitFatal();
    }
    PrtMsg( DBG | INF | NEOL | UPDATING_TARGET, targ->node.name );
    targ->busy = true;
    targExists( targ );     /* find file using sufpath */
    startcount = cListCount;

    if( targ->depend == NULL || (targ->depend->clist == NULL && targ->depend->targs == NULL) ) {
        /* has no depend/explicit rules */
        PrtMsg( DBG | INF | M_EXPLICIT_RULE, M_NO );
        ret = tryImply( targ, false );
        if( ret == RET_ERROR ) {
            targ->busy = false;
            targ->error = true;
            return( RET_ERROR );
        } else if( ret == RET_WARN ) {
            // If target with no commands is acceptable, consider it done
            if( targ->allow_nocmd ) {
                targ->cmds_done = true;
            }
        }
    } else if( !targ->scolon ) {
        /* double colon */
        PrtMsg( DBG | INF | M_EXPLICIT_RULE, M_DCOLON );
        for( curdep = targ->depend; curdep != NULL; curdep = curdep->next ) {
            if( resolve( targ, curdep ) != RET_SUCCESS ) {
                targ->busy = false;
                targ->error = true;
                return( RET_ERROR );
            }
        }
        if( !Glob.compat_nmake ) {
            if( tryImply( targ, false ) == RET_ERROR ) {
                targ->busy = false;
                targ->error = true;
                return( RET_ERROR );
            }
        }
    } else {
        PrtMsg( DBG | INF | M_EXPLICIT_RULE, M_SCOLON );
        if( resolve( targ, targ->depend ) != RET_SUCCESS ) {
            targ->busy = false;
            targ->error = true;
            return( RET_ERROR );
        }
    }

    if( (targ->attr.symbolic || Glob.noexec || Glob.query)
        && startcount != cListCount ) {
        targ->existing = true;
        targ->touched = true;
        targ->executed = false;
        targ->date = YOUNGEST_DATE;
    }

    target_exists = targExists( targ );
    if( target_exists || targ->attr.symbolic || Glob.ignore ) {
        // Target exists or it is symbolic or we're ignoring errors,
        // therefore everyone's happy and we can charge forward
        PrtMsg( DBG | INF | TARGET_IS_UPDATED, targ->node.name );
    } else {
        // Target doesn't exist, we may be in trouble
        if( targ->cmds_done && Glob.nocheck ) {
            // Target doesn't exist even though we processed some commands,
            // but we're not checking existence of files. Consider it uptodate.
            targ->existing = true;
            PrtMsg( DBG | INF | TARGET_FORCED_UPTODATE, targ->node.name );
        } else if( Glob.cont ) {
            // Target doesn't exist but we're forcibly continuing. Report
            // nonfatal error.
            targ->error = true;
            targ->busy = false;
            PrtMsg( ERR | UNABLE_TO_MAKE, targ->node.name );
            return( RET_ERROR );
        } else {
            // Target doesn't exist and we have no clue how to make it. Bomb out.
            PrtMsg( FTL | UNABLE_TO_MAKE, targ->node.name );
            ExitFatal();
        }
    }

    targ->updated = ( !targ->attr.multi );
    targ->busy = false;
    targ->error = false;
    return( RET_SUCCESS );
}
예제 #17
0
STATIC TOKEN_T lexDotName( void )
/********************************
 * Given that the last character was a DOT, input the maximum string
 * possible, and check if it is a TOK_DOTNAME, TOK_SUF, or TOK_SUFSUF
 * Special cases to look for: "."{dirc}; ".."{dirc}; ".."{extc}+;
 * and "."{extc}+"."
 * recognizes:
 *   "."{extc}*                                 TOK_SUF
 *   "."{extc}*"."{extc}*                       TOK_SUFSUF
 *   "{"path"}""."{extc}*"{"path"}""."{extc}    TOK_SUFSUF
 *   "."{dot-name}                              TOK_DOTNAME
 *   "."{dirc}                                  passes to lexFileName()
 *   ".."{dirc}                                 passes to lexFileName()
 */
{
    char        ext[MAX_SUFFIX];
    unsigned    pos;
    STRM_T      s;
    STRM_T      s2;
    TOKEN_T     ret;

    pos  = 0;

    if( *targ_path != NULLCHAR ) {
        FreeSafe( targ_path );
        targ_path = "";
    }
    if( *dep_path != NULLCHAR ) {
        FreeSafe( dep_path );
        dep_path = "";
    }
    dep_path = getCurlPath();
    s = PreGetCHR();
    if( s != '.' ) {
        PrtMsg( ERR | LOC | INVALID_SUFSUF );
        return( TOK_NULL );
    } else {
        ext[pos++] = '.';
        s = PreGetCHR();
    }

    if( sisdirc( s ) || IS_PATH_SPLIT( s ) ) {          // check for "."{dirc}
        UnGetCHR( s );
        if( *dep_path != NULLCHAR ) {
            PrtMsg( ERR | LOC | INVALID_SUFSUF );
        }
        return( lexFileName( '.' ) );
    }

    if( s == '.' ) {        /* check if ".."{extc} or ".."{dirc} */
        s2 = PreGetCHR();    /* probe one character */
        UnGetCHR( s2 );
        if( sisdirc( s2 ) || IS_PATH_SPLIT( s2 ) ) {    // is ".."{dirc}
            UnGetCHR( s );
            if( *dep_path != NULLCHAR ) {
                PrtMsg( ERR | LOC | INVALID_SUFSUF );
            }
            return( lexFileName( '.' ) );
        }
    } else {    /* get string {extc}+ */
        while( pos < MAX_SUFFIX && sisextc( s ) && s != '{' ) {
            ext[pos++] = s;
            s = PreGetCHR();
        }
        if( pos == MAX_SUFFIX ) {
            PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_SUFFIX - 1 );
            ExitFatal();
            // never return
        }
        ext[pos] = NULLCHAR;
    }

    UnGetCHR( s );

    targ_path = getCurlPath();

    s = PreGetCHR();        /* next char */

    if( s == '.' ) {        /* maybe of form "."{extc}*"."{extc}* */
        ext[pos++] = s;
        for( s = PreGetCHR(); pos < MAX_SUFFIX && sisextc( s ); s = PreGetCHR() ) {
            ext[pos++] = s;
        }
        if( pos == MAX_SUFFIX ) {
            PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_SUFFIX - 1 ); //NOTREACHED
            ExitFatal();
            // never return
        }
        ext[pos] = NULLCHAR;

        ret = TOK_SUFSUF;
    } else {
        if( *targ_path != NULLCHAR && *dep_path != NULLCHAR ) {
            PrtMsg( ERR | LOC | INVALID_SUFSUF );
        }
        ret = TOK_SUF;
    }
    UnGetCHR( s );           /* put back what we don't need */

    if( *targ_path != NULLCHAR && *dep_path != NULLCHAR && ret == TOK_SUF ) {
        PrtMsg( ERR | LOC | INVALID_SUFSUF );
    } else if( ret == TOK_SUF && checkDotName( ext ) ) {
        return( TOK_DOTNAME );
    }
    CurAttr.u.ptr = StrDupSafe( ext );
    return( ret );
}
예제 #18
0
STATIC RET_T perform( TARGET *targ, DEPEND *dep, DEPEND *impldep, time_t max_time )
/*********************************************************************************/
{
    CLIST   *clist;
    CLIST   *before;
    RET_T   ret;
    DEPEND  *depend;
    DEPEND  *impliedDepend;

    depend = NULL;
    impliedDepend = NULL;
    assert( targ != NULL && dep != NULL );

    if( Glob.query ) {
        ++cListCount;
        return( RET_WARN );
    }
    if( Glob.touch ) {
        ++cListCount;
        ResetExecuted();
        if( !targ->attr.symbolic ) {
            CacheRelease();
            if( TouchFile( targ->node.name ) != RET_SUCCESS ) {
                PrtMsg( ERR | COULD_NOT_TOUCH, targ->node.name );
                return( RET_ERROR );
            }
        }
        targ->touched = true;
        return( RET_SUCCESS );
    }

    /* means that this is a sufsuf made implicit rule */
    if( impldep == NULL ) {
        clist = dep->clist;
        depend = dep;
        impliedDepend = NULL;
    } else {
        clist = impldep->clist;
        depend = targ->depend;
        impliedDepend = dep;
    }
    if( clist == NULL ) {
        clist = DotCList( DOT_DEFAULT );
        if( clist == NULL ) {
            // No commands in Microsoft and POSIX mode is considered OK
            // and executed
            if( Glob.compat_nmake || Glob.compat_posix ) {
                targ->cmds_done = true;
                return( RET_SUCCESS );
            }
            if( targ->attr.symbolic != false ) {
                targ->cmds_done = true;
                return( RET_SUCCESS );
            }
            if( targ->allow_nocmd ) {
                /* for UNIX folks: make target symbolic */
                targ->attr.symbolic = true;
                return( RET_SUCCESS );
            }
            PrtMsg( FTL | NO_DEF_CMDS_FOR_MAKE, DotNames[DOT_DEFAULT], targ->node.name );
            ExitFatal();
        }
    }
    if( !Glob.noexec ) {
        ResetExecuted();
    }
    if( !doneBefore ) {
        before = DotCList( DOT_BEFORE );
        if( before != NULL ) {
            ++cListCount;
            if( ExecCList( before ) != RET_SUCCESS ) {
                PrtMsg( FTL | S_COMMAND_RET_BAD, DotNames[DOT_BEFORE] );
                ExitFatal();
            }
        }
        doneBefore = true;
    }
    exPush( targ, depend, impliedDepend );
    ret = carryOut( targ, clist, findMaxTime( targ, dep, max_time ) );
    exPop();
    if( ret == RET_ERROR ) {
        ExitError();
    }
    return( ret );
}
예제 #19
0
STATIC RET_T carryOut( TARGET *targ, CLIST *clist, time_t max_time )
/******************************************************************/
{
    CLIST               *err;
    int                 i;
    struct utimbuf      times;
    char                msg[max( MAX_RESOURCE_SIZE, _MAX_PATH )];

    assert( targ != NULL && clist != NULL );

    ++cListCount;
    if( ExecCList( clist ) == RET_SUCCESS ) {
        if( Glob.rcs_make && !Glob.noexec && !Glob.touch ) {
            if( max_time != OLDEST_DATE ) {
                targ->date = max_time;
                targ->backdated = true;
                if( TrySufPath( msg, targ->node.name, NULL, false ) == RET_SUCCESS ) {
                    if( USE_AUTO_DEP( targ ) ) {
                        // target has auto dependency info
                        // result: max_time may be incorrect!
                        CacheRelease();
                        checkForAutoDeps( targ, msg, &max_time );
                    }
                    times.actime = max_time;
                    times.modtime = max_time;
                    utime( msg, &times );
                    CacheRelease();
                }
            }
        }
        targ->cmds_done = true;
        return( RET_SUCCESS );
    }

    /*
     * ok - here is something I don't like.  In this portion of code here,
     * carryOut is ignoring the target passed to it, and digging the targets
     * out of the stack.  Be careful of changes.
     */
    PrtMsg( ERR | NEOL | LAST_CMD_MAKING_RET_BAD );
    for( i = exStackP - 1; i >= 0; --i ) {
        PrtMsg( ERR | NEOL | PRNTSTR, exStack[i].targ->node.name );
        if( i > 0 ) {
            PrtMsg( ERR | NEOL | PRNTSTR, ";" );
        }
    }
    MsgGetTail( LAST_CMD_MAKING_RET_BAD, msg );
    PrtMsg( ERR | PRNTSTR, msg );

    err = DotCList( DOT_ERROR );
    if( err != NULL ) {
        ++cListCount;
        if( ExecCList( err ) != RET_SUCCESS ) {
            PrtMsg( FTL | S_COMMAND_RET_BAD, DotNames[DOT_ERROR] );
            ExitFatal();
        }
    } else if( !(targ->attr.precious || targ->attr.symbolic) ) {
        if( !Glob.hold && targExists( targ ) ) {
            if( Glob.erase || GetYes( SHOULD_FILE_BE_DELETED ) ) {
                if( unlink( targ->node.name ) != 0 ) {
                    PrtMsg( FTL | SYSERR_DELETING_ITEM, targ->node.name );
                    ExitFatal();
                }
            }
        }
    }
    if( Glob.cont ) {
        return( RET_WARN );
    }
    return( RET_ERROR );
}
예제 #20
0
STATIC char *DeMacroDoubleQuote( bool IsDoubleQuote )
/****************************************************
 * This procedure takes care of double quotes in the stream
 * Note: each double quote must be paired with a double quote in the
 * input stream or this will expand until the EOL a backlash double
 * quote will be considered as a non-double quote.
 */
{
    char    buffer[_MAX_PATH];
    char    *current;
    char    *p;
    VECSTR  OutString;
    int     pos;
    STRM_T  s;
    bool    StartDoubleQuote;


    s = PreGetCHR();
    UnGetCHR( s );
    if( s == '\n' || s == STRM_END || s == STRM_MAGIC ) {
        return( CharToStrSafe( NULLCHAR ) );
    }
    if( s == STRM_TMP_LEX_START ) {
        PreGetCHR();  /* Eat STRM_TMP_LEX_START */
        pos = 0;
        for( s = PreGetCHR(); s != STRM_MAGIC && pos < _MAX_PATH; s = PreGetCHR() ) {
            assert( s != '\n' || s != STRM_END );
            buffer[pos++] = s;
        }

        if( pos >= _MAX_PATH ) {
            PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
            ExitFatal();
            // never return
        }

        buffer[pos] = NULLCHAR;
        p = StrDupSafe( buffer );
    } else {
        p = DeMacro( MAC_WS );
    }

    StartDoubleQuote = IsDoubleQuote;

    for( current = p; *current != NULLCHAR; ++current ) {
        if( *current == '\"' ) {
            if( !IsDoubleQuote ) {
                /* Found the start of a Double Quoted String */
                if( current != p ) {
                    UnGetCHR( STRM_MAGIC );
                    InsString( StrDupSafe( current ), true );
                    UnGetCHR( STRM_TMP_LEX_START );
                    *current = NULLCHAR;
                    return( p );
                }
                IsDoubleQuote = true;
            } else {
                /* Found the end of the Double Quoted String */
                if( *(current + 1) != NULLCHAR ) {
                    UnGetCHR( STRM_MAGIC );
                    InsString( StrDupSafe( current + 1 ), true );
                    UnGetCHR( STRM_TMP_LEX_START );
                    *(current + 1) = NULLCHAR;
                }
                return( p );
            }
        }
    }

    if( !StartDoubleQuote && !IsDoubleQuote ) {
        /* there are no double quotes in the text */
        /* so return text as is */
        return( p );

    }
    pos = 0;
    s = PreGetCHR();
    while( sisws( s ) ) {
        buffer[pos++] = s;
        s = PreGetCHR();
    }
    buffer[pos] = NULLCHAR;
    UnGetCHR( s );
    OutString = StartVec();
    CatStrToVec( OutString, p );
    FreeSafe( p );
    CatStrToVec( OutString, buffer );
    p = DeMacroDoubleQuote( true );
    CatStrToVec( OutString, p );
    FreeSafe( p );
    return( FinishVec( OutString ) );
}
예제 #21
0
void ParseCommandLine(int argc, char **argv, Parameters &parameters)
{
	for (;;) {
		switch (getopt(argc, argv, "c:d:D:eE:FhI:lL:n:N:oOP:s:S:U:v:W?")) {
			case 'c':
				parameters.luaStartFilename = optarg;
				continue;
			case 'd': {
				StratagusLibPath = optarg;
				size_t index;
				while ((index = StratagusLibPath.find('\\')) != std::string::npos) {
					StratagusLibPath[index] = '/';
				}
				continue;
			}
			case 'D':
				Video.Depth = atoi(optarg);
				continue;
			case 'e':
				Editor.Running = EditorCommandLine;
				continue;
			case 'E':
				parameters.luaEditorStartFilename = optarg;
				continue;
			case 'F':
				VideoForceFullScreen = 1;
				Video.FullScreen = 1;
				continue;
			case 'I':
				NetworkAddr = optarg;
				continue;
			case 'l':
				CommandLogDisabled = true;
				continue;
			case 'L':
				NetworkLag = atoi(optarg);
				if (!NetworkLag) {
					fprintf(stderr, "%s: zero lag not supported\n", argv[0]);
					Usage();
					ExitFatal(-1);
				}
				continue;
			case 'n':
				NetworkArg = optarg;
				continue;
			case 'N':
				parameters.LocalPlayerName = optarg;
				continue;
			case 'o':
				ForceUseOpenGL = 1;
				UseOpenGL = 0;
				continue;
			case 'O':
				ForceUseOpenGL = 1;
				UseOpenGL = 1;
				continue;
			case 'P':
				NetworkPort = atoi(optarg);
				continue;
			case 's':
				AiSleepCycles = atoi(optarg);
				continue;
			case 'S':
				VideoSyncSpeed = atoi(optarg);
				continue;
			case 'U':
				NetworkUpdates = atoi(optarg);
				continue;
			case 'v': {
				char *sep = strchr(optarg, 'x');
				if (!sep || !*(sep + 1)) {
					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%s'\n", argv[0], optarg);
					Usage();
					ExitFatal(-1);
				}
				Video.Height = atoi(sep + 1);
				*sep = 0;
				Video.Width = atoi(optarg);
				if (!Video.Height || !Video.Width) {
					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%sx%s'\n", argv[0], optarg, sep + 1);
					Usage();
					ExitFatal(-1);
				}
				continue;
			}
			case 'W':
				VideoForceFullScreen = 1;
				Video.FullScreen = 0;
				continue;
			case -1:
				break;
			case '?':
			case 'h':
			default:
				Usage();
				ExitFatal(-1);
		}
		break;
	}

	if (argc - optind > 1) {
		fprintf(stderr, "too many files\n");
		Usage();
		ExitFatal(-1);
	}

	if (argc - optind) {
		size_t index;
		CliMapName = argv[optind];
		while ((index = CliMapName.find('\\')) != std::string::npos) {
			CliMapName[index] = '/';
		}
		--argc;
	}
}
예제 #22
0
void ParseCommandLine(int argc, char **argv, Parameters &parameters)
{
	for (;;) {
		switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:Z?-")) {
			case 'a':
				EnableAssert = true;
				continue;
			case 'c':
				parameters.luaStartFilename = optarg;
				if (strlen(optarg) > 4 &&
					!(strstr(optarg, ".lua") == optarg + strlen(optarg) - 4)) {
						parameters.luaStartFilename += ".lua";
				}
				continue;
			case 'd': {
				StratagusLibPath = optarg;
				size_t index;
				while ((index = StratagusLibPath.find('\\')) != std::string::npos) {
					StratagusLibPath[index] = '/';
				}
				continue;
			}
			case 'D':
				Video.Depth = atoi(optarg);
				continue;
			case 'e':
				Editor.Running = EditorCommandLine;
				continue;
			case 'E':
				parameters.luaEditorStartFilename = optarg;
				continue;
			case 'F':
				VideoForceFullScreen = 1;
				Video.FullScreen = 1;
				continue;
			case 'G':
				parameters.luaScriptArguments = optarg;
				continue;
			case 'i':
				EnableUnitDebug = true;
				continue;
			case 'I':
				CNetworkParameter::Instance.localHost = optarg;
				continue;
			case 'l':
				CommandLogDisabled = true;
				continue;
			case 'N':
				parameters.LocalPlayerName = optarg;
				continue;
#if defined(USE_OPENGL) || defined(USE_GLES)
			case 'o':
				ForceUseOpenGL = 1;
				UseOpenGL = 0;
				if (ZoomNoResize) {
					fprintf(stderr, "Error: -Z only works with OpenGL enabled\n");
					Usage();
					ExitFatal(-1);
				}
				continue;
			case 'O':
				ForceUseOpenGL = 1;
				UseOpenGL = 1;
				continue;
#endif
			case 'P':
				CNetworkParameter::Instance.localPort = atoi(optarg);
				continue;
			case 'p':
				EnableDebugPrint = true;
				continue;
			case 's':
				AiSleepCycles = atoi(optarg);
				continue;
			case 'S':
				VideoSyncSpeed = atoi(optarg);
				continue;
			case 'u':
				Parameters::Instance.SetUserDirectory(optarg);
				continue;
			case 'v': {
				char *sep = strchr(optarg, 'x');
				if (!sep || !*(sep + 1)) {
					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%s'\n", argv[0], optarg);
					Usage();
					ExitFatal(-1);
				}
				Video.Height = atoi(sep + 1);
				*sep = 0;
				Video.Width = atoi(optarg);
				if (!Video.Height || !Video.Width) {
					fprintf(stderr, "%s: incorrect format of video mode resolution -- '%sx%s'\n", argv[0], optarg, sep + 1);
					Usage();
					ExitFatal(-1);
				}
#if defined(USE_OPENGL) || defined(USE_GLES)
				if (ZoomNoResize) {
					Video.ViewportHeight = Video.Height;
					Video.ViewportWidth = Video.Width;
					Video.Height = 0;
					Video.Width = 0;
				}
#endif
				continue;
			}
			case 'W':
				VideoForceFullScreen = 1;
				Video.FullScreen = 0;
				continue;
#if defined(USE_OPENGL) || defined(USE_GLES)
			case 'x':
				ShaderIndex = atoi(optarg) % MAX_SHADERS;
				if (atoi(optarg) == -1) {
					GLShaderPipelineSupported = false;
				//Wyrmgus start
				} else {
					GLShaderPipelineSupported = true;
				//Wyrmgus end
				}
				continue;
			case 'Z':
				ForceUseOpenGL = 1;
				UseOpenGL = 1;
				ZoomNoResize = 1;
				Video.ViewportHeight = Video.Height;
				Video.ViewportWidth = Video.Width;
				Video.Height = 0;
				Video.Width = 0;
				continue;
#endif
			case -1:
				break;
			case '?':
			case 'h':
			default:
				Usage();
				ExitFatal(-1);
		}
		break;
	}

	if (argc - optind > 1) {
		fprintf(stderr, "too many map files. if you meant to pass game arguments, these go after '--'\n");
		Usage();
		ExitFatal(-1);
	}

	if (argc - optind) {
		size_t index;
		CliMapName = argv[optind];
		while ((index = CliMapName.find('\\')) != std::string::npos) {
			CliMapName[index] = '/';
		}
	}
}
예제 #23
0
int ParseAnimInt(const CUnit &unit, const char *parseint)
{
	char s[100];
	const CUnit *goal = &unit;

	if (!strlen(parseint)) {
		return 0;
	}

	strcpy(s, parseint);
	char *cur = &s[2];
	if (s[0] == 'v' || s[0] == 't') { //unit variable detected
		if (s[0] == 't') {
			if (unit.CurrentOrder()->HasGoal()) {
				goal = unit.CurrentOrder()->GetGoal();
			} else {
				return 0;
			}
		}
		char *next = strchr(cur, '.');
		if (next == NULL) {
			fprintf(stderr, "Need also specify the variable '%s' tag \n", cur);
			ExitFatal(1);
		} else {
			*next = '\0';
		}
		const int index = UnitTypeVar.VariableNameLookup[cur];// User variables
		if (index == -1) {
			if (!strcmp(cur, "ResourcesHeld")) {
				return goal->ResourcesHeld;
			} else if (!strcmp(cur, "ResourceActive")) {
				return goal->Resource.Active;
			} else if (!strcmp(cur, "_Distance")) {
				return unit.MapDistanceTo(*goal);
			}
			fprintf(stderr, "Bad variable name '%s'\n", cur);
			ExitFatal(1);
		}
		if (!strcmp(next + 1, "Value")) {
			return goal->Variable[index].Value;
		} else if (!strcmp(next + 1, "Max")) {
			return goal->Variable[index].Max;
		} else if (!strcmp(next + 1, "Increase")) {
			return goal->Variable[index].Increase;
		} else if (!strcmp(next + 1, "Enable")) {
			return goal->Variable[index].Enable;
		} else if (!strcmp(next + 1, "Percent")) {
			return goal->Variable[index].Value * 100 / goal->Variable[index].Max;
		}
		return 0;
	} else if (s[0] == 'b' || s[0] == 'g') { //unit bool flag detected
		if (s[0] == 'g') {
			if (unit.CurrentOrder()->HasGoal()) {
				goal = unit.CurrentOrder()->GetGoal();
			} else {
				return 0;
			}
		}
		const int index = UnitTypeVar.BoolFlagNameLookup[cur];// User bool flags
		if (index == -1) {
			fprintf(stderr, "Bad bool-flag name '%s'\n", cur);
			ExitFatal(1);
		}
		return goal->Type->BoolFlag[index].value;
	} else if (s[0] == 's') { //spell type detected
		Assert(goal->CurrentAction() == UnitActionSpellCast);
		const COrder_SpellCast &order = *static_cast<COrder_SpellCast *>(goal->CurrentOrder());
		const SpellType &spell = order.GetSpell();
		if (!strcmp(spell.Ident.c_str(), cur)) {
			return 1;
		}
		return 0;
	} else if (s[0] == 'S') { // check if autocast for this spell available
		const SpellType *spell = SpellTypeByIdent(cur);
		if (!spell) {
			fprintf(stderr, "Invalid spell: '%s'\n", cur);
			ExitFatal(1);
		}
		if (unit.AutoCastSpell[spell->Slot]) {
			return 1;
		}
		return 0;
	} else if (s[0] == 'p') { //player variable detected
		char *next;
		if (*cur == '(') {
			++cur;
			char *end = strchr(cur, ')');
			if (end == NULL) {
				fprintf(stderr, "ParseAnimInt: expected ')'\n");
				ExitFatal(1);
			}
			*end = '\0';
			next = end + 1;
		} else {
			next = strchr(cur, '.');
		}
		if (next == NULL) {
			fprintf(stderr, "Need also specify the %s player's property\n", cur);
			ExitFatal(1);
		} else {
			*next = '\0';
		}
		char *arg = strchr(next + 1, '.');
		if (arg != NULL) {
			*arg = '\0';
		}
		return GetPlayerData(ParseAnimPlayer(unit, cur), next + 1, arg + 1);
	} else if (s[0] == 'r') { //random value
		char *next = strchr(cur, '.');
		if (next == NULL) {
			return SyncRand(atoi(cur) + 1);
		} else {
			*next = '\0';
			const int min = atoi(cur);
			return min + SyncRand(atoi(next + 1) - min + 1);
		}
	} else if (s[0] == 'l') { //player number
		return ParseAnimPlayer(unit, cur);

	}
	// Check if we trying to parse a number
	Assert(isdigit(s[0]) || s[0] == '-');
	return atoi(parseint);
}
예제 #24
0
파일: game.cpp 프로젝트: k1643/StratagusAI
/**
**  Load a Stratagus map.
**
**  @param smpname  smp filename
**  @param mapname  map filename
**  @param map      map loaded
*/
static void LoadStratagusMap(const char *smpname, const char *mapname, CMap *map)
{
	char mapfull[PATH_MAX];
	CFile file;

	// Try the same directory as the smp file first
	strcpy_s(mapfull, sizeof(mapfull), smpname);
	char *p = strrchr(mapfull, '/');
	if (!p) {
		p = mapfull;
	} else {
		++p;
	}
	strcpy_s(p, sizeof(mapfull) - (p - mapfull), mapname);

	if (file.open(mapfull, CL_OPEN_READ) == -1) {
		// Not found, try StratagusLibPath and the smp's dir
		strcpy_s(mapfull, sizeof(mapfull), StratagusLibPath.c_str());
		strcat_s(mapfull, sizeof(mapfull), "/");
		strcat_s(mapfull, sizeof(mapfull), smpname);
		char *p = strrchr(mapfull, '/');
		if (!p) {
			p = mapfull;
		} else {
			++p;
		}
		strcpy_s(p, sizeof(mapfull) - (p - mapfull), mapname);
		if (file.open(mapfull, CL_OPEN_READ) == -1) {
			// Not found again, try StratagusLibPath
			strcpy_s(mapfull, sizeof(mapfull), StratagusLibPath.c_str());
			strcat_s(mapfull, sizeof(mapfull), "/");
			strcat_s(mapfull, sizeof(mapfull), mapname);
			if (file.open(mapfull, CL_OPEN_READ) == -1) {
				// Not found, try mapname by itself as a last resort
				strcpy_s(mapfull, sizeof(mapfull), mapname);
			} else {
				file.close();
			}
		} else {
			file.close();
		}
	} else {
		file.close();
	}

	if (LcmPreventRecurse) {
		fprintf(stderr, "recursive use of load Stratagus map!\n");
		ExitFatal(-1);
	}
	InitPlayers();
	LcmPreventRecurse = 1;
	if (LuaLoadFile(mapfull) == -1) {
		fprintf(stderr, "Can't load lua file: %s\n", mapfull);
		ExitFatal(-1);
	}
	LcmPreventRecurse = 0;

#if 0
	// Not true if multiplayer levels!
	if (!ThisPlayer) { /// ARI: bomb if nothing was loaded!
		fprintf(stderr, "%s: invalid Stratagus map\n", mapname);
		ExitFatal(-1);
	}
#endif
	if (!Map.Info.MapWidth || !Map.Info.MapHeight) {
		fprintf(stderr, "%s: invalid Stratagus map\n", mapname);
		ExitFatal(-1);
	}
	Map.Info.Filename = mapname;
}
예제 #25
0
TOKEN_T LexPath( STRM_T s )
/*********************************
 * returns: ({filec}*";")+          TOK_PATH
 *          EOL                     TOK_EOL
 *          STRM_END                TOK_END
 */
{
    char        path[_MAX_PATH];
    bool        string_open;
    unsigned    pos;
    VECSTR      vec;                /* we'll store file/path here */

    for( ;; ) {                     /* get first valid character */
        if( s == '\n' || s == STRM_END ) {
            /* now we pass this to LexParser() so that it can reset */
            return( LexParser( s ) );
        }

        if( s == STRM_MAGIC ) {
            InsString( DeMacro( TOK_EOL ), true );
        } else if( !sisfilec( s ) && !IS_PATH_SPLIT( s ) && s != '\"' && !sisws( s ) ) {
            PrtMsg( ERR | LOC | EXPECTING_M, M_PATH );
        } else if( !sisws( s ) ) {
            break;
        }

        s = PreGetCHR(); /* keep fetching characters */
    }
    /* just so you know what we've got now */
    assert( sisfilec( s ) || IS_PATH_SPLIT( s ) || s == '\"' );

    vec = StartVec();

    pos = 0;
    for( ;; ) {
        /*
         * Extract path from stream. If double quote is found, start string mode
         * and ignore all filename character specifiers and just copy all
         * characters. String mode ends with another double quote. Backslash can
         * be used to escape only double quotes, otherwise they are recognized
         * as path seperators.  If we are not in string mode character validity
         * is checked against sisfilec().
         */

        string_open = false;

        while( pos < _MAX_PATH && s != '\n' && s != STRM_END ) {
            if( s == '\\' ) {
                s = PreGetCHR();

                if( s == '\"' ) {
                    path[pos++] = '\"';
                } else if( s == '\n' || s == STRM_END ) {
                    // Handle special case when backslash is placed at end of
                    // line or file
                    path[pos++] = '\\';
                } else {
                    path[pos++] = '\\';

                    // make sure we don't cross boundaries
                    if( pos < _MAX_PATH ) {
                        path[pos++] = s;
                    }
                }
            } else {
                if( s == '\"' ) {
                    string_open = !string_open;
                } else {
                    if( string_open ) {
                        path[pos++] = s;
                    } else if( sisfilec( s ) ) {
                        path[pos++] = s;
                    } else {
                        break; // not valid path character, break out.
                    }
                }
            }

            s = PreGetCHR();
        }

        if( string_open ) {
            FreeSafe( FinishVec( vec ) );
            PrtMsg( FTL | LOC | ERROR_STRING_OPEN );
            ExitFatal();
            // never return
        }

        if( pos == _MAX_PATH ) {
            FreeSafe( FinishVec( vec ) );
            PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
            ExitFatal();
            // never return
        }

        path[pos] = NULLCHAR;
        WriteVec( vec, path );

        if( !IS_PATH_SPLIT( s ) ) {
            break;
        }

        pos = 0;
        path[pos++] = PATH_SPLIT;
        s = PreGetCHR();        /* use Pre here to allow path;&(nl)path */
    }
    UnGetCHR( s );

    CurAttr.u.ptr = FinishVec( vec );

    return( TOK_PATH );
}