Skip to content

Commit

Permalink
added sid
Browse files Browse the repository at this point in the history
  • Loading branch information
Randy Gaul committed Dec 17, 2016
1 parent e37d095 commit 2b2ec58
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 0 deletions.
5 changes: 5 additions & 0 deletions examples_tinysid/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sid : main.c
gcc -I../ main.c -o $@

do_sid : sid
sid ./preprocess_me
37 changes: 37 additions & 0 deletions examples_tinysid/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#define TINYSID_IMPL
#define TINYFILES_IMPL
#include "tinysid.h"
#include "tinyfiles.h"

#include <string.h>
#include <stdlib.h>

char* strcatdup( const char* a, const char* b )
{
int len_a = strlen( a );
int len_b = strlen( b );
char* c = malloc( len_a + len_b + 1 );
memcpy( c, a, len_a );
memcpy( c + len_a, b, len_b + 1 );
return c;
}

void CB_DoPreprocess( tfFILE* file, void* udata )
{
(void)udata;
char* out = strcatdup( file->path, ".preprocessed" );
tsPreprocess( file->path, out );
free( out );
}

int main( int argc, const char** argv )
{
if ( argc != 2 )
{
printf( "Incorrect parameter usage. Should only pass the path to source directory.\n" );
return -1;
}

tfTraverse( argv[ 1 ], CB_DoPreprocess, 0 );
return 0;
}
17 changes: 17 additions & 0 deletions examples_tinysid/preprocess_me/a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <stdio.h>

typedef sid unsigned;

int main( )
{
sid id = SID( "hello" );

switch ( id )
{
case SID( "nope" ): printf( "nope" ); break;
case SID( "hello" ): printf( "yep" ); break;
case SID( "peekaboo" ): printf( "nope" ); break;
}

return 0;
}
4 changes: 4 additions & 0 deletions examples_tinysid/preprocess_me/b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SID( "hi" )
SID( "yoo" )
SID( "asdfjajsdfaiwjfkopasdkopkasopfkapsodfkpaosdfkaspodfkapsofdk" )
SID( "SID" )
227 changes: 227 additions & 0 deletions tinysid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#if !defined( TINYSID_H )

void tsPreprocess( const char* path, const char* out_path );

#define TINYSID_H
#endif

#ifdef TINYSID_IMPL

#include <stdlib.h> // malloc, free
#include <stdio.h> // fopen, fseek, ftell, fclose, fwrite, fread
#include <ctype.h> // isspace
#include <assert.h>

static unsigned djb2( char* str, char* end )
{
unsigned h = 5381;
int c;

while ( str != end )
{
c = *str;
h = ((h << 5) + h) + c;
++str;
}

return h;
}

#if !defined( TINYSID_HASH )
#define TINYSID_HASH djb2
#endif

static void tsSkipWhite_internal( char** dataPtr, char** outPtr )
{
char* data = *dataPtr;
char* out = *outPtr;

while ( isspace( *data ) )
*out++ = *data++;

*dataPtr = data;
*outPtr = out;
}

static int tsNext_internal( char** dataPtr, char** outPtr )
{
char* data = *dataPtr;
char* out = *outPtr;
int result = 1;

while ( 1 )
{
if ( !*data )
{
result = 0;
goto return_result;
}

tsSkipWhite_internal( &data, &out );

if ( !*data )
{
result = 0;
goto return_result;
}

if ( !isalnum( *data ) )
{
*out++ = *data++;
continue;
}

int index = 0;
int matched = 1;
const char* match = "SID(";
while ( 1 )
{
if ( !match[ index ] )
break;

if ( !*data )
{
result = 0;
goto return_result;
}

if ( *data == match[ index ] )
{
++data;
++index;
}

else
{
matched = 0;
break;
}
}

data -= index;

if ( matched )
break;

while ( isalnum( *data ) )
*out++ = *data++;
}

return_result:

*dataPtr = data;
*outPtr = out;

return result;
}

void tsPreprocess( const char* path, const char* out_path )
{
#ifdef _WIN32
_set_printf_count_output( 1 );
#endif

char* data = 0;
int size = 0;
FILE* fp = fopen( path, "rb" );

if ( fp )
{
fseek( fp, 0, SEEK_END );
size = ftell( fp );
fseek( fp, 0, SEEK_SET );
data = (char*)malloc( size + 1 );
fread( data, size, 1, fp );
fclose( fp );
data[ size ] = 0;
}

else
{
printf( "SID ERROR: sid.exe could not open input file %s.\n", path );
return;
}

char* out = (char*)malloc( size * 2 );
char* outOriginal = out;

int fileWasModified = 0;

while ( tsNext_internal( &data, &out ) )
{
fileWasModified = 1;
data += 4;
while ( isspace( *data ) )
data++;

// TODO: handle escaped quotes
if ( *data != '"' )
{
printf( "SID ERROR: Only strings can be placed inside of the SID macro.\n" );
assert( 0 );
return;
}

char* ptr = ++data;

// TODO: make sure that strings in here aren't over the maximum length
while ( 1 )
{
if ( *ptr == '\\' )
{
ptr += 2;
continue;
}

if ( *ptr == '"' )
break;

++ptr;
}

int count = 0;
unsigned h = djb2( data, ptr ); // TODO: detect and report collisions
int bytes = ptr - data;
sprintf( out, "0x%x /* \"%.*s\" */%n", h, bytes, data, &count );
out += count;

data = ptr + 1;
while ( isspace( *data ) )
data++;
if ( data[ 0 ] != ')' )
{
printf( "SID ERROR: Must have ) immediately after the SID macro (look near the string \"%.*s\").\n", (int)(ptr - data), data );
assert( 0 );
return;
}
data += 1;
}

if ( fileWasModified )
{
fp = fopen( out_path, "wb" );
fwrite( outOriginal, out - outOriginal, 1, fp );
fclose( fp );
}
}

#endif

/*
zlib license:
Copyright (c) 2016 Randy Gaul http://www.randygaul.net
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from
the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

0 comments on commit 2b2ec58

Please sign in to comment.