0
votes

I have this code:

static char * display(const u8 array[], int length) {
    int i;
    char *str;
    for (i = 0; i < length; i++) {
        if (i%32 == 0) {
            //printf("\n");
            strcat(str, "\n");
        }
        if (i%8 == 0) {
            //printf(" ");
            strcat(str, " ");
        }
        //printf("%02X", array[i]);
        strcat(str, (char *)array[i]);
    }
    return str;
    /*
    char str[80];
    strcpy (str,"these ");
    strcat (str,"strings ");
    strcat (str,"are ");
    strcat (str,"concatenated.");
    puts (str);
    return 0;
    */
}

Originally this code was printing a string. I dont want it to print a string, I need to make it returning a string. But it gives me this error:

main.c: In function 'display':
main.c:1707:9: warning: passing argument 2 of 'strcat' makes pointer from integer without a cast [ena bled by default]

     strcat(str, array[i]);                                                                      
     ^                                                                                            In file included from main.c:61:0:                                    

/usr/include/string.h:133:14: note: expected 'const char * restrict' but argument is of type 'u8' extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^ sh-4.2# gcc -o main *.c
main.c: In function 'display':
main.c:1707:21: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
strcat(str, (char *)array[i]);

EDIT:

build shared object and load:

VALUE generateIt(char *valor) {
  struct NESSIEstruct w;
  u8 digest[DIGESTBYTES];

  int i;
  for(i=0; valor[i]!='\0'; ++i);
  int sizeo = i;

  NESSIEinit(&w);
  NESSIEadd((u8*)valor, 8*sizeo, &w);
  NESSIEfinalize(&w, digest);
  return displayIt(digest, DIGESTBYTES);
}

on top I do:

#include 'ruby.h'

and I add also this:

void
Init_whirlpool(){
  rb_mWhirlpool = rb_define_module("Whirlpool");
  rb_cClass = rb_define_class_under(rb_mWhirlpool, "Class", rb_cObject);
  rb_define_method(rb_cClass, "generate", generateIt, 1);
}
1
Well, a u8 is obviously not the right type.Ed S.
str is an uninitialized pointer that will have an undefined value. Probably going to crash when you use it.crashmstr
@iharob * u8 -> unsigned integer type, at least 8 bits, equivalent to unsigned charpsantos
@PSantos What is VALUE is it a generic type used by ruby? something like void *? I am almost sure the problem is you need to use some ruby custom memory allocation funciton that lets the interpreter handle memory allocation. And where did you add the free?Iharob Al Asimi
@iharob In Ruby C API, every Ruby type/class is a VALUE C type. In fact VALUE is a just a uintptr_t C type, or void* to simplify things. This is how Ruby’s loose typing is implemented in C.psantos

1 Answers

2
votes

I believe this is what you need

static char *display(const unsigned char array[], int length)
{
    int  i, k;
    char *str;

    str = malloc(3 * length + 1);
    if (str == NULL)
        return NULL;
    k      = 0;
    str[0] = '\0';
    for (i = 0; i < length; i++) {
        char hex[3];

        if (i % 32 == 0)
            str[k++] = '\n';
        if (i % 8 == 0)
            str[k++] = ' ';
        snprintf(hex, sizeof(hex), "%02X", array[i]);

        str[k++] = hex[0];
        str[k++] = hex[1];
    }
    str[k] = '\0';

    return str;
}

snprintf is POSIX, if it gives a compilation error, change it to _snprintf.

And don't forget to free the returned value in the caller function.