Project clean-up: move 'misc' into the platform lib, update CMake to build 'platform' as a lib, and various fixes for Visual Studio compiler warnings

pull/7/head
athile 15 years ago
parent 82bbc69453
commit 819c146ad1

@ -68,17 +68,14 @@ set(INPUT_HEADER components/engine/input/oismanager.hpp components/engine/input/
components/engine/input/dispatcher.hpp components/engine/input/poller.hpp) components/engine/input/dispatcher.hpp components/engine/input/poller.hpp)
source_group(input FILES ${INPUT} ${INPUT_HEADER}) source_group(input FILES ${INPUT} ${INPUT_HEADER})
set(MISC components/misc/stringops.cpp components/misc/fileops.cpp)
set(MISC_HEADER components/misc/fileops.hpp components/misc/slice_array.hpp
components/misc/stringops.hpp)
source_group(misc FILES ${MISC} ${MISC_HEADER})
set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${OGRE} ${INPUT} ${MISC}) set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${OGRE} ${INPUT} ${MISC})
set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER} set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER}
${ESM_HEADER} ${OGRE_HEADER} ${INPUT_HEADER} ${MISC_HEADER}) ${ESM_HEADER} ${OGRE_HEADER} ${INPUT_HEADER} ${MISC_HEADER})
# source directory: libs # source directory: libs
ADD_SUBDIRECTORY( libs/platform )
set(MANGLE_VFS libs/mangle/vfs/servers/ogre_vfs.cpp) set(MANGLE_VFS libs/mangle/vfs/servers/ogre_vfs.cpp)
source_group(mangle_vfs FILES ${MANGLE_VFS}) source_group(mangle_vfs FILES ${MANGLE_VFS})
@ -148,6 +145,7 @@ target_link_libraries(openmw
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OIS_LIBRARIES} ${OIS_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
platform
caelum) caelum)
if (APPLE) if (APPLE)

@ -573,7 +573,10 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = .. INPUT = ..\apps
..\components
..\libs
..\docs
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

@ -7,7 +7,7 @@
#include "components/esm_store/cell_store.hpp" #include "components/esm_store/cell_store.hpp"
#include "components/bsa/bsa_archive.hpp" #include "components/bsa/bsa_archive.hpp"
#include "components/engine/ogre/renderer.hpp" #include "components/engine/ogre/renderer.hpp"
#include "components/misc/fileops.hpp" #include "libs/platform/fileops.hpp"
#include "apps/openmw/mwrender/interior.hpp" #include "apps/openmw/mwrender/interior.hpp"
#include "mwinput/inputmanager.hpp" #include "mwinput/inputmanager.hpp"
@ -104,7 +104,7 @@ void OMW::Engine::go()
const char* plugCfg = "plugins.cfg"; const char* plugCfg = "plugins.cfg";
mOgre.configure(!isFile("ogre.cfg"), plugCfg, false); mOgre.configure(!OMW::Platform::isFile("ogre.cfg"), plugCfg, false);
addResourcesDirectory (mDataDir / "Meshes"); addResourcesDirectory (mDataDir / "Meshes");
addResourcesDirectory (mDataDir / "Textures"); addResourcesDirectory (mDataDir / "Textures");

@ -12,7 +12,7 @@
#include <libs/mangle/stream/stream.hpp> #include <libs/mangle/stream/stream.hpp>
#include <libs/mangle/stream/servers/file_stream.hpp> #include <libs/mangle/stream/servers/file_stream.hpp>
#include <libs/mangle/tools/str_exception.hpp> #include <libs/mangle/tools/str_exception.hpp>
#include "components/misc/stringops.hpp" #include "libs/platform/stringops.hpp"
#ifdef __APPLE__ #ifdef __APPLE__
// need our own implementation of strnlen // need our own implementation of strnlen
@ -218,6 +218,8 @@ public:
/// parse the header. /// parse the header.
void openRaw(Mangle::Stream::StreamPtr _esm, const std::string &name) void openRaw(Mangle::Stream::StreamPtr _esm, const std::string &name)
{ {
using namespace OMW::Platform;
close(); close();
esm = _esm; esm = _esm;
c.filename = name; c.filename = name;

@ -30,8 +30,9 @@ namespace Nif
{ {
/// Anything that has a controller /// Anything that has a controller
struct Controlled : Extra class Controlled : public Extra
{ {
public:
ControllerPtr controller; ControllerPtr controller;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -42,8 +43,9 @@ struct Controlled : Extra
}; };
/// Has name, extra-data and controller /// Has name, extra-data and controller
struct Named : Controlled class Named : public Controlled
{ {
public:
SString name; SString name;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -54,8 +56,9 @@ struct Named : Controlled
}; };
typedef Named NiSequenceStreamHelper; typedef Named NiSequenceStreamHelper;
struct NiParticleGrowFade : Controlled class NiParticleGrowFade : public Controlled
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
@ -65,8 +68,9 @@ struct NiParticleGrowFade : Controlled
} }
}; };
struct NiParticleColorModifier : Controlled class NiParticleColorModifier : public Controlled
{ {
public:
NiColorDataPtr data; NiColorDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -76,8 +80,9 @@ struct NiParticleColorModifier : Controlled
} }
}; };
struct NiGravity : Controlled class NiGravity : public Controlled
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
@ -88,8 +93,9 @@ struct NiGravity : Controlled
}; };
// NiPinaColada // NiPinaColada
struct NiPlanarCollider : Controlled class NiPlanarCollider : public Controlled
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
@ -99,8 +105,9 @@ struct NiPlanarCollider : Controlled
} }
}; };
struct NiParticleRotation : Controlled class NiParticleRotation : public Controlled
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);

@ -31,8 +31,9 @@
namespace Nif namespace Nif
{ {
struct Controller : Record class Controller : public Record
{ {
public:
ControllerPtr next; ControllerPtr next;
int flags; int flags;
float frequency, phase; float frequency, phase;
@ -54,8 +55,9 @@ struct Controller : Record
} }
}; };
struct NiBSPArrayController : Controller class NiBSPArrayController : public Controller
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
@ -68,8 +70,9 @@ struct NiBSPArrayController : Controller
}; };
typedef NiBSPArrayController NiParticleSystemController; typedef NiBSPArrayController NiParticleSystemController;
struct NiMaterialColorController : Controller class NiMaterialColorController : public Controller
{ {
public:
NiPosDataPtr data; NiPosDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -79,8 +82,9 @@ struct NiMaterialColorController : Controller
} }
}; };
struct NiPathController : Controller class NiPathController : public Controller
{ {
public:
NiPosDataPtr posData; NiPosDataPtr posData;
NiFloatDataPtr floatData; NiFloatDataPtr floatData;
@ -99,8 +103,9 @@ struct NiPathController : Controller
} }
}; };
struct NiUVController : Controller class NiUVController : public Controller
{ {
public:
NiUVDataPtr data; NiUVDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -112,8 +117,9 @@ struct NiUVController : Controller
} }
}; };
struct NiKeyframeController : Controller class NiKeyframeController : public Controller
{ {
public:
NiKeyframeDataPtr data; NiKeyframeDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -123,8 +129,9 @@ struct NiKeyframeController : Controller
} }
}; };
struct NiAlphaController : Controller class NiAlphaController : public Controller
{ {
public:
NiFloatDataPtr data; NiFloatDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -134,8 +141,9 @@ struct NiAlphaController : Controller
} }
}; };
struct NiGeomMorpherController : Controller class NiGeomMorpherController : public Controller
{ {
public:
NiMorphDataPtr data; NiMorphDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -146,8 +154,9 @@ struct NiGeomMorpherController : Controller
} }
}; };
struct NiVisController : Controller class NiVisController : public Controller
{ {
public:
NiVisDataPtr data; NiVisDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)

@ -29,8 +29,10 @@
namespace Nif namespace Nif
{ {
struct NiSourceTexture : Named class NiSourceTexture : public Named
{ {
public:
// Is this an external (references a separate texture file) or // Is this an external (references a separate texture file) or
// internal (data is inside the nif itself) texture? // internal (data is inside the nif itself) texture?
bool external; bool external;
@ -65,7 +67,7 @@ struct NiSourceTexture : Named
{ {
Named::read(nif); Named::read(nif);
external = nif->getByte(); external = !!nif->getByte();
if(external) filename = nif->getString(); if(external) filename = nif->getString();
else else
@ -83,8 +85,9 @@ struct NiSourceTexture : Named
}; };
// Common ancestor for several data classes // Common ancestor for several data classes
struct ShapeData : Record class ShapeData : public Record
{ {
public:
FloatArray vertices, normals, colors, uvlist; FloatArray vertices, normals, colors, uvlist;
const Vector *center; const Vector *center;
float radius; float radius;
@ -116,8 +119,9 @@ struct ShapeData : Record
} }
}; };
struct NiTriShapeData : ShapeData class NiTriShapeData : public ShapeData
{ {
public:
// Triangles, three vertex indices per triangle // Triangles, three vertex indices per triangle
SliceArray<short> triangles; SliceArray<short> triangles;
@ -150,8 +154,9 @@ struct NiTriShapeData : ShapeData
} }
}; };
struct NiAutoNormalParticlesData : ShapeData class NiAutoNormalParticlesData : public ShapeData
{ {
public:
int activeCount; int activeCount;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -171,8 +176,9 @@ struct NiAutoNormalParticlesData : ShapeData
} }
}; };
struct NiRotatingParticlesData : NiAutoNormalParticlesData class NiRotatingParticlesData : public NiAutoNormalParticlesData
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
NiAutoNormalParticlesData::read(nif); NiAutoNormalParticlesData::read(nif);
@ -185,8 +191,9 @@ struct NiRotatingParticlesData : NiAutoNormalParticlesData
} }
}; };
struct NiPosData : Record class NiPosData : public Record
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int count = nif->getInt(); int count = nif->getInt();
@ -210,8 +217,9 @@ struct NiPosData : Record
} }
}; };
struct NiUVData : Record class NiUVData : public Record
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
// TODO: This is claimed to be a "float animation key", which is // TODO: This is claimed to be a "float animation key", which is
@ -235,8 +243,9 @@ struct NiUVData : Record
} }
}; };
struct NiFloatData : Record class NiFloatData : public Record
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int count = nif->getInt(); int count = nif->getInt();
@ -245,8 +254,9 @@ struct NiFloatData : Record
} }
}; };
struct NiPixelData : Record class NiPixelData : public Record
{ {
public:
unsigned int rmask, gmask, bmask, amask; unsigned int rmask, gmask, bmask, amask;
int bpp, mips; int bpp, mips;
@ -283,8 +293,9 @@ struct NiPixelData : Record
} }
}; };
struct NiColorData : Record class NiColorData : public Record
{ {
public:
struct ColorData struct ColorData
{ {
float time; float time;
@ -302,8 +313,9 @@ struct NiColorData : Record
} }
}; };
struct NiVisData : Record class NiVisData : public Record
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int count = nif->getInt(); int count = nif->getInt();
@ -319,8 +331,9 @@ struct NiVisData : Record
} }
}; };
struct NiSkinInstance : Record class NiSkinInstance : public Record
{ {
public:
NiSkinDataPtr data; NiSkinDataPtr data;
NodePtr root; NodePtr root;
NodeList bones; NodeList bones;
@ -338,8 +351,9 @@ struct NiSkinInstance : Record
void post(NIFFile *nif); void post(NIFFile *nif);
}; };
struct NiSkinData : Record class NiSkinData : public Record
{ {
public:
// This is to make sure the structs are packed, ie. that the // This is to make sure the structs are packed, ie. that the
// compiler doesn't mess them up with extra alignment bytes. // compiler doesn't mess them up with extra alignment bytes.
#pragma pack(push) #pragma pack(push)
@ -395,8 +409,9 @@ struct NiSkinData : Record
} }
}; };
struct NiMorphData : Record class NiMorphData : public Record
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int morphCount = nif->getInt(); int morphCount = nif->getInt();
@ -416,8 +431,9 @@ struct NiMorphData : Record
} }
}; };
struct NiKeyframeData : Record class NiKeyframeData : public Record
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
// Rotations first // Rotations first

@ -35,15 +35,17 @@ namespace Nif
themselves decend from the Extra class, and all the extra data themselves decend from the Extra class, and all the extra data
connected to an object form a linked list connected to an object form a linked list
*/ */
struct Extra : Record class Extra : public Record
{ {
public:
ExtraPtr extra; ExtraPtr extra;
void read(NIFFile *nif) { extra.read(nif); } void read(NIFFile *nif) { extra.read(nif); }
}; };
struct NiVertWeightsExtraData : Extra class NiVertWeightsExtraData : public Extra
{ {
public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Extra::read(nif); Extra::read(nif);
@ -57,8 +59,9 @@ struct NiVertWeightsExtraData : Extra
} }
}; };
struct NiTextKeyExtraData : Extra class NiTextKeyExtraData : public Extra
{ {
public:
struct TextKey struct TextKey
{ {
float time; float time;
@ -83,8 +86,9 @@ struct NiTextKeyExtraData : Extra
} }
}; };
struct NiStringExtraData : Extra class NiStringExtraData : public Extra
{ {
public:
/* Two known meanings: /* Two known meanings:
"MRK" - marker, only visible in the editor, not rendered in-game "MRK" - marker, only visible in the editor, not rendered in-game
"NCO" - no collision "NCO" - no collision

@ -23,7 +23,7 @@
#include "nif_file.hpp" #include "nif_file.hpp"
#include "record.hpp" #include "record.hpp"
#include "components/misc/stringops.hpp" #include "libs/platform/stringops.hpp"
#include "extra.hpp" #include "extra.hpp"
#include "controlled.hpp" #include "controlled.hpp"
@ -44,6 +44,8 @@ using namespace Nif;
void NIFFile::parse() void NIFFile::parse()
{ {
using namespace OMW::Platform;
// Check the header string // Check the header string
const char* head = getString(40); const char* head = getString(40);
if(!begins(head, "NetImmerse File Format")) if(!begins(head, "NetImmerse File Format"))

@ -28,7 +28,7 @@
#include <libs/mangle/stream/filters/buffer_stream.hpp> #include <libs/mangle/stream/filters/buffer_stream.hpp>
#include <libs/mangle/tools/str_exception.hpp> #include <libs/mangle/tools/str_exception.hpp>
#include "../misc/slice_array.hpp" #include "libs/platform/slice_array.hpp"
#include <vector> #include <vector>
#include <string> #include <string>

@ -34,8 +34,9 @@ namespace Nif
parent node (unless it's the root), and transformation (location parent node (unless it's the root), and transformation (location
and rotation) relative to it's parent. and rotation) relative to it's parent.
*/ */
struct Node : Named class Node : public Named
{ {
public:
// Node flags. Interpretation depends somewhat on the type of node. // Node flags. Interpretation depends somewhat on the type of node.
int flags; int flags;
const Transformation *trafo; const Transformation *trafo;
@ -55,7 +56,7 @@ struct Node : Named
trafo = nif->getTrafo(); trafo = nif->getTrafo();
props.read(nif); props.read(nif);
hasBounds = nif->getInt(); hasBounds = !!nif->getInt();
if(hasBounds) if(hasBounds)
{ {
nif->getInt(); // always 1 nif->getInt(); // always 1

@ -29,8 +29,9 @@
namespace Nif namespace Nif
{ {
struct Property : Named class Property : public Named
{ {
public:
// The meaning of these depends on the actual property type. // The meaning of these depends on the actual property type.
int flags; int flags;
@ -41,8 +42,9 @@ struct Property : Named
} }
}; };
struct NiTexturingProperty : Property class NiTexturingProperty : public Property
{ {
public:
// A sub-texture // A sub-texture
struct Texture struct Texture
{ {
@ -67,7 +69,7 @@ struct NiTexturingProperty : Property
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
inUse = nif->getInt(); inUse = !!nif->getInt();
if(!inUse) return; if(!inUse) return;
texture.read(nif); texture.read(nif);

@ -0,0 +1,14 @@
project(Platform)
file(GLOB_RECURSE SOURCES src/*)
file(GLOB_RECURSE CAELUM_HDR include/*)
set(SOURCES
fileops.cpp
fileops.hpp
slice_array.hpp
stdint.h
stringops.cpp
stringops.hpp
strings.h)
add_library(platform STATIC ${SOURCES})

@ -0,0 +1,11 @@
#include "fileops.hpp"
#include <boost/filesystem.hpp>
namespace OMW { namespace Platform {
bool isFile(const char *name)
{
boost::filesystem::path cfg_file_path(name);
return boost::filesystem::exists(cfg_file_path);
}
}}

@ -0,0 +1,10 @@
#ifndef __FILEOPS_H_
#define __FILEOPS_H_
namespace OMW { namespace Platform {
/// Check if a given path is an existing file (not a directory)
bool isFile(const char *name);
}}
#endif

@ -0,0 +1,75 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.sourceforge.net/
This file (slice_array.h) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
#ifndef _SLICE_ARRAY_H_
#define _SLICE_ARRAY_H_
// A simple array implementation containing a pointer and a
// length. Used for holding slices into a data buffer.
#include <string.h>
template <class T>
struct SliceArray
{
const T* ptr;
size_t length;
/// Initialize to zero length
SliceArray() : ptr(0), length(0) {}
/// Initialize from pointer + length
SliceArray(const T* _ptr, size_t _length)
: ptr(_ptr), length(_length) {}
/// Initialize from null-terminated string
SliceArray(const char* str)
{
ptr = str;
length = strlen(str);
}
bool operator==(SliceArray &t)
{
return
length == t.length &&
(memcmp(ptr,t.ptr, length*sizeof(T)) == 0);
}
/// Only use this for stings
bool operator==(const char* str)
{
return
str[length] == 0 &&
(strncmp(ptr, str, length) == 0);
}
/** This allocates a copy of the data. Only use this for debugging
and error messages. */
std::string toString()
{ return std::string(ptr,length); }
};
typedef SliceArray<char> SString;
typedef SliceArray<int> IntArray;
typedef SliceArray<float> FloatArray;
#endif

@ -0,0 +1,63 @@
#include "stringops.hpp"
#include <string.h>
#include "strings.h"
namespace OMW { namespace Platform {
bool begins(const char* str1, const char* str2)
{
while(*str2)
{
if(*str1 == 0 || *str1 != *str2) return false;
str1++;
str2++;
}
return true;
}
bool ends(const char* str1, const char* str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
if(len1 < len2) return false;
return strcmp(str2, str1+len1-len2) == 0;
}
// True if the given chars match, case insensitive
static bool icmp(char a, char b)
{
if(a >= 'A' && a <= 'Z')
a += 'a' - 'A';
if(b >= 'A' && b <= 'Z')
b += 'a' - 'A';
return a == b;
}
bool ibegins(const char* str1, const char* str2)
{
while(*str2)
{
if(*str1 == 0 || !icmp(*str1,*str2)) return false;
str1++;
str2++;
}
return true;
}
bool iends(const char* str1, const char* str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
if(len1 < len2) return false;
return strcasecmp(str2, str1+len1-len2) == 0;
}
}}

@ -0,0 +1,19 @@
#ifndef __STRINGOPS_H
#define __STRINGOPS_H
namespace OMW { namespace Platform {
/// Returns true if str1 begins with substring str2
bool begins(const char* str1, const char* str2);
/// Returns true if str1 ends with substring str2
bool ends(const char* str1, const char* str2);
/// Case insensitive, returns true if str1 begins with substring str2
bool ibegins(const char* str1, const char* str2);
/// Case insensitive, returns true if str1 ends with substring str2
bool iends(const char* str1, const char* str2);
}}
#endif

@ -0,0 +1,6 @@
hello, len=5
001
hell, len=4
010
01
4 3

@ -0,0 +1,30 @@
#include <iostream>
using namespace std;
#include <assert.h>
#include "../slice_array.hpp"
int main()
{
SString s, t;
s = SString("hello");
cout << s.toString() << ", len=" << s.length << endl;
cout << (s=="hel") << (s=="hell") << (s=="hello") << endl;
t = s;
s = SString("othello"+2, 4);
cout << s.toString() << ", len=" << s.length << endl;
cout << (s=="hel") << (s=="hell") << (s=="hello") << endl;
cout << (s==t) << (SString("hello")==t) << endl;
const int arr[4] = {1,2,3,4};
IntArray ia(arr,4);
cout << ia.length << " " << ia.ptr[2] << endl;
return 0;
}

@ -0,0 +1,48 @@
#include <assert.h>
#include "../stringops.hpp"
int main()
{
assert(begins("abc", "a"));
assert(begins("abc", "ab"));
assert(begins("abc", "abc"));
assert(begins("abcd", "abc"));
assert(!begins("abc", "b"));
assert(!begins("abc", "bc"));
assert(!begins("abc", "bcd"));
assert(!begins("abc", "abcd"));
assert(ibegins("Abc", "a"));
assert(ibegins("aBc", "ab"));
assert(ibegins("abC", "abc"));
assert(ibegins("abcD", "abc"));
assert(!ibegins("abc", "b"));
assert(!ibegins("abc", "bc"));
assert(!ibegins("abc", "bcd"));
assert(!ibegins("abc", "abcd"));
assert(ends("abc", "c"));
assert(ends("abc", "bc"));
assert(ends("abc", "abc"));
assert(ends("abcd", "abcd"));
assert(!ends("abc", "b"));
assert(!ends("abc", "ab"));
assert(!ends("abc", "bcd"));
assert(!ends("abc", "abcd"));
assert(iends("Abc", "c"));
assert(iends("aBc", "bc"));
assert(iends("abC", "abc"));
assert(iends("abcD", "abcd"));
assert(!iends("abc", "b"));
assert(!iends("abc", "ab"));
assert(!iends("abc", "bcd"));
assert(!iends("abc", "abcd"));
return 0;
}

@ -0,0 +1,18 @@
#!/bin/bash
make || exit
mkdir -p output
PROGS=*_test
for a in $PROGS; do
if [ -f "output/$a.out" ]; then
echo "Running $a:"
./$a | diff output/$a.out -
else
echo "Creating $a.out"
./$a > "output/$a.out"
git add "output/$a.out"
fi
done
Loading…
Cancel
Save