Welcome to the Builder Academy

Question Confused over piece of code in parse_room()

More
25 Jan 2020 06:26 - 25 Jan 2020 15:10 #8499 by krell
I'm trying to wrap my head around this piece of code of parse_room() in db.c.

Code:
case 'E': CREATE(new_descr, struct extra_descr_data, 1); new_descr->keyword = fread_string(fl, buf2); new_descr->keyword = fread_string(fl, buf2); /* Fix for crashes in the editor when formatting. E-descs are assumed to * end with a \r\n. -Welcor */ { char *end = strchr(new_descr->description, '\0'); if (end > new_descr->description && *(end-1) != '\n') { CREATE(end, char, strlen(new_descr->description)+3); sprintf(end, "%s\r\n", new_descr->description); /* snprintf ok : size checked above*/ free(new_descr->description); new_descr->description = end; } } new_descr->next = world[room_nr].ex_description; world[room_nr].ex_description = new_descr; break;

What does

Code:
{ char *end = strchr(new_descr->description, '\0'); if (end > new_descr->description && *(end-1) != '\n') { CREATE(end, char, strlen(new_descr->description)+3); sprintf(end, "%s\r\n", new_descr->description); /* snprintf ok : size checked above*/ free(new_descr->description); new_descr->description = end; } }

actually do? Is it ever actually executed? How is it actually called? Is it good practice to free a pointer that you just copied the contents into a second pointer and then assign the pointer you just freed to the second pointer?

Forgive all the questions, but I'm reading this code and my being stumped is likely due to my lack of knowledge. Thanks.
Last edit: 25 Jan 2020 15:10 by krell.

Please Log in or Create an account to join the conversation.

More
25 Jan 2020 08:52 #8500 by Castillo
Correction the code is:
Code:
CREATE(new_descr, struct extra_descr_data, 1); new_descr->keyword = fread_string(fl, buf2); new_descr->description = fread_string(fl, buf2);

well, the function fread_string(fl, buf2) return an allocated memory using strdup.

fread_string end with this line.
Code:
return (strlen(buf) ? strdup(buf) : NULL);

So, since he want to create a bigger string. He needs to free new_descr->description,
and create a new one.

He want to create a new one bigger by 3 chars, to hold \r\n\x0
This is a bug fix, if you read the comments. He want to make sure new_descr->description end with "\r\n"

Amazingly, fread_string seems to do that, but not in some case... which, seems to be a design problem.
Code:
/* If there is a '~', end the string; else put an "\r\n" over the '\n'. */ /* now only removes trailing ~'s -- Welcor */ point = strchr(tmp, '\0'); for (point-- ; (*point=='\r' || *point=='\n'); point--); if (*point=='~') { *point='\0'; done = 1; } else { *(++point) = '\r'; *(++point) = '\n'; *(++point) = '\0'; }

Note: it seems that fread_string could return NULL, so therorically
char *end = strchr(new_descr->description, '\0');
could crash.

Bob

Please Log in or Create an account to join the conversation.

More
25 Jan 2020 14:56 #8501 by krell
Okay, that was along the lines what I figured it was doing. I guess one thing that I'm still a bit confused about is when code looks like this:

Code:
Some code Some code { Some code Some code } Some code Some code

But the sub code doesn't have any loop or decision making logic to call on it. Does the execution of the code just roll into it sequentially? I'm thinking that it must or it would never be executed, which means it must always be executed. Is that the case? (pun intended after the fact XD)

But why separate it via braces then?

Please Log in or Create an account to join the conversation.

More
25 Jan 2020 15:09 #8502 by krell

Castillo wrote: Correction the code is:

Code:
CREATE(new_descr, struct extra_descr_data, 1); new_descr->keyword = fread_string(fl, buf2); new_descr->description = fread_string(fl, buf2);


Yeah, I don't know how those colons ended up there instead of the semicolons. If I recall correctly, due to the way I had my terminal parsed, X Org wasn't letting me nicely copy and paste the whole segment in question, so I was copying over line-by-line. So I didn't copy the semicolons and thought I had typed in the missing characters. But now I see I typed the wrong one. Corrected in original post now. Thanks.

Please Log in or Create an account to join the conversation.

More
25 Jan 2020 15:11 - 25 Jan 2020 15:31 #8503 by Castillo

Some code
Some code
{ <=====
Some code
Some code
} <======
Some code
Some code


The <===== does nothing.

My guess: if (new_descr->description)
is missing on top of that to avoid strchr on a NULL pointer:
char *end = strchr(new_descr->description, '\0');

Bob
Last edit: 25 Jan 2020 15:31 by Castillo.

Please Log in or Create an account to join the conversation.

More
26 Jan 2020 15:11 #8504 by thomas
Yes, that's a needed fix for NULL from fread_string().

And, in case someone needs to search for it, { } is called a scope.

It does something - it limits the scope of any variables to this part of the code. In C, you can only define new variables at the start of a scope. So this scope is here to allow us to create the end variable.

It also means that this is a bit hacky. Had I made code like it at work, my colleagues might have stopped me and instead insisted on making me create a function for this scope. I'll see if I can have a look at improving this later.

Please Log in or Create an account to join the conversation.

Time to create page: 0.186 seconds