I'm about to jump off of a roof. Here's the meat & potatoes code:
Code:
char *make_new_query(char *hd)
{
int i, j, k;
char hard_drive[4];
char buffer[5];
char class_part[50];
char query[3000];
char prefix[100] = "SELECT * FROM (SELECT * FROM main WHERE (";
strcpy(hard_drive, hd);
for(i=0; i<8; i++) {
for(j = 0; j < keytab[i].total_songs; j++) {
if(i == 0) {
strcpy(query, prefix);
} else {
strcat(query, prefix);
}
for(k = keytab[i].low_range; k < (keytab[i].high_range + 1); k++) {
snprintf(buffer, 5, "%i", k);
strcat(query, "class_no = ");
strcat(query, buffer);
if(k != keytab[i].high_range)
strcat(query, " OR ");
}
strcat(query, ") AND hd=\'");
strcat(query, hard_drive);
if(strcmp(hard_drive, "A") == 0) strcpy(hard_drive,"B");
else if (strcmp(hard_drive, "B") == 0) strcpy(hard_drive,"A");
strcat(query, "\' ORDER BY random() limit 1)");
if(i != 7) strcat(query, " UNION ALL ");
}
}
strcat(query, ";");
return query;
}
So, I'm making a custom query, and (as you can see) I've resorted to making this huge char buffer on the stack. The size of query is 1/10 of the size that I want (I'm still testing). I want to dynamically allocate query since it's the one that changes sizes, depending.
Here's the other code I was using to dynamically allocate query.
Code:
char *safestrcat(char *to, char *from)
{
size_t len;
char *buffer;
len = (strlen(to) + strlen(from) + 1);
buffer = xrealloc(to, len);
strcat(buffer, to);
strcat(buffer, from);
return buffer;
}
I kept getting an error with this one! Now, in "The GNU C Library" by S. Loosemore, they say "Programmers using the strcat or wcscat function...can easily be recognized as lazy and reckless." Yet, before the code above, I tried the code they had on pp. 102-103, and it didn't work, and I don't understand why it didn't (they have one misspelling in there I fixed, but that wasn't it).
Here's my xrealloc code:
Code:
void *xrealloc(void *ptr, size_t size)
{
register void *value = realloc(ptr, size);
if(value == 0)
HandleError(errno, "xralloc", "xrealloc failed");
return value;
}
So, I wanted to strdup the first part of the query, and then use my safestrcat function for the rest of it. However, when I had it in the function, it would take until I put the k variable into the buffer, safestrcat'ed buffer to class_part, and then it would segmentation fault when I tried to safestrcat class_part onto query. My safestrdup function was this:
Code:
char *safestrdup(const char *s)
{
char *retval;
retval = strdup(s);
if (!retval) HandleError(0, "strdup", "dup %s failed", s);
return retval;
}
I think I'm missing something about how strings work. If someone could help me out of this mess, I'd appreciate it. I don't want to leave this code like this (although it works). My goal is to dynamically allocate the query variable. Thanks, and I hope I made sense.