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]

Reply via email to