summary refs log blame commit diff stats
path: root/tinyc/libtcc.h
blob: 96070e2995ff698f369bab3883786f92908e2352 (plain) (tree)











































































































                                                                                  
#ifndef LIBTCC_H
#define LIBTCC_H

#ifdef LIBTCC_AS_DLL
#define LIBTCCAPI __declspec(dllexport)
#else
#define LIBTCCAPI
#endif

#ifdef __cplusplus
extern "C" {
#endif

struct TCCState;

typedef struct TCCState TCCState;

/* create a new TCC compilation context */
LIBTCCAPI TCCState *tcc_new(void);

/* free a TCC compilation context */
LIBTCCAPI void tcc_delete(TCCState *s);

/* add debug information in the generated code */
LIBTCCAPI void tcc_enable_debug(TCCState *s);

/* set error/warning display callback */
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
                        void (*error_func)(void *opaque, const char *msg));

/* set/reset a warning */
LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value);

/*****************************/
/* preprocessor */

/* add include path */
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);

/* add in system include path */
LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);

/* define preprocessor symbol 'sym'. Can put optional value */
LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);

/* undefine preprocess symbol 'sym' */
LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);

/*****************************/
/* compiling */

/* add a file (either a C file, dll, an object, a library or an ld
   script). Return -1 if error. */
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);

/* compile a string containing a C source. Return non zero if
   error. */
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);

/*****************************/
/* linking commands */

/* set output type. MUST BE CALLED before any compilation */
#define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
                                 output file) (default) */
#define TCC_OUTPUT_EXE      1 /* executable file */
#define TCC_OUTPUT_DLL      2 /* dynamic library */
#define TCC_OUTPUT_OBJ      3 /* object file */
#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */
LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);

#define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
#define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */

/* equivalent to -Lpath option */
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);

/* the library name is the same as the argument of the '-l' option */
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);

/* add a symbol to the compiled program */
LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val);

/* output an executable, library or object file. DO NOT call
   tcc_relocate() before. */
LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);

/* link and run main() function and return its value. DO NOT call
   tcc_relocate() before. */
LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);

/* copy code into memory passed in by the caller and do all relocations
   (needed before using tcc_get_symbol()).
   returns -1 on error and required size if ptr is NULL */
LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);

/* return symbol value or NULL if not found */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);

/* set CONFIG_TCCDIR at runtime */
LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);

#ifdef __cplusplus
}
#endif

#endif
>, y, z: int32): int32 {.inline.} = Result = y xor (x or (not z)) proc rot(x: var int32, n: int8) {.inline.} = x = toU32(x shl ze(n)) or (x shr toU32(32 -% ze(n))) proc FF(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = a = a +% F(b, c, d) +% x +% ac rot(a, s) a = a +% b proc GG(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = a = a +% G(b, c, d) +% x +% ac rot(a, s) a = a +% b proc HH(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = a = a +% H(b, c, d) +% x +% ac rot(a, s) a = a +% b proc II(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = a = a +% I(b, c, d) +% x +% ac rot(a, s) a = a +% b proc encode(dest: var MD5Block, src: cstring) = var j = 0 for i in 0..high(dest): dest[i] = toU32(ord(src[j]) or ord(src[j+1]) shl 8 or ord(src[j+2]) shl 16 or ord(src[j+3]) shl 24) inc(j, 4) proc decode(dest: var openarray[int8], src: openarray[int32]) = var i = 0 for j in 0..high(src): dest[i] = toU8(src[j] and 0xff'i32) dest[i+1] = toU8(src[j] shr 8'i32 and 0xff'i32) dest[i+2] = toU8(src[j] shr 16'i32 and 0xff'i32) dest[i+3] = toU8(src[j] shr 24'i32 and 0xff'i32) inc(i, 4) proc transform(Buffer: pointer, State: var MD5State) = var myBlock: MD5Block encode(myBlock, cast[cstring](buffer)) var a = State[0] var b = State[1] var c = State[2] var d = State[3] FF(a, b, c, d, myBlock[0], 7'i8, 0xD76AA478'i32) FF(d, a, b, c, myBlock[1], 12'i8, 0xE8C7B756'i32) FF(c, d, a, b, myBlock[2], 17'i8, 0x242070DB'i32) FF(b, c, d, a, myBlock[3], 22'i8, 0xC1BDCEEE'i32) FF(a, b, c, d, myBlock[4], 7'i8, 0xF57C0FAF'i32) FF(d, a, b, c, myBlock[5], 12'i8, 0x4787C62A'i32) FF(c, d, a, b, myBlock[6], 17'i8, 0xA8304613'i32) FF(b, c, d, a, myBlock[7], 22'i8, 0xFD469501'i32) FF(a, b, c, d, myBlock[8], 7'i8, 0x698098D8'i32) FF(d, a, b, c, myBlock[9], 12'i8, 0x8B44F7AF'i32) FF(c, d, a, b, myBlock[10], 17'i8, 0xFFFF5BB1'i32) FF(b, c, d, a, myBlock[11], 22'i8, 0x895CD7BE'i32) FF(a, b, c, d, myBlock[12], 7'i8, 0x6B901122'i32) FF(d, a, b, c, myBlock[13], 12'i8, 0xFD987193'i32) FF(c, d, a, b, myBlock[14], 17'i8, 0xA679438E'i32) FF(b, c, d, a, myBlock[15], 22'i8, 0x49B40821'i32) GG(a, b, c, d, myBlock[1], 5'i8, 0xF61E2562'i32) GG(d, a, b, c, myBlock[6], 9'i8, 0xC040B340'i32) GG(c, d, a, b, myBlock[11], 14'i8, 0x265E5A51'i32) GG(b, c, d, a, myBlock[0], 20'i8, 0xE9B6C7AA'i32) GG(a, b, c, d, myBlock[5], 5'i8, 0xD62F105D'i32) GG(d, a, b, c, myBlock[10], 9'i8, 0x02441453'i32) GG(c, d, a, b, myBlock[15], 14'i8, 0xD8A1E681'i32) GG(b, c, d, a, myBlock[4], 20'i8, 0xE7D3FBC8'i32) GG(a, b, c, d, myBlock[9], 5'i8, 0x21E1CDE6'i32) GG(d, a, b, c, myBlock[14], 9'i8, 0xC33707D6'i32) GG(c, d, a, b, myBlock[3], 14'i8, 0xF4D50D87'i32) GG(b, c, d, a, myBlock[8], 20'i8, 0x455A14ED'i32) GG(a, b, c, d, myBlock[13], 5'i8, 0xA9E3E905'i32) GG(d, a, b, c, myBlock[2], 9'i8, 0xFCEFA3F8'i32) GG(c, d, a, b, myBlock[7], 14'i8, 0x676F02D9'i32) GG(b, c, d, a, myBlock[12], 20'i8, 0x8D2A4C8A'i32) HH(a, b, c, d, myBlock[5], 4'i8, 0xFFFA3942'i32) HH(d, a, b, c, myBlock[8], 11'i8, 0x8771F681'i32) HH(c, d, a, b, myBlock[11], 16'i8, 0x6D9D6122'i32) HH(b, c, d, a, myBlock[14], 23'i8, 0xFDE5380C'i32) HH(a, b, c, d, myBlock[1], 4'i8, 0xA4BEEA44'i32) HH(d, a, b, c, myBlock[4], 11'i8, 0x4BDECFA9'i32) HH(c, d, a, b, myBlock[7], 16'i8, 0xF6BB4B60'i32) HH(b, c, d, a, myBlock[10], 23'i8, 0xBEBFBC70'i32) HH(a, b, c, d, myBlock[13], 4'i8, 0x289B7EC6'i32) HH(d, a, b, c, myBlock[0], 11'i8, 0xEAA127FA'i32) HH(c, d, a, b, myBlock[3], 16'i8, 0xD4EF3085'i32) HH(b, c, d, a, myBlock[6], 23'i8, 0x04881D05'i32) HH(a, b, c, d, myBlock[9], 4'i8, 0xD9D4D039'i32) HH(d, a, b, c, myBlock[12], 11'i8, 0xE6DB99E5'i32) HH(c, d, a, b, myBlock[15], 16'i8, 0x1FA27CF8'i32) HH(b, c, d, a, myBlock[2], 23'i8, 0xC4AC5665'i32) II(a, b, c, d, myBlock[0], 6'i8, 0xF4292244'i32) II(d, a, b, c, myBlock[7], 10'i8, 0x432AFF97'i32) II(c, d, a, b, myBlock[14], 15'i8, 0xAB9423A7'i32) II(b, c, d, a, myBlock[5], 21'i8, 0xFC93A039'i32) II(a, b, c, d, myBlock[12], 6'i8, 0x655B59C3'i32) II(d, a, b, c, myBlock[3], 10'i8, 0x8F0CCC92'i32) II(c, d, a, b, myBlock[10], 15'i8, 0xFFEFF47D'i32) II(b, c, d, a, myBlock[1], 21'i8, 0x85845DD1'i32) II(a, b, c, d, myBlock[8], 6'i8, 0x6FA87E4F'i32) II(d, a, b, c, myBlock[15], 10'i8, 0xFE2CE6E0'i32) II(c, d, a, b, myBlock[6], 15'i8, 0xA3014314'i32) II(b, c, d, a, myBlock[13], 21'i8, 0x4E0811A1'i32) II(a, b, c, d, myBlock[4], 6'i8, 0xF7537E82'i32) II(d, a, b, c, myBlock[11], 10'i8, 0xBD3AF235'i32) II(c, d, a, b, myBlock[2], 15'i8, 0x2AD7D2BB'i32) II(b, c, d, a, myBlock[9], 21'i8, 0xEB86D391'i32) State[0] = State[0] +% a State[1] = State[1] +% b State[2] = State[2] +% c State[3] = State[3] +% d proc MD5Init*(c: var MD5Context) = ## initializes a MD5Context c.State[0] = 0x67452301'i32 c.State[1] = 0xEFCDAB89'i32 c.State[2] = 0x98BADCFE'i32 c.State[3] = 0x10325476'i32 c.Count[0] = 0'i32 c.Count[1] = 0'i32 ZeroMem(addr(c.Buffer), SizeOf(MD5Buffer)) proc MD5Update*(c: var MD5Context, input: cstring, len: int) = ## updates the MD5Context with the `input` data of length `len` var input = input var Index = (c.Count[0] shr 3) and 0x3F c.Count[0] = c.count[0] +% toU32(len shl 3) if c.Count[0] < (len shl 3): c.Count[1] = c.count[1] +% 1'i32 c.Count[1] = c.count[1] +% toU32(len shr 29) var PartLen = 64 - Index if len >= PartLen: CopyMem(addr(c.Buffer[Index]), Input, PartLen) transform(addr(c.Buffer), c.State) var i = PartLen while i + 63 < len: Transform(addr(Input[I]), c.State) inc(i, 64) CopyMem(addr(c.Buffer[0]), addr(Input[i]), len-i) else: CopyMem(addr(c.Buffer[Index]), addr(Input[0]), len) proc MD5Final*(c: var MD5Context, digest: var MD5Digest) = ## finishes the MD5Context and stores the result in `digest` var Bits: MD5CBits PadLen: int decode(bits, c.Count) var Index = (c.Count[0] shr 3) and 0x3F if Index < 56: PadLen = 56 - Index else: PadLen = 120 - Index MD5Update(c, padding, PadLen) MD5Update(c, cast[cstring](addr(Bits)), 8) decode(digest, c.State) ZeroMem(addr(c), SizeOf(MD5Context)) proc toMD5*(s: string): MD5Digest = ## computes the MD5Digest value for a string `s` var c: MD5Context MD5Init(c) MD5Update(c, cstring(s), len(s)) MD5Final(c, result) proc `$`*(D: MD5Digest): string = ## converts a MD5Digest value into its string representation const digits = "0123456789abcdef" result = "" for i in 0..15: add(result, Digits[(D[I] shr 4) and 0xF]) add(result, Digits[D[I] and 0xF]) proc getMD5*(s: string): string = ## computes an MD5 value of `s` and returns its string representation var c: MD5Context d: MD5Digest MD5Init(c) MD5Update(c, cstring(s), len(s)) MD5Final(c, d) result = $d proc `==`*(D1, D2: MD5Digest): bool = ## checks if two MD5Digest values are identical for i in 0..15: if D1[i] != D2[i]: return false return true when isMainModule: assert(getMD5("Franz jagt im komplett verwahrlosten Taxi quer durch Bayern") == "a3cca2b2aa1e3b5b3b5aad99a8529074") assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") == "7e716d0e702df0505fc72e2b89467910") assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e")