al_fprintf
DanielH

I was looking at this post. This lead me to the Allegro development road map. I thought I would contribute one of the "Nice To Have" section.

// header file
#ifndef __al_included_allegro5_alprintf_h
#define __al_included_allegro5_alprintf_h

#include <allegro5\allegro.h>
#include <stdarg.h>

bool al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args);
bool al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...);

#endif // __al_included_allegro5_alprintf_h

#SelectExpand
1// source file 2#include "al_fprintf.h" 3 4bool al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args) 5{ 6 bool rv = false; 7 ALLEGRO_USTR *ustr = 0; 8 size_t size = 0; 9 10 if (pfile != 0 && format != 0) 11 { 12 ustr = al_ustr_dup(al_ustr_empty_string()); 13 14 if (ustr) 15 { 16 rv = al_ustr_vappendf(ustr, format, args); 17 18 if (rv) 19 { 20 size = al_ustr_size(ustr); 21 22 if (size > 0) 23 { 24 if (size != al_fwrite(pfile, (const void*)(al_cstr(ustr)), size)) 25 { 26 rv = false; 27 } 28 } 29 } 30 31 al_ustr_free(ustr); 32 } 33 } 34 35 return rv; 36} 37 38bool al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...) 39{ 40 bool rv = false; 41 va_list args = 0; 42 43 if (pfile != 0 && format != 0) 44 { 45 va_start(args, format); 46 rv = al_vfprintf(pfile, format, args); 47 va_end(args); 48 } 49 50 return rv; 51}

Chris Katko

You beat me to it by actually doing work, you monster!

Trent Gamblin

Is there any reason you have two functions instead of just one?

Thomas Fjellstrom

The first one should probably be called al_vfprintf rather than al_fprintf. Not least of which because c doesn't let you overload functions.

DanielH

Trent Been working with ALLEGRO_USTR alot lately and since it has two appendf functions (... & va_args). Just copying the same style.

Thomas fixed

Trent Gamblin

I think this is a useful addition for someone to add. Will try to remember to do it myself.

Thomas Fjellstrom

I agree. This is definitely useful. Between supporting format printing to files, it also uses the ustr code to make sure UTF8 writing works.

Edgar Reynaldo

Bump to make sure this doesn't go forgotten. Both functions are nice.

DanielH said:

 46 rv = al_fprintf(pfile, format, args);

I think you meant al_vfprintf there, since you changed the name of the function.

Thomas Fjellstrom

Can you test this code a bit? hammer it a little with invalid input and the like? Once validated, I can apply.

DanielH

Edgar Fixed

Thomas If someone else could tackle this. I don't quite have the time for a while.

tobing

I have put the code into aintern_file, and will test it a bit. Instead of returning a bool I would prefer to return an int, indicating the number of bytes written...

DanielH

tobing I had it return bool because of the use of ustr's appendf function. Of course I agree it should return the size written to file.

I haven't used plain C in forever. Does it support size_t?

// header file
#ifndef __al_included_allegro5_alprintf_h
#define __al_included_allegro5_alprintf_h

#include <allegro5\allegro.h>
#include <stdarg.h>

size_t al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args);
size_t al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...);

#endif // __al_included_allegro5_alprintf_h

#SelectExpand
1// source file 2#include "al_fprintf.h" 3 4size_t al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args) 5{ 6 size_t rv = 0; 7 ALLEGRO_USTR *ustr = 0; 8 9 if (pfile != 0 && format != 0) 10 { 11 ustr = al_ustr_dup(al_ustr_empty_string()); 12 13 if (ustr) 14 { 15 if (al_ustr_vappendf(ustr, format, args)) 16 { 17 rv = al_ustr_size(ustr); 18 19 if (rv > 0) 20 { 21 rv = al_fwrite(pfile, (const void*)(al_cstr(ustr)), rv); 22 } 23 } 24 25 al_ustr_free(ustr); 26 } 27 } 28 29 return rv; 30} 31 32size_t al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...) 33{ 34 size_t rv = 0; 35 va_list args = 0; 36 37 if (pfile != 0 && format != 0) 38 { 39 va_start(args, format); 40 rv = al_vfprintf(pfile, format, args); 41 va_end(args); 42 } 43 44 return rv; 45}

On a side note:

al_ustr_dup(al_ustr_empty_string());
v.s.
al_ustr_new("");

P.S. at work so can't actually run and test the code I just changed

Thomas Fjellstrom

size_t is valid in C as well, and most functions, especially newer ones will use size_t over int. size_t may even be 64bit on a 64bit platform.

tobing

Here's a patch for current origin/5.1 in git, that contains the last implementation by DanielH, but with al_ustr_new("") instead of the dup on empty string.

I have tested this a bit, and works fine with unicode characters.

Trent Gamblin

This is committed. I added some quick documentation.

Also changed it to return a negative number on error like stdio fprintf.

tobing

Thanks for submitting and doing the cleanup. ;)

The return is a size_t, so returning -1 is not exactly doing what it should do, so maybe we should return int instead of size_t?

Arthur Kalliokoski

The libc fprintf returns the number of bytes in an int, so I'd vote for that. Someday 2147483648 bytes in a single write won't be enough, but today is not that day.

Trent Gamblin
tobing said:

The return is a size_t, so returning -1 is not exactly doing what it should do, so maybe we should return int instead of size_t?

Good catch, thanks. Changing it to int.

DanielH

Thanks guys.

However, can someone answer a previous question?

al_ustr_dup(al_ustr_empty_string());

v.s.

al_ustr_new("");

I see that my code was changed for the latter case. In looking at other's code, I've seen both.

tobing

Ah, I didn't realize that this was a question.

Well, I used the second variant because the result seems to be the same, but uses only one call.

DanielH

You're right. I did post it, but didn't phrase it as a question.

Edgar Reynaldo

Small patch to fix a warning about comparison between signed and unsigned integers (I hate seeing warnings) :

#SelectExpand
1 src/file.c | 2 +- 2 1 file changed, 1 insertion(+), 1 deletion(-) 3 4diff --git a/src/file.c b/src/file.c 5index 16f1e80..b6b2ce6 100644 6--- a/src/file.c 7+++ b/src/file.c 8@@ -559,7 +559,7 @@ int al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args) 9 if (size > 0) 10 { 11 rv = al_fwrite(pfile, (const void*)(al_cstr(ustr)), size); 12- if (rv != size) { 13+ if (rv != (int)size) { 14 rv = -1; 15 } 16 }

Trent Gamblin

Committed.

tobing

Thanks a lot!

Thread #614829. Printed from Allegro.cc