jstedfast / gmime

A C/C++ MIME creation and parser library with support for S/MIME, PGP, and Unix mbox spools.
GNU Lesser General Public License v2.1
111 stars 36 forks source link

The samples from README wont compile #117

Closed emdete closed 2 years ago

emdete commented 2 years ago

It seems the samples in the README are outdated. First one i tried did not compile. I suggest to move the code into the sample directory, add links from the README and add its build to the test flow.

What do you think?

jstedfast commented 2 years ago

Which sample?

emdete commented 2 years ago

The ones in the README ;)

For example this one:

GMimeMessage *message;
GMimePart *body;

message = g_mime_message_new (TRUE);

g_mime_message_add_mailbox (message, GMIME_ADDRESS_TYPE_FROM, "Joey", "joey@friends.com");
g_mime_message_add_mailbox (message, GMIME_ADDRESS_TYPE_TO, "Alice", "alice@wonderland.com");
g_mime_message_set_subject (message, "How you doin?", NULL);

body = g_mime_text_part_new_with_subtype ("plain");
g_mime_text_part_set_text (body, "Hey Alice,\n\n"
    "What are you up to this weekend? Monica is throwing one of her parties on\n"
    "Saturday and I was hoping you could make it.\n\n"
    "Will you be my +1?\n\n"
    "-- Joey\n");

g_mime_message_set_mime_part (message, (GMimeObject *) body);
g_object_unref (body);

gives (ok, it compiles, but it gives warnings, and it finally cores):

cc `pkg-config --cflags gmime-3.0`   -c -o m.o m.c                                                                                                                    
m.c: In function ‘main’:
m.c:14:6: warning: assignment to ‘GMimePart *’ {aka ‘struct _GMimePart *’} from incompatible pointer type ‘GMimeTextPart *’ {aka ‘struct _GMimeTextPart *’} [-Wincompatible-po
inter-types]
   14 | body = g_mime_text_part_new_with_subtype ("plain");
      |      ^
m.c:15:28: warning: passing argument 1 of ‘g_mime_text_part_set_text’ from incompatible pointer type [-Wincompatible-pointer-types]
   15 | g_mime_text_part_set_text (body, "Hey Alice,\n\n"
      |                            ^~~~
      |                            |
      |                            GMimePart * {aka struct _GMimePart *}
In file included from /usr/include/gmime-3.0/gmime/gmime.h:37,
                 from m.c:1:
/usr/include/gmime-3.0/gmime/gmime-text-part.h:65:48: note: expected ‘GMimeTextPart *’ {aka ‘struct _GMimeTextPart *’} but argument is of type ‘GMimePart *’ {aka ‘struct _GMi
mePart *’}
   65 | void g_mime_text_part_set_text (GMimeTextPart *mime_part, const char *text);
      |                                 ~~~~~~~~~~~~~~~^~~~~~~~~
gcc -o m m.o `pkg-config --libs gmime-3.0`
LANG=C ./m
Segmentation fault

I love the samples because those are boiled down to the bare minimum - it can speed up learning gmime alot, but those samples should compile & work. This could be achieved by putting those into the test cycle (still keeping it to the bare minimum of code).

jstedfast commented 2 years ago

The samples need g_mime_init(), but the problem with that is that you would not be putting a g_mime_init() in every function of your code.

These sample snippets are meant to show how to do common tasks. They are not meant to be full programs.

If you want a full program, check the examples/ directory.

jstedfast commented 2 years ago

Also,

The ones in the README ;)

Is not helpful because there are a bunch of snippets. I need specifics :)

emdete commented 2 years ago

I had troubles with each of the samples from the README, even adding the init doesnt remove the warnings and i think learning-code should be warning free ;)

sure, i checked the examples/ as well but those do not contain one that creates an email, adding attachment, encrypt, use autocrypt and alll the fine features gmime provides.

jstedfast commented 2 years ago

If you could paste your full program for each sample and the compile warnings you got, I'll fix them. I don't have a Linux machine anymore so I can't do it myself.

jstedfast commented 2 years ago

The only compile errors I've seen so far are GMimePart vs GMimeTextPart (GMimeTextPart subclasses GMimePart, so it's fine, but does present warnings). GMimeTextPart was added more recently (2 or 3 years ago?) to make setting/getting text simpler for the average user - before they would have to manipulate a GMimePart directly to get it.

jstedfast commented 2 years ago

Found/fixed a compile error for getting the mbox marker & offset from the parser.

emdete commented 2 years ago

I wrote a small script to compile all samples:

#!/usr/bin/env python3    
from subprocess import call    
s = None    
no = 0    
with open('../README') as r:    
    for line in r.readlines():    
        line = line.strip()    
        if line == '```c':    
            s = open(f'{no:02}.c', 'w')    
            print('#include <stdio.h>', file=s)    
            print('#include <stdlib.h>', file=s)    
            print('#include <string.h>', file=s)    
            print('#include <fcntl.h>', file=s)    
            print('#include <time.h>', file=s)    
            print('#include <glib.h>', file=s)    
            print('#include <glib/gstdio.h>', file=s)    
            print('', file=s)    
            print('#include <gmime/gmime.h>', file=s)    
            print('', file=s)    
            print('int main() {', file=s)    
            print('g_mime_init();', file=s)    
            print('g_mime_charset_map_init();', file=s)    
        elif s and line == '```':    
            print('g_mime_shutdown();', file=s)    
            print('return 0;', file=s)    
            print('}', file=s)    
            s.close()    
            retcode = call(f'gcc $(pkg-config --cflags gmime-3.0) -o {no:02} {no:02}.c $(pkg-config --libs gmime-3.0)', shell=True)    
            s = None    
            no += 1    
        elif s:    
            print(line, file=s) 

so it's easy to see the warnings & errors (for example g_mime_parser_construct_message is called with one instead of two args). Full log is https://mister-muffin.de/p/vmXN.c

jstedfast commented 2 years ago

They should all be fixed now, but you can't expect your script to produce clean builds for all of the samples because some of them call functions like CreateMessage() that is up to you to implement.

Also, don't call g_mime_charset_map_init() directly - let g_mime_init() call that.

emdete commented 2 years ago

Thank you!

How about putting a plain

GMimeMessage *message;

into the sample to make clear that this is needed and make the samples compile? The type safe G-cast-macros like GMIME_OBJECT could be added too. About the samples that need each other i need to think..

I think it would be cool if the samples compile to see if they still fit after changes. They could go into the test cycle. Outdated samples are a waste of time for newbies like myself ;)

i didnt know about the other init, the doc doesnt tell. Maybe that can be added as well?

emdete commented 2 years ago

i adapted the README.md a bit and changed the script. Everything compiles now (but probably cores). If you are interested let me knw, i would do a PR then.