diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..5fcec57be0566bc34251556777c92f91cba35861 --- /dev/null +++ b/.clang-format @@ -0,0 +1,178 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Right +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: true +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/.gitignore b/.gitignore index e79924440b9dffee48a7489d4b61cf4d81fa69eb..e7aa54f51e8ae54be38299c4623eecc1e29e61f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -# Created by https://www.toptal.com/developers/gitignore/api/c +bin/ + +#Created by https://www.toptal.com/developers/gitignore/api/c # Edit at https://www.toptal.com/developers/gitignore?templates=c ### C ### diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d0aec1be850f9e1cb364f993b2b66e1832cbaead --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +# see https://yuukidach.github.io/2019/08/05/makefile-learning/ +# Variable setup +CC:=gcc +CFLAGS:=-g -Ofast -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11 +LIBS:=-lSDL2 -lm +VPATH:=ultra-cp + +BIN = bin + +# Get source and object +SRCS = $(filter-out $(wildcard */*_tests.c */*test.c */*tests.c */*_test.c), $(wildcard *.c */*.c)) +OBJS = $(addprefix $(BIN)/, $(SRCS:.c=.o)) +SRCS_TEST = $(filter-out $(wildcard main.c */main.c gfx/*), $(wildcard *.c */*.c)) +OBJS_TEST = $(addprefix $(BIN)/, $(SRCS_TEST:.c=.o)) + +# Create the target +main: $(OBJS) + $(CC) $(CFLAGS) -o $(BIN)/$@ $^ $(LIBS) $(LDFLAGS) + ./$(BIN)/$@ $(ARGS) + +# Convert the source in object, but before all, run `$(BIN)` aka mkdir +$(BIN)/%.o: %.c + mkdir -p $(@D) + $(CC) $(CFLAGS) -o $@ -c $< $(LDFLAGS) -lSDL2 + +# Echo the source and object values +help: + @echo "src: $(SRCS)" + @echo "obj: $(OBJS)" + @echo "obj_test: $(OBJ_TEST)" + +clean: + rm -rf $(BIN) + +.PHONY: test-draw help clean main + diff --git a/main.c b/main.c new file mode 100644 index 0000000000000000000000000000000000000000..6023e7af5fd0c74952a29251944362a61c449ec5 --- /dev/null +++ b/main.c @@ -0,0 +1,15 @@ +#include "parser/parser.h" +#include "ultra-cp/ultra-cp.h" +#include <ctype.h> +#include <linux/limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int main(int argc, char **argv) { + printf("aflag = %d\n", get_opt(argc, argv, "af")); + + char source_path[PATH_MAX]; + + return EXIT_SUCCESS; +} diff --git a/parser/parser.c b/parser/parser.c new file mode 100644 index 0000000000000000000000000000000000000000..25b279d1257eac3772e4ac10cc2e391f2cc3e9e7 --- /dev/null +++ b/parser/parser.c @@ -0,0 +1,23 @@ +#include "parser.h" + +uint8_t get_opt(int argc, char **argv, char *args) { + uint8_t opt = 0b00; + + int c; + while ((c = getopt(argc, argv, args)) != -1) { + switch (c) { + case 'a': + opt |= 0b01; + break; + + case 'f': + opt |= 0b10; + break; + + default: + break; + } + } + + return opt; +} diff --git a/parser/parser.h b/parser/parser.h new file mode 100644 index 0000000000000000000000000000000000000000..01ca25abc408499c766c7ec2d291084ad3a3dc8f --- /dev/null +++ b/parser/parser.h @@ -0,0 +1,18 @@ +#ifndef PARSER_H_ +#define PARSER_H_ + +#include <unistd.h> +#include <stdint.h> + +/** + * @brief Get options from cli + * + * @param argc Arg count + * @param argv Arg values + * @param args Arg expected + * + * @returns Options + */ +uint8_t get_opt(int argc, char **argv, char *args); + +#endif // !PARSER_H_ diff --git a/ultra-cp/ultra-cp.c b/ultra-cp/ultra-cp.c new file mode 100644 index 0000000000000000000000000000000000000000..4e0e8e15165b4638c8aa8e24d2535b741f04a101 --- /dev/null +++ b/ultra-cp/ultra-cp.c @@ -0,0 +1,106 @@ +#include "ultra-cp.h" +#include <stdlib.h> +#include <sys/stat.h> +#include <time.h> + +//==================== +// PRIVATE +//==================== + +//==================== +// PUBLIC +//==================== +char *get_permissions(const char *name) { + struct stat file_stat; + + // Read stats + if (stat(name, &file_stat) < 0) + return NULL; + + char *permissions = calloc(10, sizeof(char)); + + permissions[0] = S_ISDIR(file_stat.st_mode) ? 'd' : S_ISLNK(file_stat.st_mode) ? 'l' : '-'; + permissions[1] = (file_stat.st_mode & S_IRUSR) ? 'r' : '-'; + permissions[2] = (file_stat.st_mode & S_IWUSR) ? 'w' : '-'; + permissions[3] = (file_stat.st_mode & S_IXUSR) ? 'x' : '-'; + permissions[4] = (file_stat.st_mode & S_IRGRP) ? 'r' : '-'; + permissions[5] = (file_stat.st_mode & S_IWGRP) ? 'w' : '-'; + permissions[6] = (file_stat.st_mode & S_IXGRP) ? 'x' : '-'; + permissions[7] = (file_stat.st_mode & S_IROTH) ? 'r' : '-'; + permissions[8] = (file_stat.st_mode & S_IWOTH) ? 'w' : '-'; + permissions[9] = (file_stat.st_mode & S_IXOTH) ? 'x' : '-'; + + return permissions; +} + +int get_size(const char *name) { + int size = 0; + struct stat file_stat; + + // Read stats + if (stat(name, &file_stat) < 0) + return 0; + + size = file_stat.st_size; + + return size; +} + +char *get_date(const char *name) { + struct stat file_stat; + + // Read stats + if (stat(name, &file_stat) < 0) + return NULL; + + char *date = calloc(25, sizeof(char)); + + strftime(date, 25, "%a %b %d %X %Y", localtime(&(file_stat.st_ctime))); + + return date; +} + +void list_dir(const char *name) { + DIR *dir; + struct dirent *entry; + + // Cannot open dir + if (!(dir = opendir(name))) + return; + + // Loop through all entries of the given directory + while ((entry = readdir(dir)) != NULL) { + const char *d_name; + d_name = entry->d_name; + + // Skip "." and ".." + if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) + continue; + + int path_lenght; + char path[PATH_MAX]; + + // Create the full relative path and file stats + path_lenght = snprintf(path, PATH_MAX, "%s/%s", name, d_name); + char *permissions = get_permissions(path); + int size = get_size(path); + char *date = get_date(path); + + printf("%s %*d %s %s\n", permissions, 10, size, date, path); + + free(permissions); + free(date); + + // Path length exceeded clause + if (path_lenght >= PATH_MAX) { + fprintf(stderr, "Path length has got too long.\n"); + exit(EXIT_FAILURE); + } + + // Go deeper if directory + if (entry->d_type == DT_DIR) + list_dir(path); + } + + closedir(dir); +} diff --git a/ultra-cp/ultra-cp.h b/ultra-cp/ultra-cp.h new file mode 100644 index 0000000000000000000000000000000000000000..b7ffca454eff223c77b49343b52812c7f2427834 --- /dev/null +++ b/ultra-cp/ultra-cp.h @@ -0,0 +1,47 @@ +#ifndef ULTRA_CP_ +#define ULTRA_CP_ + +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +/** + * @brief Get the given file permissions + * + * @param name Path of the file + * + * @returns Permissions string + */ +char *get_permissions(const char *name); + +/** + * @brief Get the given file size + * + * @param name Path of the file + * + * @returns File size + */ +int get_size(const char *name); + +/** + * @brief Get the given file date + * + * @param name Path of the file + * + * @returns File date + */ +char *get_date(const char *name); + +/** + * @brief List the content of the given directory + * + * @param name Relative path + */ +void list_dir(const char *name); + +#endif // !ULTRA_CP_