------=_Part_32524_16756164.1181217950075
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Thanks for the detailed explanation.

Once again thanks to all.

On 6/7/07, Gerrit E.G. Hobbelt 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-...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
> #include
> #include
>
> #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
> #include
> #include
>
> #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
> #include
> #include
>
> #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 openssl-dev@openssl.org
> Automated List Manager majordomo@openssl.org
>


------=_Part_32524_16756164.1181217950075
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Thanks for the detailed explanation.

Once again thanks to all.

On 6/7/07, Gerrit E.G. Hobbelt <
Ger.Hobbelt@bermuda-holding.com> 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                      
penssl-dev@openssl.org">openssl-dev@openssl.org
Automated List Manager                           majordomo@openssl.org



------=_Part_32524_16756164.1181217950075--
__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org