From b0cc9c51af59eaf9d9d31527aa8277e353bba65a Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 28 Sep 2008 18:15:28 +0000 Subject: [PATCH] OutStream, TeeStream, Md5Stream, Sha1Stream, Crc32Stream, MD5, SHA1, CRC32, optimized C++ parser, CodeEditor annotations git-svn-id: svn://ultimatepp.org/upp/trunk@487 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CodeEditor/CodeEditor.h | 14 + uppsrc/CodeEditor/EditorBar.cpp | 38 ++- uppsrc/Core/Core.h | 75 +++--- uppsrc/Core/Core.upp | 3 + uppsrc/Core/Hash.h | 58 ++++ uppsrc/Core/MD5.cpp | 386 +++++++++++++++++++++++++++ uppsrc/Core/SHA1.cpp | 209 +++++++++++++++ uppsrc/Core/Stream.cpp | 46 ++++ uppsrc/Core/Stream.h | 29 ++ uppsrc/Core/Util.cpp | 25 ++ uppsrc/Core/Util.h | 3 + uppsrc/Core/src.tpp/AIndex$en-us.tpp | 2 +- uppsrc/Core/z.cpp | 26 +- uppsrc/Core/z.h | 16 +- uppsrc/CppBase/Base.cpp | 372 -------------------------- uppsrc/CppBase/CppBase.h | 54 ++-- uppsrc/CppBase/CppBase.upp | 1 + uppsrc/CppBase/Qualify.cpp | 383 ++++++++++++++++++++++++++ uppsrc/Crypto/Sha1.cpp | 8 +- uppsrc/Web/md5.cpp | 326 +--------------------- uppsrc/ide/Assist.cpp | 1 + uppsrc/ide/Browser/Base.cpp | 45 +--- uppsrc/ide/Browser/Item.cpp | 4 +- uppsrc/ide/Index.cpp | 16 +- uppsrc/ide/ide.h | 2 +- uppsrc/ide/idefile.cpp | 2 +- 26 files changed, 1317 insertions(+), 827 deletions(-) create mode 100644 uppsrc/Core/Hash.h create mode 100644 uppsrc/Core/MD5.cpp create mode 100644 uppsrc/Core/SHA1.cpp create mode 100644 uppsrc/CppBase/Qualify.cpp diff --git a/uppsrc/CodeEditor/CodeEditor.h b/uppsrc/CodeEditor/CodeEditor.h index fbaf57be2..7bc68e3ec 100644 --- a/uppsrc/CodeEditor/CodeEditor.h +++ b/uppsrc/CodeEditor/CodeEditor.h @@ -36,6 +36,7 @@ struct LineInfoRemRecord : Moveable { int firstedited; int edited; }; + typedef Vector LineInfoRem; void Renumber(LineInfo& lf); @@ -59,9 +60,12 @@ private: int error; int firstedited; int edited; + Image icon; + String annotation; LnInfo() { lineno = -1; error = 0; firstedited = 0; edited = 0; } }; + Vector li; LineInfoRem li_removed; @@ -72,11 +76,13 @@ private: bool bingenabled; bool hilite_if_endif; bool line_numbers; + bool annotations; bool ignored_next_edit; int next_age; String& PointBreak(int& y); void sPaintImage(Draw& w, int y, int fy, const Image& img); + void SyncWidth(); public: Callback1 WhenBreakpoint; @@ -104,6 +110,9 @@ public: void SetLineInfo(const LineInfo& li, int total); LineInfoRem & GetLineInfoRem() { return li_removed; } void SetLineInfoRem(pick_ LineInfoRem& li) { li_removed = li; } + + void SetAnnotation(int line, const Image& img, const String& ann); + String GetAnnotation(int line) const; int GetLineNo(int lineno) const; int GetNoLine(int line) const; @@ -114,6 +123,7 @@ public: void EnableBreakpointing(bool b) { bingenabled = b; } void HiliteIfEndif(bool b) { hilite_if_endif = b; Refresh(); } void LineNumbers(bool b); + void Annotations(bool b); bool IsHiliteIfEndif() const { return hilite_if_endif; } @@ -452,6 +462,10 @@ public: void MarkLines(bool b) { mark_lines = b; } bool GetMarkLines() { return mark_lines; } void AutoEnclose(bool b) { auto_enclose = b; } + + void Annotations(bool b) { bar.Annotations(b); } + void SetAnnotation(int i, const Image& icon, const String& a) { bar.SetAnnotation(i, icon, a); } + void GetAnnotation(int i) const { bar.GetAnnotation(i); } void HideBar() { bar.Hide(); } diff --git a/uppsrc/CodeEditor/EditorBar.cpp b/uppsrc/CodeEditor/EditorBar.cpp index fa05787f9..d7382bb4e 100644 --- a/uppsrc/CodeEditor/EditorBar.cpp +++ b/uppsrc/CodeEditor/EditorBar.cpp @@ -75,11 +75,15 @@ void EditorBar::Paint(Draw& w) { String b; int err = 0; int edit = 0; + String ann; + Image icon; if(i < li.GetCount()) { const LnInfo& l = li[i]; b = l.breakpoint; err = l.error; edit = l.edited; + icon = l.icon; + ann = l.annotation; } if(line_numbers && i < editor->GetLineCount()) { String n = AsString(i + 1); @@ -139,6 +143,10 @@ void EditorBar::Paint(Draw& w) { for(int q = 0; q < 2; q++) if(ptri[q] == i) sPaintImage(w, y, fy, ptrimg[q]); + + if(annotations && !IsNull(icon)) + w.DrawImage(sz.cx - 12, y + (fy - icon.GetSize().cy) / 2, icon); + y += fy; i++; } @@ -306,6 +314,19 @@ String EditorBar::GetBreakpoint(int ln) return ln < li.GetCount() ? li[ln].breakpoint : Null; } +void EditorBar::SetAnnotation(int line, const Image& img, const String& ann) +{ + if(line >= 0 && line < li.GetCount()) { + li[line].icon = img; + li[line].annotation = ann; + } +} + +String EditorBar::GetAnnotation(int line) const +{ + return line >= 0 && line < li.GetCount() ? li[line].annotation : String(); +} + void EditorBar::SetBreakpoint(int ln, const String& s) { li.At(ln).breakpoint = s; @@ -405,11 +426,22 @@ void EditorBar::HidePtr() Refresh(); } +void EditorBar::SyncWidth() +{ + Width((line_numbers ? 27 : 12) + annotations * 12); + Refresh(); +} + void EditorBar::LineNumbers(bool b) { line_numbers = b; - Width(b ? 27 : 12); - Refresh(); + SyncWidth(); +} + +void EditorBar::Annotations(bool b) +{ + annotations = b; + SyncWidth(); } EditorBar::EditorBar() { @@ -417,7 +449,7 @@ EditorBar::EditorBar() { editor = NULL; bingenabled = true; hilite_if_endif = true; - line_numbers = false; + line_numbers = annotations = false; ignored_next_edit = false; next_age = 0; } diff --git a/uppsrc/Core/Core.h b/uppsrc/Core/Core.h index fea93088f..08d014aae 100644 --- a/uppsrc/Core/Core.h +++ b/uppsrc/Core/Core.h @@ -398,55 +398,56 @@ inline void operator delete[](void *ptr, const std::nothrow_t&) throw() { UPP:: NAMESPACE_UPP -#include -#include -#include -#include -#include +#include "Mt.h" +#include "Global.h" +#include "Topt.h" +#include "Profile.h" +#include "String.h" -#include -#include -#include -#include -#include +#include "CharSet.h" +#include "TimeDate.h" +#include "Path.h" +#include "Stream.h" +#include "Diag.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "Vcont.h" +#include "BiCont.h" +#include "Index.h" +#include "Map.h" +#include "Other.h" +#include "Algo.h" +#include "Vcont.hpp" +#include "Index.hpp" -#include -#include -#include +#include "Value.h" +#include "Gtypes.h" +#include "Color.h" -#include -#include +#include "Uuid.h" +#include "Ptr.h" -#include -#include +#include "Callback.h" +#include "Util.h" -#include -#include +#include "Format.h" +#include "Convert.h" -#include +#include "z.h" +#include "hash.h" -#include -#include -#include -#include -#include +#include "Parser.h" +#include "XML.h" +#include "Lang.h" +#include "i18n.h" +#include "Topic.h" -#include +#include "App.h" -#include +#include "Xmlize.h" -#include +#include "CoWork.h" -#include +#include "Win32Util.h" #if (defined(HEAPDBG) || defined(TESTLEAKS)) && defined(PLATFORM_POSIX) extern int sMemDiagInitCount; diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index 85370b036..dcef5acd6 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -122,6 +122,9 @@ file Topic.cpp, CoWork.h, CoWork.cpp, + Hash.h, + MD5.cpp, + SHA1.cpp, "Runtime linking" readonly separator, dli.h, dli_header.h, diff --git a/uppsrc/Core/Hash.h b/uppsrc/Core/Hash.h new file mode 100644 index 000000000..a11a3512d --- /dev/null +++ b/uppsrc/Core/Hash.h @@ -0,0 +1,58 @@ +#ifndef _Core_Hash_h_ +#define _Core_Hash_h_ + +/* MD5 context. */ +typedef struct { + dword state[4]; /* state (ABCD) */ + dword count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +class Md5Stream : public OutStream { + MD5_CTX context; + + virtual void Out(const void *data, dword size); + +public: + void Finish(byte *hash16); + String FinishString(); + String FinishStringS(); + + Md5Stream(); + ~Md5Stream(); +}; + +void MD5(byte *hash16, const void *data, dword size); +void MD5(byte *hash16, const String& data); +String MD5String(const void *data, dword size); +String MD5String(const String& data); +String MD5StringS(const void *data, dword size); +String MD5StringS(const String& data); + +class Sha1Stream : public OutStream { + dword state[5]; + byte buffer[64]; + int pos; + dword size; + + virtual void Out(const void *data, dword size); + + void Cleanup(); + +public: + void Finish(byte *hash20); + String FinishString(); + String FinishStringS(); + + Sha1Stream(); + ~Sha1Stream(); +}; + +void SHA1(byte *hash20, const void *data, dword size); +void SHA1(byte *hash20, const String& s); +String SHA1String(const void *data, dword size); +String SHA1String(const String& data); +String SHA1StringS(const void *data, dword size); +String SHA1StringS(const String& data); + +#endif diff --git a/uppsrc/Core/MD5.cpp b/uppsrc/Core/MD5.cpp new file mode 100644 index 000000000..2b57ab1e6 --- /dev/null +++ b/uppsrc/Core/MD5.cpp @@ -0,0 +1,386 @@ +#include "Core.h" + +NAMESPACE_UPP + +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm +*/ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*/ + +/* Constants for MD5Transform routine. +*/ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform (dword [4], const unsigned char [64]); +static void Encode (unsigned char *, const dword *, unsigned int); +static void Decode (dword *, const unsigned char *, unsigned int); +static void MD5_memcpy (void *, const void *, unsigned int); +static void MD5_memset (void *, int, unsigned int); + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (dword)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (dword)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (dword)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (dword)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. +*/ +void MD5Init (MD5_CTX *context) +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. +*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. +*/ +void MD5Update (MD5_CTX *context, const unsigned char *input, dword inputLen) +//MD5_CTX *context; /* context */ +//unsigned char *input; /* input block */ +//unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((dword)inputLen << 3)) < ((dword)inputLen << 3)) + context->count[1]++; + context->count[1] += ((dword)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. +*/ + if (inputLen >= partLen) { + MD5_memcpy + ((void *)&context->buffer[index], (void *)input, partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy((void *)&context->buffer[index], (void *)&input[i], + inputLen-i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. +*/ +void MD5Final (unsigned char *digest, MD5_CTX *context) +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. +*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. +*/ + MD5_memset ((void *)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. +*/ +static void MD5Transform (dword state[4], const unsigned char block[64]) +{ + dword a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + +/* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + +*/ + MD5_memset ((void *)x, 0, sizeof (x)); +} + +/* Encodes input (dword) into output (unsigned char). Assumes len is + a multiple of 4. +*/ +static void Encode (unsigned char *output, const dword *input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (dword). Assumes len is + a multiple of 4. +*/ +static void Decode (dword *output, const unsigned char *input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((dword)input[j]) | (((dword)input[j+1]) << 8) | + (((dword)input[j+2]) << 16) | (((dword)input[j+3]) << 24); +} + +/* Note: Replace "for loop" with standard memcpy if possible. +*/ + +static void MD5_memcpy (void * output, const void * input, unsigned int len) +{ + memcpy(output, input, len); +} + +/* Note: Replace "for loop" with standard memset if possible. +*/ +static void MD5_memset (void * output, int value, unsigned int len) +{ + memset(output, value, len); +} + +// ------------------ U++ code starts here: ---------------------- + +void Md5Stream::Out(const void *data, dword size) +{ + MD5Update (&context, (const unsigned char *)data, size); +} + +void Md5Stream::Finish(byte *hash16) +{ + Flush(); + MD5Final(hash16, &context); +} + +String Md5Stream::FinishString() +{ + byte hash[16]; + Finish(hash); + return HexString(hash, 16); +} + +String Md5Stream::FinishStringS() +{ + byte hash[16]; + Finish(hash); + return HexString(hash, 16, 4); +} + +Md5Stream::Md5Stream() +{ + MD5Init (&context); +} + +Md5Stream::~Md5Stream() +{ + memset(&context, 0, sizeof(context)); +} + +void MD5(byte *hash16, const void *data, dword size) +{ + Md5Stream md5; + md5.Put(data, size); + md5.Finish(hash16); +} + +String MD5String(const void *data, dword size) +{ + Md5Stream md5; + md5.Put(data, size); + return md5.FinishString(); +} + +void MD5(byte *hash16, const String& data) +{ + return MD5(hash16, ~data, data.GetCount()); +} + +String MD5String(const String& data) +{ + return MD5String(~data, data.GetCount()); +} + +String MD5StringS(const void *data, dword size) +{ + Md5Stream md5; + md5.Put(data, size); + return md5.FinishStringS(); +} + +String MD5StringS(const String& data) +{ + return MD5StringS(~data, data.GetCount()); +} + +END_UPP_NAMESPACE diff --git a/uppsrc/Core/SHA1.cpp b/uppsrc/Core/SHA1.cpp new file mode 100644 index 000000000..e20bea20f --- /dev/null +++ b/uppsrc/Core/SHA1.cpp @@ -0,0 +1,209 @@ +#include "Core.h" + +NAMESPACE_UPP + +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* Hash a single 512-bit block. This is the core of the algorithm. */ +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ + +#ifdef COMPILER_MSC +#define rol(value, bits) _rotl(value, bits) +#else +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) +#endif + +#define blk0(i) (block[i] = (rol(block[i],24)&0xFF00FF00)|(rol(block[i],8)&0x00FF00FF)) +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +void SHA1Transform(dword state[5], byte buffer[64]) +{ + dword a, b, c, d, e; + dword *block = (dword *)buffer; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + a = b = c = d = e = 0; +} + +void SHA1Init(dword state[5]) +{ + state[0] = 0x67452301; + state[1] = 0xEFCDAB89; + state[2] = 0x98BADCFE; + state[3] = 0x10325476; + state[4] = 0xC3D2E1F0; +} + +void SHA1Size(byte buffer[64], dword size) +{ + buffer[63] = byte(size << 3); + buffer[62] = byte(size >> 5); + buffer[61] = byte(size >> 13); + buffer[60] = byte(size >> 21); + buffer[59] = byte(size >> 29); + buffer[58] = 0; + buffer[57] = 0; + buffer[56] = 0; +} + +void SHA1Result(byte *hash20, dword state[5]) +{ + for(int i = 0; i < 5; i++) { + const byte *h = (const byte *)&state[i]; + hash20[0] = h[3]; + hash20[1] = h[2]; + hash20[2] = h[1]; + hash20[3] = h[0]; + hash20 += 4; + } +} + +void Sha1Stream::Cleanup() +{ + pos = size = 0; + memset(buffer, 0, sizeof(buffer)); + memset(state, 0, sizeof(state)); +} + +void Sha1Stream::Out(const void *data, dword length) +{ + const byte *s = (const byte *)data; + size += length; + while(pos + length >= 64) { + int n = 64 - pos; + memcpy(buffer + pos, s, n); + SHA1Transform(state, buffer); + s += n; + length -= n; + pos = 0; + } + memcpy(buffer + pos, s, length); + pos += length; +} + +void Sha1Stream::Finish(byte *hash20) +{ + Flush(); + memset(buffer + pos, 0, 64 - pos); + buffer[pos] = 128; + if(pos > 55) { + SHA1Transform(state, buffer); + memset(buffer, 0, 64); + } + SHA1Size(buffer, size); + SHA1Transform(state, buffer); + SHA1Result(hash20, state); + Cleanup(); +} + +String Sha1Stream::FinishString() +{ + byte hash[20]; + Finish(hash); + return HexString(hash, 20); +} + +String Sha1Stream::FinishStringS() +{ + byte hash[20]; + Finish(hash); + return HexString(hash, 20, 4); +} + +Sha1Stream::Sha1Stream() +{ + SHA1Init(state); + pos = 0; + size = 0; +} + +Sha1Stream::~Sha1Stream() +{ + Cleanup(); +} + +void SHA1(byte *hash20, const void *data, dword size) +{ + Sha1Stream sha1; + sha1.Put(data, size); + sha1.Finish(hash20); +} + +void SHA1(byte *hash20, const String& s) +{ + return SHA1(hash20, s, s.GetLength()); +} + +String SHA1String(const void *data, dword size) +{ + Sha1Stream sha1; + sha1.Put(data, size); + return sha1.FinishString(); +} + +String SHA1String(const String& data) +{ + return SHA1String(~data, data.GetLength()); +} + +String SHA1StringS(const void *data, dword size) +{ + Sha1Stream sha1; + sha1.Put(data, size); + return sha1.FinishStringS(); +} + +String SHA1StringS(const String& data) +{ + return SHA1StringS(~data, data.GetLength()); +} + +END_UPP_NAMESPACE diff --git a/uppsrc/Core/Stream.cpp b/uppsrc/Core/Stream.cpp index 15f4b45ab..2cef9e0d5 100644 --- a/uppsrc/Core/Stream.cpp +++ b/uppsrc/Core/Stream.cpp @@ -1182,6 +1182,52 @@ void CompareStream::_Put(int w) { _Put(&b, 1); } +OutStream::OutStream() +{ + buffer = ptr = h; + wrlim = h + sizeof(h); +} + +void OutStream::_Put(int w) +{ + Flush(); + *ptr++ = w; +} + +void OutStream::_Put(const void *data, dword size) +{ + if(ptr == buffer) + Out(data, size); + else + if(ptr + size < wrlim) { + memcpy(ptr, data, size); + ptr += size; + } + else { + Flush(); + Out(data, size); + } +} + +void OutStream::Flush() +{ + if(ptr != buffer) { + Out(buffer, ptr - buffer); + ptr = h; + } +} + +bool OutStream::IsOpen() const +{ + return true; +} + +void TeeStream::Out(const void *data, dword size) +{ + a.Put(data, size); + b.Put(data, size); +} + struct NilStreamClass : public Stream { virtual void _Put(int w) {} virtual bool IsOpen() const { return true; } diff --git a/uppsrc/Core/Stream.h b/uppsrc/Core/Stream.h index 07f62a35f..648830f5c 100644 --- a/uppsrc/Core/Stream.h +++ b/uppsrc/Core/Stream.h @@ -496,6 +496,35 @@ public: CompareStream(Stream& aStream); }; +class OutStream : public Stream { + byte h[128]; +protected: + virtual void _Put(int w); + virtual void _Put(const void *data, dword size); + virtual bool IsOpen() const; + + virtual void Out(const void *data, dword size) = 0; + + void Flush(); + + OutStream(); +}; + +class TeeStream : public OutStream { +protected: + virtual void Out(const void *data, dword size); + +private: + Stream& a; + Stream& b; + +public: + void Close() { Flush(); } + + TeeStream(Stream& a, Stream& b) : a(a), b(b) {} + ~TeeStream() { Close(); } +}; + class FileMapping { public: diff --git a/uppsrc/Core/Util.cpp b/uppsrc/Core/Util.cpp index 9e0e0eff9..dd86bd64d 100644 --- a/uppsrc/Core/Util.cpp +++ b/uppsrc/Core/Util.cpp @@ -501,6 +501,31 @@ String Decode64(const String& s) } } +String HexString(const byte *s, int count, int sep) +{ + StringBuffer b(2 * count + (count - 1) / sep); + static const char itoc[] = "0123456789abcdef"; + int i = 0; + char *t = b; + for(;;) { + for(int q = 0; q < sep; q++) { + if(i >= count) + return b; + *t++ = itoc[(s[i] & 0xf0) >> 4]; + *t++ = itoc[s[i] & 0x0f]; + i++; + } + if(i >= count) + return b; + *t++ = ' '; + } +} + +String HexString(const String& s, int sep) +{ + return HexString(s, s.GetCount(), sep); +} + String NormalizeSpaces(const char *s) { StringBuffer r; diff --git a/uppsrc/Core/Util.h b/uppsrc/Core/Util.h index f55f2eca1..d98b1b397 100644 --- a/uppsrc/Core/Util.h +++ b/uppsrc/Core/Util.h @@ -34,6 +34,9 @@ String Garble(const String& s); String Encode64(const String& s); String Decode64(const String& s); +String HexString(const byte *s, int count, int sep = INT_MAX); +String HexString(const String& s, int sep = INT_MAX); + #ifdef PLATFORM_WINCE WString ToSystemCharset(const String& src); String FromSystemCharset(const WString& src); diff --git a/uppsrc/Core/src.tpp/AIndex$en-us.tpp b/uppsrc/Core/src.tpp/AIndex$en-us.tpp index d87ede1d7..34a163690 100644 --- a/uppsrc/Core/src.tpp/AIndex$en-us.tpp +++ b/uppsrc/Core/src.tpp/AIndex$en-us.tpp @@ -57,7 +57,7 @@ and optional deep copy] transfer semantics, although these features are more important in derived concrete index flavors.&] [s0; &] [ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&] -[s4;%- &] +[s4;H0;%- &] [s5;:`:`:AIndex`:`:Add`(const T`&`,unsigned`):%- [@(0.0.255) void]_[* Add]([@(0.0.255) cons t]_[*@4 T][@(0.0.255) `&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_hash])&] [s2; Adds a new element [%-*@3 x] with a precomputed hash value [%-*@3 `_hash]. diff --git a/uppsrc/Core/z.cpp b/uppsrc/Core/z.cpp index 8884e42a1..ae4d42c98 100644 --- a/uppsrc/Core/z.cpp +++ b/uppsrc/Core/z.cpp @@ -43,26 +43,28 @@ enum RESERVED = 0xE0, /* bits 5..7: reserved */ }; -void Crc32::Put(const void *ptr, int count) +void Crc32Stream::Out(const void *ptr, dword count) { crc = crc32(crc, (byte *)ptr, count); } -void Crc32::Put(char c) -{ - crc = crc32(crc, (byte *)&c, 1); -} - -void Crc32::Put(byte c) -{ - crc = crc32(crc, (byte *)&c, 1); -} - -Crc32::Crc32() +Crc32Stream::Crc32Stream() { crc = crc32(0, NULL, 0); } +dword CRC32(const void *ptr, dword count) +{ + Crc32Stream c; + c.Put(ptr, count); + return c; +} + +dword CRC32(const String& s) +{ + return CRC32(~s, s.GetLength()); +} + static int sZpress(Stream& out, Stream& in, int size, Gate2 progress, bool nohdr, dword *crc, bool compress) { diff --git a/uppsrc/Core/z.h b/uppsrc/Core/z.h index 6f69deb4f..9465f70a7 100644 --- a/uppsrc/Core/z.h +++ b/uppsrc/Core/z.h @@ -1,16 +1,18 @@ -class Crc32 { +class Crc32Stream : public OutStream { dword crc; -public: - void Put(const void *ptr, int count); - void Put(char c); - void Put(byte c); + virtual void Out(const void *data, dword size); - operator dword() const { return crc; } +public: + dword Finish() { Flush(); return crc; } + operator dword() { return Finish(); } - Crc32(); + Crc32Stream(); }; +dword CRC32(const void *ptr, dword count); +dword CRC32(const String& s); + int ZCompress(Stream& out, Stream& in, int size, Gate2 progress = false, bool nohdr = false, dword *crc = NULL); int ZDecompress(Stream& out, Stream& in, int size, Gate2 progress = false, bool nohdr = false, dword *crc = NULL); diff --git a/uppsrc/CppBase/Base.cpp b/uppsrc/CppBase/Base.cpp index 8956bb66f..388d12bc1 100644 --- a/uppsrc/CppBase/Base.cpp +++ b/uppsrc/CppBase/Base.cpp @@ -2,60 +2,9 @@ NAMESPACE_UPP -#ifdef _MSC_VER -#pragma inline_depth(255) -#pragma optimize("t", on) -#endif - #define LLOG(x) #define LTIMING(x) // RTIMING(x) -class Nestfo { - bool bvalid, nvalid; - Vector baselist; - Vector nests; - int nesti; - void Bases(int i, Vector& g); - void Init(); - -public: - const CppBase& base; - VectorMap cache; - - const Vector& GetBases(); - const Vector& GetNests(); - int GetNest() const { return nesti; } - void NoBases() { baselist.Clear(); bvalid = true; } - - Nestfo(const CppBase& base, int nesti = -1); - Nestfo(int nesti, const CppBase& base); - Nestfo(const CppBase& base, const String& nest); - Nestfo(const Nestfo& f); -}; - -void CppWordsHash::AddWord(const String& s) -{ - int i = GetHashValue(s) & 127; - w[i >> 5] |= 1 << (i & 31); -} - -void CppWordsHash::AddWords(const char *s) -{ - CParser p(s); - while(p) - if(p.IsId()) - AddWord(p.ReadId()); - else - p.SkipTerm(); -} - -CppWordsHash AllCppWords() -{ - CppWordsHash h; - h.SetAll(); - return h; -} - CppItem& CppNest::GetAdd(const String& _key, const String& _name) { int i = key.Find(_key); @@ -72,327 +21,6 @@ bool CppBase::IsType(int i) const return GetKey(i) != "::"; } -Nestfo::Nestfo(const CppBase& base, int nesti) - : nesti(nesti), base(base) -{ - Init(); -} - -Nestfo::Nestfo(int nesti, const CppBase& base) - : nesti(nesti), base(base) -{ - Init(); -} - -Nestfo::Nestfo(const CppBase& base, const String& nest) - : nesti(base.Find(nest)), base(base) -{ - Init(); -} - -Nestfo::Nestfo(const Nestfo& f) - : base(f.base) -{ - nests <<= f.nests; - bvalid = nvalid = false; - nesti = f.nesti; -} - -void Nestfo::Init() -{ - bvalid = nvalid = false; -} - -void Nestfo::Bases(int i, Vector& g) -{ - LTIMING("GetBases"); - if(base.IsType(i)) { - const CppNest& n = base.nest[i]; - for(int i = 0; i < n.GetCount(); i++) { - const CppItem& im = n[i]; - if(im.IsType()) { - const char *q = im.qptype; - const char *b = q; - for(;;) { - if(*q == ';' || *q == '\0') { - if(b < q) { - int nq = base.Find(String(b, q)); - if(nq >= 0) - g.Add(nq); - } - if(*q == '\0') - return; - q++; - b = q; - } - else - q++; - } - } - } - } -} - -const Vector& Nestfo::GetBases() -{ - if(!bvalid) { - bvalid = true; - baselist.Clear(); - if(nesti < 0) - return baselist; - Vector b; - Index bi; - Bases(nesti, b); - while(b.GetCount()) { - Vector bb; - for(int i = 0; i < b.GetCount(); i++) { - int q = b[i]; - if(bi.Find(q) < 0) { - bi.Add(q); - Bases(b[i], bb); - } - } - b = bb; - } - for(int i = 0; i < bi.GetCount(); i++) - baselist.Add(base.GetKey(bi[i]) + "::"); - } - return baselist; -} - - -const Vector& Nestfo::GetNests() -{ - if(!nvalid) { - nvalid = true; - nests.Clear(); - if(nesti < 0) - return nests; - String nn = base.GetKey(nesti); - while(nn.GetCount()) { - if(nn[0] == ':' && nn.GetCount() == 2) { - nests.Add(nn); - return nests; - } - nests.Add(nn + "::"); - int q = nn.ReverseFind(':'); - nn.Trim(max(0, q - 1)); - } - nests.Add("::"); - } - return nests; -} - -String Qualify(Nestfo& nf, const String& type); - -String Qualify0(Nestfo& nf, const String& type) -{ - if(IsNull(type) || type == "const" || - type == "int" || type == "double" || type == "long" || type == "char" || type == "void") - return type; - const Vector& nd = nf.GetNests(); - if(type[0] == ':') { - if(nf.base.Find(type) >= 0) - return type; - } - else - if(nd.GetCount()) { - LTIMING("First test"); - String qt = nd[0] + type; - if(nf.base.Find(qt) >= 0) - return qt; - } - if(nf.GetNest() >= 0) { - int q = type.ReverseFind(':'); - if(q >= 0) { - LTIMING("Qualifying qualification"); - Nestfo hnf(nf); - hnf.NoBases(); - String qn = Qualify(hnf, type.Mid(0, max(q - 1, 0))); - if(qn[0] != ':') - return type; - int nesti = nf.base.Find(qn); - if(nesti < 0) - return type; - String tp = type.Mid(q + 1); - Nestfo nnf(nf.base, nesti); - const Vector& bs = nnf.GetBases(); - for(int i = 0; i < bs.GetCount(); i++) { - String qt = bs[i] + tp; - if(nf.base.Find(qt) >= 0) - return qt; - } - } - else { - const Vector& bs = nf.GetBases(); - for(int i = 0; i < bs.GetCount(); i++) { - String qt = bs[i] + type; - if(nf.base.Find(qt) >= 0) - return qt; - } - } - } - if(type[0] != ':') { - LTIMING("Testing nests"); - for(int i = 1; i < nd.GetCount(); i++) { - String qt = nd[i] + type; - if(nf.base.Find(qt) >= 0) - return qt; - } - } - return type; -} - -String Qualify(Nestfo& nf, const String& type) -{ - int q = nf.cache.Find(type); - if(q >= 0) - return nf.cache[q]; - String x = Qualify0(nf, type); - nf.cache.Add(type, x); - return x; -} - -String QualifyIds(Nestfo& nf, const String& k, CppWordsHash& w, bool all) -{ - String r; - CParser p(k); - Vector empty; - while(p) { - if(p.IsChar2(':', ':')) { - String t; - while(p.Char2(':', ':')) { - t << "::"; - if(p.IsId()) { - String id = p.ReadId(); - w.AddWord(id); - t << id; - } - } - Nestfo nnf(nf.GetNest(), nf.base); - if(all) - t = Qualify(nnf, t); - if(iscid(*r.Last()) && iscid(*t)) - r << ' '; - r << t; - } - else - if(p.IsId()) { - String t = p.ReadId(); - w.AddWord(t); - while(p.Char2(':', ':')) { - t << "::"; - if(p.IsId()) { - String id = p.ReadId(); - w.AddWord(id); - t << id; - } - } - if(all) - t = Qualify(nf, t); - if(iscid(*r.Last()) && iscid(*t)) - r << ' '; - r << t; - } - else { - int c = p.GetChar(); - if(c == '(') - all = true; - r.Cat(c); - p.Spaces(); - } - } - return r; -} - -String Qualify(const CppBase& base, const String& nest, const String& type) -{ - CppWordsHash dummy; - Nestfo nf(base, nest); - return QualifyIds(nf, type, dummy, true); -} - -String QualifyKey(const CppBase& base, const String& nest, const String& type) -{ - CppWordsHash dummy; - Nestfo nf(base, nest); - return QualifyIds(nf, type, dummy, false); -} - -void QualifyTypes(Nestfo& nf, CppItem& m) -{ - m.qtype = QualifyIds(nf, m.type, m.words, true); - m.qptype = QualifyIds(nf, m.ptype, m.words, true); -} - -void QualifyTypes(CppBase& base, const String& nest, CppItem& m) -{ - Nestfo nf(base, nest); - QualifyTypes(nf, m); -} - -void QualifyPass1(CppBase& base, const CppWordsHash& words) -{ - LTIMING("Qualify1"); - for(int ni = 0; ni < base.GetCount(); ni++) { - CppNest& n = base[ni]; - Nestfo nf(base, ni); - for(int i = 0; i < n.GetCount(); i++) { - CppItem& m = n.item[i]; - if((m.words.IsAll() || (m.words & words)) && m.IsType()) { - m.words.Clear(); - QualifyTypes(nf, m); - } - } - } -} - -void QualifyPass2(CppBase& base, const CppWordsHash& words) -{ - LTIMING("Qualify2"); - for(int ni = 0; ni < base.GetCount(); ni++) { - CppNest& n = base[ni]; - Nestfo nf(base, ni); - Index rem; - for(int i = 0; i < n.GetCount(); i++) { - CppItem& m = n.item[i]; - if((m.words.IsAll() || (words & m.words)) && !m.IsType()) { - m.words.Clear(); - QualifyTypes(nf, m); - if(m.IsCode()) { - String k = n.key[i]; - String r = QualifyIds(nf, m.key, m.words, false); - if(k != r) { - int q = n.key.Find(r); - if(q >= 0 && q != i) - if(m.decla) { - m.pos.Append(n.item[q].pos); - rem.FindAdd(q); - n.key.Set(i, r); - } - else { - n.item[q].pos.Append(m.pos); - rem.FindAdd(i); - } - else - n.key.Set(i, r); - } - } - } - } - Vector rm = rem.PickKeys(); - Sort(rm); - n.Remove(rm); - } -} - -void Qualify(CppBase& base, const CppWordsHash& words) -{ - LTIMING("Qualify"); - QualifyPass1(base, words); - QualifyPass2(base, words); -} - void Remove(CppBase& base, const Vector& pf) { int ni = 0; diff --git a/uppsrc/CppBase/CppBase.h b/uppsrc/CppBase/CppBase.h index b3e3f9505..ecaa49e16 100644 --- a/uppsrc/CppBase/CppBase.h +++ b/uppsrc/CppBase/CppBase.h @@ -15,26 +15,6 @@ enum { #undef CPPID }; -class CppWordsHash { - dword w[4]; - -public: - void Clear() { w[0] = w[1] = w[2] = w[3] = 0; } - void SetAll() { w[0] = w[1] = w[2] = w[3] = ~0; } - void AddWord(const String& s); - void AddWords(const char *s); - - bool operator&(const CppWordsHash& b) const { - return (w[0] & b.w[0]) | (w[1] & b.w[1]) | (w[2] & b.w[2]) | (w[3] & b.w[3]); - } - - bool IsAll() const { return (w[0] & w[1] & w[2] & w[3]) == (dword)~0; } - - CppWordsHash() { Clear(); } -}; - -CppWordsHash AllCppWords(); - enum { t_eof, t_string = -200, @@ -265,11 +245,12 @@ struct CppSimpleItem { struct CppItem : CppSimpleItem { Vector pos; String key; - CppWordsHash words; + byte qualify_type, qualify_param; + int serial; void Serialize(Stream& s); - CppItem() { words.SetAll(); } + CppItem() { qualify_type = qualify_param = true; serial = 0; } }; struct CppNest { @@ -288,6 +269,8 @@ struct CppNest { struct CppBase { ArrayMap nest; + int serial; + String serial_md5; CppNest& operator[](int i) { return nest[i]; } int GetCount() const { return nest.GetCount(); } @@ -297,6 +280,8 @@ struct CppBase { CppNest& GetAdd(const String& s) { return nest.GetAdd(s); } bool IsType(int i) const; + + CppBase() { serial = 0; } }; class Parser { @@ -458,11 +443,34 @@ public: String NoTemplatePars(const String& type); +class Nestfo { + bool bvalid, nvalid; + Vector baselist; + Vector nests; + int nesti; + void Bases(int i, Vector& g); + void Init(); + +public: + const CppBase& base; + VectorMap cache; + + const Vector& GetBases(); + const Vector& GetNests(); + int GetNest() const { return nesti; } + void NoBases() { baselist.Clear(); bvalid = true; } + + Nestfo(const CppBase& base, int nesti = -1); + Nestfo(int nesti, const CppBase& base); + Nestfo(const CppBase& base, const String& nest); + Nestfo(const Nestfo& f); +}; + String Qualify(const CppBase& base, const String& nest, const String& type); void QualifyTypes(CppBase& base, const String& nest, CppItem& m); String QualifyKey(const CppBase& base, const String& nest, const String& type); -void Qualify(CppBase& base, const CppWordsHash& words); +void Qualify(CppBase& base); void Parse(Stream& s, const Vector& ignore, CppBase& base, const String& fn, Callback2 err); diff --git a/uppsrc/CppBase/CppBase.upp b/uppsrc/CppBase/CppBase.upp index 70e431bac..4bf78e4a3 100644 --- a/uppsrc/CppBase/CppBase.upp +++ b/uppsrc/CppBase/CppBase.upp @@ -12,6 +12,7 @@ file cpplex.cpp, Parser.cpp, Base.cpp, + Qualify.cpp, Info readonly separator, Copying; diff --git a/uppsrc/CppBase/Qualify.cpp b/uppsrc/CppBase/Qualify.cpp new file mode 100644 index 000000000..507bc49ee --- /dev/null +++ b/uppsrc/CppBase/Qualify.cpp @@ -0,0 +1,383 @@ +#include "CppBase.h" + +NAMESPACE_UPP + +#define LLOG(x) +#define LTIMING(x) // RTIMING(x) + +Nestfo::Nestfo(const CppBase& base, int nesti) + : nesti(nesti), base(base) +{ + LTIMING("Nestfo(const CppBase& base, int nesti)"); + Init(); +} + +Nestfo::Nestfo(int nesti, const CppBase& base) + : nesti(nesti), base(base) +{ + LTIMING("Nestfo(int nesti, const CppBase& base)"); + Init(); +} + +Nestfo::Nestfo(const CppBase& base, const String& nest) + : nesti(base.Find(nest)), base(base) +{ + LTIMING("Nestfo(const CppBase& base, const String& nest)"); + Init(); +} + +Nestfo::Nestfo(const Nestfo& f) + : base(f.base) +{ + LTIMING("Nestfo copy contructor"); + nests <<= f.nests; + bvalid = nvalid = false; + nesti = f.nesti; +} + +void Nestfo::Init() +{ + bvalid = nvalid = false; +} + +void Nestfo::Bases(int i, Vector& g) +{ + if(base.IsType(i)) { + const CppNest& n = base.nest[i]; + for(int i = 0; i < n.GetCount(); i++) { + const CppItem& im = n[i]; + if(im.IsType()) { + const char *q = im.qptype; + const char *b = q; + for(;;) { + if(*q == ';' || *q == '\0') { + if(b < q) { + int nq = base.Find(String(b, q)); + if(nq >= 0) + g.Add(nq); + } + if(*q == '\0') + return; + q++; + b = q; + } + else + q++; + } + } + } + } +} + +const Vector& Nestfo::GetBases() +{ + LTIMING("GetBases"); + if(!bvalid) { + bvalid = true; + baselist.Clear(); + if(nesti < 0) + return baselist; + Vector b; + Index bi; + Bases(nesti, b); + while(b.GetCount()) { + Vector bb; + for(int i = 0; i < b.GetCount(); i++) { + int q = b[i]; + if(bi.Find(q) < 0) { + bi.Add(q); + Bases(b[i], bb); + } + } + b = bb; + } + for(int i = 0; i < bi.GetCount(); i++) + baselist.Add(base.GetKey(bi[i]) + "::"); + } + return baselist; +} + +const Vector& Nestfo::GetNests() +{ + LTIMING("GetNests"); + if(!nvalid) { + nvalid = true; + nests.Clear(); + if(nesti < 0) + return nests; + String nn = base.GetKey(nesti); + while(nn.GetCount()) { + if(nn[0] == ':' && nn.GetCount() == 2) { + nests.Add(nn); + return nests; + } + nests.Add(nn + "::"); + int q = nn.ReverseFind(':'); + nn.Trim(max(0, q - 1)); + } + nests.Add("::"); + } + return nests; +} + +String DoQualify(Nestfo& nf, const String& type); + +String Qualify0(Nestfo& nf, const String& type) +{ + const Vector& nd = nf.GetNests(); + if(type[0] == ':') { + LTIMING(":: test"); + if(nf.base.Find(type) >= 0) + return type; + } + else + if(nd.GetCount()) { + LTIMING("First test"); + String qt = nd[0] + type; + if(nf.base.Find(qt) >= 0) + return qt; + } + if(nf.GetNest() >= 0) { + int q = type.ReverseFind(':'); + if(q >= 0) { + LTIMING("Qualifying qualification"); + Nestfo hnf(nf); + hnf.NoBases(); + String qn = DoQualify(hnf, type.Mid(0, max(q - 1, 0))); + if(qn[0] != ':') + return type; + int nesti = nf.base.Find(qn); + if(nesti < 0) + return type; + String tp = type.Mid(q + 1); + Nestfo nnf(nf.base, nesti); + const Vector& bs = nnf.GetBases(); + for(int i = 0; i < bs.GetCount(); i++) { + String qt = bs[i] + tp; + if(nf.base.Find(qt) >= 0) + return qt; + } + } + else { + LTIMING("Bases"); + const Vector& bs = nf.GetBases(); + for(int i = 0; i < bs.GetCount(); i++) { + String qt = bs[i] + type; + if(nf.base.Find(qt) >= 0) + return qt; + } + } + } + if(type[0] != ':') { + LTIMING("Testing nests"); + for(int i = 1; i < nd.GetCount(); i++) { + String qt = nd[i] + type; + if(nf.base.Find(qt) >= 0) + return qt; + } + } + return type; +} + +String DoQualify(Nestfo& nf, const String& type) +{ + LTIMING("Qualify"); + int q = nf.cache.Find(type); + if(q >= 0) + return nf.cache[q]; + LTIMING("Qualify0"); + String x = Qualify0(nf, type); + nf.cache.Add(type, x); + return x; +} + +static String s_int("int"); +static String s_void("void"); +static String s_double("double"); +static String s_char("char"); +static String s_float("float"); +static String s_long("long"); +static String s_const("const"); +static String s_struct("struct"); +static String s_class("class"); +static String s_unsigned("unsigned"); + +inline void Qualify(String& r, Nestfo& nf, const char *b, const char *s, byte& qual) +{ + String type(b, s); + if(type.GetCount() == 0 || type == s_const || + type == s_int || type == s_double || type == s_char || + type == s_long || type == s_unsigned || type == s_struct || type == s_class || + type == s_float) + return; + r << DoQualify(nf, type); +} + +String QualifyIds(Nestfo& nf, const String& k, bool all, byte& qual) +{ + LTIMING("QualifyIds"); + String r; + const char *s = k; + Vector empty; + while(*s) { + int c = *s; + if(c == ':') { + const char *b = s++; + while(*s == ':' || iscid(*s)) s++; + if(all) { + Nestfo nnf(nf.GetNest(), nf.base); + Qualify(r, nnf, b, s, qual); + } + else + r.Cat(b, s); + } + else + if(iscid(c)) { + const char *b = s++; + while(*s == ':' || iscid(*s)) s++; + if(iscid(*r.Last())) + r << ' '; + if(all) + Qualify(r, nf, b, s, qual); + else + r.Cat(b, s); + } + else { + if(c == '(') + all = true; + r.Cat(c); + s++; + while(*s == ' ') s++; + } + } + return r; +} + +String Qualify(const CppBase& base, const String& nest, const String& type) +{ + Nestfo nf(base, nest); + byte dummy = 2; + return QualifyIds(nf, type, true, dummy); +} + +String QualifyKey(const CppBase& base, const String& nest, const String& type) +{ + Nestfo nf(base, nest); + byte dummy = 2; + return QualifyIds(nf, type, false, dummy); +} + +void QualifyTypes(CppBase& base, const String& nest, CppItem& m) +{ + Nestfo nf(base, nest); + m.qtype = QualifyIds(nf, m.type, true, m.qualify_type); + m.qptype = QualifyIds(nf, m.ptype, true, m.qualify_param); +} + +void QualifyPass1(CppBase& base) +{ + LTIMING("QualifyPass1"); + for(int ni = 0; ni < base.GetCount(); ni++) { + CppNest& n = base[ni]; + Nestfo nf(base, ni); + for(int i = 0; i < n.GetCount(); i++) { + CppItem& m = n.item[i]; + if(m.serial != base.serial && m.IsType()) { + m.serial = base.serial; + if(m.qualify_type) { + m.qualify_type = false; + m.qtype = QualifyIds(nf, m.type, true, m.qualify_type); + } + if(m.qualify_param) { + m.qualify_param = false; + m.qptype = QualifyIds(nf, m.ptype, true, m.qualify_param); + } + } + } + } +} + +void QualifyPass2(CppBase& base) +{ + LTIMING("QualifyPass2"); + for(int ni = 0; ni < base.GetCount(); ni++) { + CppNest& n = base[ni]; + Nestfo nf(base, ni); + Index rem; + String prev_type, prev_qtype; + byte prev_qualify = 0; + for(int i = 0; i < n.GetCount(); i++) { + CppItem& m = n.item[i]; + if(m.serial != base.serial && !m.IsType()) { + m.serial = base.serial; + if(m.qualify_type) { + if(m.type == prev_type) { + m.qtype = prev_qtype; + m.qualify_type = prev_qualify; + } + else { + m.qualify_type = false; + m.qtype = QualifyIds(nf, m.type, true, m.qualify_type); + prev_type = m.type; + prev_qtype = m.qtype; + prev_qualify = m.qualify_type; + } + } + if(m.qualify_param) { + m.qualify_param = false; + m.qptype = QualifyIds(nf, m.ptype, true, m.qualify_param); + if(m.IsCode()) { + String k = n.key[i]; + String r = QualifyIds(nf, m.key, false, m.qualify_param); + if(k != r) { + LTIMING("Key adjustment"); + int q = n.key.Find(r); + if(q >= 0 && q != i) + if(m.decla) { + m.pos.Append(n.item[q].pos); + rem.FindAdd(q); + n.key.Set(i, r); + } + else { + n.item[q].pos.Append(m.pos); + rem.FindAdd(i); + } + else + n.key.Set(i, r); + } + } + } + } + } + LTIMING("Key removal"); + Vector rm = rem.PickKeys(); + Sort(rm); + n.Remove(rm); + } +} + +void Qualify(CppBase& base) +{ + Md5Stream md5; + Vector no = GetSortOrder(base.nest.GetKeys()); + for(int q = 0; q < base.GetCount(); q++) { + int ni = no[q]; + md5 << base.GetKey(ni); + const CppNest& n = base.nest[ni]; + for(int i = 0; i < n.GetCount(); i++) { + const CppItem& m = n[i]; + if(m.IsType()) + md5 << ';' << m.ptype; + } + md5 << '\n'; + } + String c5 = md5.FinishString(); + if(c5 != base.serial_md5) { + base.serial++; + base.serial_md5 = c5; + } + QualifyPass1(base); + QualifyPass2(base); +} + +END_UPP_NAMESPACE diff --git a/uppsrc/Crypto/Sha1.cpp b/uppsrc/Crypto/Sha1.cpp index 92be9877a..5931adcd5 100644 --- a/uppsrc/Crypto/Sha1.cpp +++ b/uppsrc/Crypto/Sha1.cpp @@ -126,8 +126,8 @@ String SHA1(const void *data, dword length) { SHA1Transform(state, buffer); String r = SHA1Result(state); size = 0; - memset(buffer, 0, 64); - memset(state, 0, 5); + memset(buffer, 0, sizeof(buffer)); + memset(state, 0, sizeof(state)); return r; } @@ -169,8 +169,8 @@ Sha1::Sha1() { } Sha1::~Sha1() { - memset(buffer, 0, 64); - memset(state, 0, 5); + memset(buffer, 0, sizeof(buffer)); + memset(state, 0, sizeof(state)); } END_UPP_NAMESPACE diff --git a/uppsrc/Web/md5.cpp b/uppsrc/Web/md5.cpp index 14b4c14e7..3ef22cb9b 100644 --- a/uppsrc/Web/md5.cpp +++ b/uppsrc/Web/md5.cpp @@ -2,335 +2,11 @@ NAMESPACE_UPP -/* MD5 context. */ -typedef struct { - dword state[4]; /* state (ABCD) */ - dword count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD5_CTX; - -void MD5Init (MD5_CTX *); -void MD5Update (MD5_CTX *, const unsigned char *, unsigned int); -void MD5Final (unsigned char [16], MD5_CTX *); - String MD5Digest(const char *text, int length) { - MD5_CTX context; unsigned char digest[16]; - - MD5Init (&context); - MD5Update (&context, (const unsigned char *)text, length); - MD5Final (digest, &context); - + MD5(digest, text, length); return String(digest, 16); } -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm -*/ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. -*/ - -/* Constants for MD5Transform routine. -*/ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform (dword [4], const unsigned char [64]); -static void Encode (unsigned char *, const dword *, unsigned int); -static void Decode (dword *, const unsigned char *, unsigned int); -static void MD5_memcpy (void *, const void *, unsigned int); -static void MD5_memset (void *, int, unsigned int); - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. -*/ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. -*/ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. -*/ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (dword)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (dword)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (dword)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (dword)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. -*/ -void MD5Init (MD5_CTX *context) -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. -*/ -void MD5Update (MD5_CTX *context, const unsigned char *input, unsigned int inputLen) -//MD5_CTX *context; /* context */ -//unsigned char *input; /* input block */ -//unsigned int inputLen; /* length of input block */ -{ - unsigned int i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((dword)inputLen << 3)) < ((dword)inputLen << 3)) - context->count[1]++; - context->count[1] += ((dword)inputLen >> 29); - - partLen = 64 - index; - - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - MD5_memcpy - ((void *)&context->buffer[index], (void *)input, partLen); - MD5Transform (context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - index = 0; - } - else - i = 0; - - /* Buffer remaining input */ - MD5_memcpy((void *)&context->buffer[index], (void *)&input[i], - inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. -*/ -void MD5Final (unsigned char *digest, MD5_CTX *context) -{ - unsigned char bits[8]; - unsigned int index, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. -*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. -*/ - MD5_memset ((void *)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. -*/ -static void MD5Transform (dword state[4], const unsigned char block[64]) -{ - dword a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - -/* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. - -*/ - MD5_memset ((void *)x, 0, sizeof (x)); -} - -/* Encodes input (dword) into output (unsigned char). Assumes len is - a multiple of 4. -*/ -static void Encode (unsigned char *output, const dword *input, unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (dword). Assumes len is - a multiple of 4. -*/ -static void Decode (dword *output, const unsigned char *input, unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((dword)input[j]) | (((dword)input[j+1]) << 8) | - (((dword)input[j+2]) << 16) | (((dword)input[j+3]) << 24); -} - -/* Note: Replace "for loop" with standard memcpy if possible. -*/ - -static void MD5_memcpy (void * output, const void * input, unsigned int len) -{ - memcpy(output, input, len); -} - -/* Note: Replace "for loop" with standard memset if possible. -*/ -static void MD5_memset (void * output, int value, unsigned int len) -{ - memset(output, value, len); -} - END_UPP_NAMESPACE diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index 5b6cf781e..8dbe94893 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -41,6 +41,7 @@ AssistEditor::AssistEditor() searchindex.SetFilter(CharFilterAlphaToUpper); searchindex <<= THISBACK(SearchIndex); showindex = true; + Annotations(true); } Vector TemplatePars(const String& type) diff --git a/uppsrc/ide/Browser/Base.cpp b/uppsrc/ide/Browser/Base.cpp index 58317a987..9e64e44af 100644 --- a/uppsrc/ide/Browser/Base.cpp +++ b/uppsrc/ide/Browser/Base.cpp @@ -153,15 +153,15 @@ void LoadBrowserBase(Progress& pi) } } -void FinishBase(const CppWordsHash& w) +void FinishBase() { TimeStop tm; - Qualify(BrowserBase(), w); + Qualify(BrowserBase()); } void ReQualifyBrowserBase() { - Qualify(BrowserBase(), AllCppWords()); + Qualify(BrowserBase()); } Vector SortedNests() @@ -176,33 +176,6 @@ Vector SortedNests() return n; } -CppWordsHash Difference(const Vector& a) -{ - TimeStop tm; - Vector b = SortedNests(); - CppWordsHash h; - int ai = 0; - int bi = 0; - while(ai < a.GetCount() && bi < b.GetCount()) { - int q = SgnCompare(a[ai], b[bi]); - if(q < 0) - h.AddWords(a[ai++]); - else - if(q > 0) - h.AddWords(b[bi++]); - else { - ai++; - bi++; - } - } - while(ai < a.GetCount()) - h.AddWords(a[ai++]); - while(bi < b.GetCount()) - h.AddWords(b[bi++]); - LLOG("Difference " << tm); - return h; -} - void UpdateBrowserBase(Progress& pi) { Index fp; @@ -271,8 +244,6 @@ void BrowserBaseScan(Stream& s, const String& fn) { LTIMING("BrowserBaseScan"); TimeStop tm; - Vector before = SortedNests(); - LLOG("Scan1 " << tm); CppBase& base = BrowserBase(); LLOG("Scan2 " << tm); Vector remove; @@ -281,7 +252,7 @@ void BrowserBaseScan(Stream& s, const String& fn) LLOG("Scan3 " << tm); Parse(s, IgnoreList(), base, fn, CNULL); LLOG("Scan4 " << tm); - FinishBase(Difference(before)); + FinishBase(); LLOG("Scan total " << tm); LLOG("---------"); } @@ -295,7 +266,7 @@ void BrowserBaseScanLay(const String& fn) remove.Add(fn); Remove(base, remove); ScanLayFile(fn); - FinishBase(Difference(before)); + FinishBase(); } void ClearBrowserBase() @@ -314,7 +285,7 @@ void StartBrowserBase() pi.Title("Assist++"); LoadBrowserBase(pi); UpdateBrowserBase(pi); - FinishBase(AllCppWords()); + FinishBase(); } start--; } @@ -325,7 +296,7 @@ void SyncBrowserBase() Progress pi; pi.Title("Assist++"); UpdateBrowserBase(pi); - FinishBase(AllCppWords()); + FinishBase(); } } @@ -336,7 +307,7 @@ void RescanBrowserBase() Progress pi; pi.Title("Assist++"); UpdateBrowserBase(pi); - FinishBase(AllCppWords()); + FinishBase(); s_console = false; } diff --git a/uppsrc/ide/Browser/Item.cpp b/uppsrc/ide/Browser/Item.cpp index 74dd9a8e4..05e6b8529 100644 --- a/uppsrc/ide/Browser/Item.cpp +++ b/uppsrc/ide/Browser/Item.cpp @@ -5,7 +5,7 @@ bool IsCppKeyword(const String& id) { static Index kw; - if(kw.GetCount() == 0) { + ONCELOCK { const char **cppk = CppKeyword(); for(int i = 0; cppk[i]; i++) kw.Add(cppk[i]); @@ -20,7 +20,7 @@ bool IsCppType(const String& id) "const", "mutable", "struct", "class", "union" }; static Index kt; - if(kt.GetCount() == 0) { + ONCELOCK { for(int i = 0; i < __countof(t); i++) kt.Add(t[i]); } diff --git a/uppsrc/ide/Index.cpp b/uppsrc/ide/Index.cpp index 19be50f98..5290ba494 100644 --- a/uppsrc/ide/Index.cpp +++ b/uppsrc/ide/Index.cpp @@ -1,7 +1,19 @@ #include "ide.h" -void AssistEditor::CreateIndex() +void AssistEditor::CreateIndex(const String& filename) { + int fi = GetCppFileIndex(filename); + CppBase& base = BrowserBase(); + for(int j = 0; j < base.GetCount(); j++) { + CppNest& nest = base[j]; + for(int k = 0; k < nest.GetCount(); k++) { + CppItem& m = nest.item[k]; + for(int p = 0; p < m.pos.GetCount(); p++) { + if(m.pos[p].file == fi) + SetAnnotation(m.pos[p].line - 1, BrowserImg::Ref(), ""); + } + } + } searchindex.Clear(); Renumber2(); indexitem.Clear(); @@ -225,7 +237,7 @@ void AssistEditor::ShowIndex(bool b) indexframe.Show(showindex); if(showindex) { SetFocus(); - CreateIndex(); +// CreateIndex(); SyncIndex(); SyncIndexCursor(); } diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index dcb4c840f..023c5350b 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -420,7 +420,7 @@ struct AssistEditor : CodeEditor { void SwapSContext(Parser& p); - void CreateIndex(); + void CreateIndex(const String& filename); void SyncIndex(); void IndexSync(); diff --git a/uppsrc/ide/idefile.cpp b/uppsrc/ide/idefile.cpp index e4969b1dd..ae3fb640f 100644 --- a/uppsrc/ide/idefile.cpp +++ b/uppsrc/ide/idefile.cpp @@ -434,7 +434,7 @@ void Ide::EditFile0(const String& path, byte charset, bool astext, const String& SetBar(); editor.assist_active = IsProjectFile(editfile) && (IsCSourceFile(editfile) || IsCHeaderFile(editfile)); editor.CheckEdited(true); - editor.CreateIndex(); + editor.CreateIndex(editfile); } void Ide::EditAsText()