Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#348 Review usage of fgets in file reading #398

Closed
wants to merge 67 commits into from
Closed

#348 Review usage of fgets in file reading #398

wants to merge 67 commits into from

Conversation

darvark
Copy link
Contributor

@darvark darvark commented Jul 9, 2023

Removed all occurrences of fgets and replaced with getline.
Additionally code re-formated with astyle

darvark and others added 30 commits June 23, 2023 20:43
* make band limits configurable

* allow showing out-of-band spots on bandmap
test/rules/cqww/rules/cqww Outdated Show resolved Hide resolved
@zcsahok
Copy link
Member

zcsahok commented Aug 3, 2023

Would it make sense to have a function that reads a file and return the lines as an array of pointers?
Just in order to split file reading and the actual processing.

@darvark
Copy link
Contributor Author

darvark commented Aug 3, 2023

Would it make sense to have a function that reads a file and return the lines as an array of pointers? Just in order to split file reading and the actual processing.

So you want to have new file dedicated only to read file and returning content of this file as array of char * ?

@airween
Copy link
Member

airween commented Aug 4, 2023

Wondering if it wouldn't be too much to add checking if errno != ENOMEM to codition if (inputbuffer_len > 0). Theoretically getline still can read some amount of data before exceed memory so input buffer will be non zero.

IMHO checking the result of memory allocation according to different aspects can never be too much. :)

@zcsahok
Copy link
Member

zcsahok commented Aug 4, 2023

So you want to have new file dedicated only to read file and returning content of this file as array of char * ?

The typical usage pattern is

  1. look for the file and open it
  2. read it line-by-line in a loop
    3. process each line

The loop in Step 2 is surely generic. So one could even make a function for it

int process_file(FILE *f, char *filename, char *(*func)(char *), char *comment_chars);

where func does the use case specific processing (Step 3). It returns a non-null message in case of an error.
Lines that start with one of the chars in comment_chars are treated as comments and skipped.

This would be even better than reading-in the whole file.

@darvark
Copy link
Contributor Author

darvark commented Aug 5, 2023

@zcsahok I think it worth to consider such functionality, but probably it's outside of this issue scope. We should/can discuss this in separate thread and create new issue for it. Such change would be bigger than just switch from fgets to getline.

}

fclose(cfp);

if (s_inputbuffer > 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing a pointer and 0. It works, but using the typical check

if (s_inputbuffer != NULL) 

would be clearer.

gchar *backupfile;
gchar *cmd;
char buffer[200];
char *buffer = NULL;
size_t buffer_len = 200;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As buffer==NULL the assigned value is ignored by getline, so do not set it.
See https://elixir.bootlin.com/glibc/latest/source/libio/iogetdelim.c#L62

char buffer[160];
int read;
char *buffer = NULL;
size_t buffer_len = 160;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not set buffer_len.

struct stat statbuf;
char inputbuffer[800];
char *inputbuffer = NULL;
size_t read_len = 160;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not set read_len.

@@ -332,8 +333,10 @@ void dxcc_add(char *dxcc_line) {
/** load cty database from filename */
int load_ctydata(char *filename) {
FILE *fd;
char buf[181] = "";
char *buf = NULL;
size_t buf_len = 181;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not set buf_len.

struct ie_list *make_ie_list(char *file) {

FILE *fp;
char inputbuffer[91];
char *inputbuffer = NULL;
size_t inputbuffer_len = 91;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not set inputbuffer_len.

g_strchomp(buffer); /* drop trailing whitespace */

printf("%s\n", buffer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private logging?

struct cabrillo_desc *cabdesc;
char input_logfile[24];
char output_logfile[80], temp_logfile[80];
char logline[MAX_CABRILLO_LEN];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused MAX_CABRILLO_LEN from MAX_CABRILLO_LEN.

int qtcdirection = 0;
int next_qtc_qso;
int qsoflags_for_qtc[MAX_QSOS];
int nr_qtcsent = 0;

int readqtccalls() {
int s = 0;
char inputbuffer[160];
char *inputbuffer = NULL;
size_t inputbuffer_len = 160;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not set length.

country_list_raw = colon + 1; // skip optional contest name
} else {
country_list_raw = buffer;
if (buffer != NULL) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buffer is never NULL at this point. In case the previous calloc fails, then the following g_strlcpy (line 687) will already cause a segmentation violation.

@@ -747,7 +748,9 @@ int load_callmaster(void) {

FILE *cfp;
char *callmaster_location;
char s_inputbuffer[186] = "";
char *s_inputbuffer = NULL;
size_t s_inputbuffer_len = 186;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not set length.


char buffer[160];
char *buffer = NULL;
size_t buffer_len = 160;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do no set length.

@zcsahok
Copy link
Member

zcsahok commented Aug 8, 2023

My point was to avoid copy-pasting the same code to all affected source files. This can be done also later, no problem.

This PR contains 43 changed files including 3 file mode changes. On the other hand there are only 12 files in src/ that use fgets. The extra changes are due to astyle reformatting as this was not applied previously in a consistent manner. Additionally, the comments in some files like globalvars.h or qtcvars.h get mangled when reformatted.

So, I suggest to consolidate this PR as follows

  • take this as a successful prototyping and create a brand new branch from master head
  • copy the 12 .c files from this branch considering the review comments
  • apply astyle to the 12 files only, keep others unchanged
  • open a new PR

In the meantime I am preparing a PR to allow unconditional application of astyle
and also actually reindent the code in a controlled way.

Then we check the feasibility of introducing a generic file reading function.

Does this sound like a plan?

@darvark
Copy link
Contributor Author

darvark commented Aug 8, 2023

My point was to avoid copy-pasting the same code to all affected source files. This can be done also later, no problem.

This PR contains 43 changed files including 3 file mode changes. On the other hand there are only 12 files in src/ that use fgets. The extra changes are due to astyle reformatting as this was not applied previously in a consistent manner. Additionally, the comments in some files like globalvars.h or qtcvars.h get mangled when reformatted.

So, I suggest to consolidate this PR as follows

* take this as a successful prototyping and create a brand new branch from master head

* copy the 12 .c files from this branch considering the review comments

* apply astyle to the 12 files only, keep others unchanged

* open a new PR

In the meantime I am preparing a PR to allow unconditional application of astyle and also actually reindent the code in a controlled way.

Then we check the feasibility of introducing a generic file reading function.

Does this sound like a plan?

Yes, thank you for all your comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants