Thanks for the detailed explanation. Once again thanks to all.
On 6/7/07, Gerrit E.G. Hobbelt <[EMAIL PROTECTED]> wrote:
Stefan Neis wrote: > [...] > No. The functions are there just fine. > _Implementing_ them uses the macros. > > So the definition for SHA1_Update is in that file with the > #define HASH_UPDATE SHA1_Update > It just internally uses the macro to implement it. > It somewhat confusing, but you can use your preprocessor > to understand what's going on. Passing a "-E" (or "/E") instead > of "-c" (or "/c") to the command line that compiles the actual > file should give you the preprocessor output, i.e. the code that > the compiler actually gets to see after the macro substitutions > did take place - that might help to understand what's actually > going on... > I second that. Sound advice there! However, I have a feeling there's a more fundamental issue at hand here. Therefore I'd like to add something that may sound too trivial to you, but please bear with me as I think it will benefit you greatly before you start porting the OpenSSL source code: please check out Kernighan & Ritchie's book 'C, the programming language' where you should pay _special_ attention to the chapters describing the C preprocessor: that the part we're interested in here anyway. An English version is available here (translations to other languages abound): http://www.amazon.com/C-Programming-Language-2nd-Ed/dp/0131103709/ or you probably already have it somewhere in your bookshelf; please revisit for the detailed operation of the ANSI C preprocessor. Before you check out md32_common.h and the crypto/xxx library code you may try your hand at something simpler to easily recognize the inner workings (OpenSSL /E output might be a tad daunting at first): create a project / makefile which compiles 3 C source files to create a Windows console executable using the code listed at the end (I've got a MSVS2005 project zip available if you like: only 4KB): If you can explain to yourself clearly what is happening in fake_common.h and how those fake_MD5() and fake_SHA() functions came to be, you'll also recognize the way md32_common.h et al do this at a much grander scale. When you also wish to understand the ASN1 code, see how these values in the expected output were calculated: 3, 6 and 9. Bottom line: OpenSSL uses the C preprocessor to templatize the code to great effect: reduced code size ( less lines means less bugs) & code reuse (single point to fix bug; no duplications which may be overlooked during maintenance). HTH, Ger PS: the actual C code here is meant as a preprocessor sample only; the sample code is littered with some ugly coding practices. It's the stuff with the # dashes that counts anyway. ---fake_common.h--- /* generic implementation stuff: it's only about recognizing the workings of the C preproc... */ #ifndef __FAKE_HASH_H__ #define __FAKE_HASH_H__ /* another bit of preprocessor stuff; important to understand before you try to understand the ASN1 template code: */ #define get_magic(t) call_magic(t) #define call_magic(t) get_magic_ ## t (3) int get_magic_MD5(int fact); int get_magic_SHA(int fact); int get_magic_FAKE_TYPE(int fact); /* this one is a bit nasty :-) */ /* end of extra bit of stuff */ #define name(f) mkstr(f) #define mkstr(f) # f /* overly simplified piece of md32_common.h */ char *FAKE_HASH(void) { static char buf[256]; sprintf(buf, "I'm '%s()'! and I give you: %d/%d", name(FAKE_HASH), get_magic(FAKE_TYPE), call_magic(FAKE_TYPE)); return buf; } #endif ---------- ---fake_md5.h--- #ifndef __FAKE_MD5_H__ #define __FAKE_MD5_H__ /* prototype only: API */ char *fake_MD5(void); #endif ---------- ---fake_sha.h--- #ifndef __FAKE_SHA_H__ #define __FAKE_SHA_H__ /* prototype only: API */ char *fake_SHA(void); #endif ---------- ---fake_md5.c--- #include <stdlib.h> #include <stdio.h> #include <string.h> #include "fake_md5.h" /* not required, but helps development by prototype validation */ #define FAKE_HASH fake_MD5 #define FAKE_TYPE MD5 #include "fake_common.h" ---------- ---fake_sha.c--- #include <stdlib.h> #include <stdio.h> #include <string.h> #include "fake_sha.h" /* not required, but helps development by prototype validation */ #define FAKE_HASH fake_SHA #define FAKE_TYPE SHA #include "fake_common.h" ---------- ---main.c--- /* expected output of test program: calling fake MD5 --> I'm 'fake_MD5()'! and I give you: 3/9 calling fake SHA --> I'm 'fake_SHA()'! and I give you: 6/9 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "fake_md5.h" #include "fake_sha.h" int main(void) { printf("calling fake MD5 --> %s\n", fake_MD5()); printf("calling fake SHA --> %s\n", fake_SHA()); return 0; } /* next is only relevant for additional ## sample code in fake_common.h */ int get_magic_MD5(int fact) { return 1 * fact; } int get_magic_SHA(int fact) { return 2 * fact; } int get_magic_FAKE_TYPE(int fact) { return 3 * fact; } ---------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [email protected] Automated List Manager [EMAIL PROTECTED]
