Impl. parser (TODO Fix invalid free crash)
During testing, having at least three positional args cause an invalid free crash. Should be investigated and fixed.
This commit is contained in:
parent
002590379e
commit
44080e85cc
6 changed files with 238 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
/build*/
|
||||
compile_commands.json
|
||||
/.cache/
|
||||
|
|
|
@ -5,12 +5,13 @@ set(SimpleArchiver_VERSION 1.0)
|
|||
|
||||
set(SimpleArchiver_SOURCES
|
||||
src/main.c
|
||||
src/parser.c
|
||||
)
|
||||
|
||||
add_compile_options(
|
||||
-Wall -Wextra -Wpedantic -Wno-missing-braces
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Weffc++>
|
||||
$<$<CONFIG:DEBUG>:-O0>
|
||||
$<$<CONFIG:DEBUG>:-Og>
|
||||
)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
|
|
1
src/.lvimrc
Normal file
1
src/.lvimrc
Normal file
|
@ -0,0 +1 @@
|
|||
set expandtab tabstop=2 softtabstop=2 shiftwidth=2
|
19
src/main.c
19
src/main.c
|
@ -15,6 +15,21 @@
|
|||
*
|
||||
* `main.c` is the entry-point of this software/program.
|
||||
*/
|
||||
int main(int argc, char **argv) {
|
||||
return 0;
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
simple_archiver_print_usage();
|
||||
|
||||
//__attribute__((cleanup(simple_archiver_free_parsed)))
|
||||
SDArchiverParsed parsed = simple_archiver_create_parsed();
|
||||
|
||||
simple_archiver_parse_args(argc, argv, &parsed);
|
||||
|
||||
puts("freeing");
|
||||
simple_archiver_free_parsed(&parsed);
|
||||
puts("end");
|
||||
return 0;
|
||||
}
|
||||
|
|
166
src/parser.c
Normal file
166
src/parser.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright 2024 Stephen Seo
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* `parser.c` is the source file for parsing args.
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void simple_archiver_print_usage(void) {
|
||||
puts("Usage flags:");
|
||||
puts("-c : create archive file");
|
||||
puts("-x : extract archive file");
|
||||
puts("-f <filename> : filename to work on");
|
||||
puts("--compressor <full_compress_cmd> : requires --decompressor");
|
||||
puts("--decompressor <full_decompress_cmd> : requires --compressor");
|
||||
puts("If creating archive file, remaining args specify files to archive.");
|
||||
puts("If extracting archive file, remaining args specify files to extract.");
|
||||
}
|
||||
|
||||
SDArchiverParsed simple_archiver_create_parsed(void) {
|
||||
SDArchiverParsed parsed;
|
||||
|
||||
parsed.flags = 0;
|
||||
parsed.filename = NULL;
|
||||
parsed.compressor = NULL;
|
||||
parsed.decompressor = NULL;
|
||||
parsed.working_files = NULL;
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
int simple_archiver_parse_args(int argc, const char **argv,
|
||||
SDArchiverParsed *out) {
|
||||
if (out->filename) {
|
||||
free(out->filename);
|
||||
out->filename = NULL;
|
||||
}
|
||||
if (out->compressor) {
|
||||
free(out->compressor);
|
||||
out->compressor = NULL;
|
||||
}
|
||||
if (out->decompressor) {
|
||||
free(out->decompressor);
|
||||
out->decompressor = NULL;
|
||||
}
|
||||
|
||||
// Skip program name as it is the first arg usually.
|
||||
--argc;
|
||||
++argv;
|
||||
|
||||
int is_remaining_args = 0;
|
||||
|
||||
while (argc > 0) {
|
||||
if (!is_remaining_args) {
|
||||
if (strcmp(argv[0], "-c") == 0) {
|
||||
// unset first bit.
|
||||
out->flags &= 0xFFFFFFFE;
|
||||
} else if (strcmp(argv[0], "-x") == 0) {
|
||||
// set first bit.
|
||||
out->flags |= 0x1;
|
||||
} else if (strcmp(argv[0], "-f") == 0 && argc > 1) {
|
||||
int size = strlen(argv[1]) + 1;
|
||||
out->filename = malloc(size);
|
||||
strncpy(out->filename, argv[1], size);
|
||||
--argc;
|
||||
++argv;
|
||||
} else if (strcmp(argv[0], "--compressor") == 0 && argc > 1) {
|
||||
int size = strlen(argv[1]) + 1;
|
||||
out->compressor = malloc(size);
|
||||
strncpy(out->compressor, argv[1], size);
|
||||
--argc;
|
||||
++argv;
|
||||
} else if (strcmp(argv[0], "--decompressor") == 0 && argc > 1) {
|
||||
int size = strlen(argv[1]) + 1;
|
||||
out->decompressor = malloc(size);
|
||||
strncpy(out->decompressor, argv[1], size);
|
||||
--argc;
|
||||
++argv;
|
||||
} else if (argv[0][0] != '-') {
|
||||
is_remaining_args = 1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (out->working_files == NULL) {
|
||||
puts("first addition to working_files");
|
||||
out->working_files = malloc(sizeof(char *) * 2);
|
||||
int arg_length = strlen(argv[0]) + 1;
|
||||
out->working_files[0] = malloc(arg_length);
|
||||
strncpy(out->working_files[0], argv[0], arg_length);
|
||||
out->working_files[1] = NULL;
|
||||
} else {
|
||||
puts("later addition to working_files");
|
||||
int working_size = 1;
|
||||
char **ptr = out->working_files;
|
||||
while (ptr && *ptr) {
|
||||
++working_size;
|
||||
++ptr;
|
||||
}
|
||||
printf("working_size is %u\n", working_size);
|
||||
|
||||
// TODO verify this is necessary, using different variables.
|
||||
ptr = out->working_files;
|
||||
out->working_files = realloc(ptr, working_size + 1);
|
||||
|
||||
// Set new actual last element to NULL.
|
||||
out->working_files[working_size] = NULL;
|
||||
int size = strlen(argv[0]) + 1;
|
||||
// Set last element to the arg.
|
||||
out->working_files[working_size - 1] = malloc(size);
|
||||
strncpy(out->working_files[working_size - 1], argv[0], size);
|
||||
}
|
||||
}
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void simple_archiver_free_parsed(SDArchiverParsed *parsed) {
|
||||
parsed->flags = 0;
|
||||
if (parsed->filename) {
|
||||
free(parsed->filename);
|
||||
parsed->filename = NULL;
|
||||
}
|
||||
if (parsed->compressor) {
|
||||
free(parsed->compressor);
|
||||
parsed->compressor = NULL;
|
||||
}
|
||||
if (parsed->decompressor) {
|
||||
free(parsed->decompressor);
|
||||
parsed->decompressor = NULL;
|
||||
}
|
||||
if (parsed->working_files) {
|
||||
char **ptr = parsed->working_files;
|
||||
unsigned int idx = 0;
|
||||
puts("freeing working_files strings...");
|
||||
while (ptr[idx]) {
|
||||
printf("Freeing at idx %u\n", idx);
|
||||
free(ptr[idx]);
|
||||
++idx;
|
||||
}
|
||||
puts("freeing string array...");
|
||||
free(parsed->working_files);
|
||||
parsed->working_files = NULL;
|
||||
|
||||
puts("free_parsed is done.");
|
||||
}
|
||||
}
|
51
src/parser.h
Normal file
51
src/parser.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2024 Stephen Seo
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* `parser.h` is the header for parsing args.
|
||||
*/
|
||||
|
||||
#ifndef SEODISPARATE_COM_SIMPLE_ARCHIVER_PARSER_H_
|
||||
#define SEODISPARATE_COM_SIMPLE_ARCHIVER_PARSER_H_
|
||||
|
||||
typedef struct SDArchiverParsed {
|
||||
/// Each bit is a flag.
|
||||
/// 0b0 - is creating.
|
||||
/// 0b1 - is extracting.
|
||||
unsigned int flags;
|
||||
/// Null-terminated string.
|
||||
char *filename;
|
||||
/// Null-terminated string.
|
||||
char *compressor;
|
||||
/// Null-terminated string.
|
||||
char *decompressor;
|
||||
/// Null-terminated strings in array of strings.
|
||||
/// Last entry should be NULL.
|
||||
/// Not used when extracting.
|
||||
char **working_files;
|
||||
} SDArchiverParsed;
|
||||
|
||||
extern void simple_archiver_print_usage(void);
|
||||
|
||||
extern SDArchiverParsed simple_archiver_create_parsed(void);
|
||||
|
||||
/// Expects the user to pass a pointer to an SDArchiverParsed.
|
||||
/// This means the user should have a SDArchiverParsed variable
|
||||
/// and it should be passed with e.g. "&var".
|
||||
extern int simple_archiver_parse_args(int argc, const char **argv,
|
||||
SDArchiverParsed *out);
|
||||
|
||||
extern void simple_archiver_free_parsed(SDArchiverParsed *parsed);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue