Browse Source

Add: Application dir and first application to list all group files in a dir

Sebastian Kreisel 7 months ago
parent
commit
6c033e19fb
7 changed files with 152 additions and 35 deletions
  1. 1 1
      .gitignore
  2. 4 12
      Makefile
  3. 55 0
      src/application/group_library.c
  4. 18 0
      src/application/group_library.h
  5. 40 17
      src/group/group_io.c
  6. 18 3
      src/group/group_io.h
  7. 16 2
      src/main.c

+ 1 - 1
.gitignore

@@ -1,6 +1,6 @@
 /saves
 /prof
-/groups
+/grplib
 /_old
 /old
 /bin

+ 4 - 12
Makefile

@@ -22,10 +22,8 @@ CC_FLAGS += -DVERSION='"$(VERSION)"'
 
 INCLUDES = -I src/
 
-SRC_FILES += $(wildcard src/gen/*.c) \
-	     $(wildcard src/common/*.c) \
-	     $(wildcard src/group/*.c) \
-	     $(wildcard src/ring/*.c)
+SRC_FILES += $(wildcard src/group/*.c) \
+	     $(wildcard src/application/*.c)
 OBJ_FILES = $(addprefix bin/,$(notdir $(SRC_FILES:.c=.o)))
 DEP_FILES = $(OBJ_FILES:.o=.d)
 
@@ -51,17 +49,11 @@ bin/%.o: test/%.c
 bin/%.o: src/%.c
 	$(CC) $(CC_FLAGS) $(INCLUDES) -MMD -c $< -o $@
 
-#bin/%.o: src/gen/%.c
-#	$(CC) $(CC_FLAGS) $(INCLUDES) -MMD -c $< -o $@
-
-#bin/%.o: src/common/%.c
-#	$(CC) $(CC_FLAGS) $(INCLUDES) -MMD -c $< -o $@
-
 bin/%.o: src/group/%.c
 	$(CC) $(CC_FLAGS) $(INCLUDES) -MMD -c $< -o $@
 
-#bin/%.o: src/ring/%.c
-#	$(CC) $(CC_FLAGS) $(INCLUDES) -MMD -c $< -o $@
+bin/%.o: src/application/%.c
+	$(CC) $(CC_FLAGS) $(INCLUDES) -MMD -c $< -o $@
 
 clean:
 	-rm ./bin/*

+ 55 - 0
src/application/group_library.c

@@ -0,0 +1,55 @@
+#include "group_library.h"
+
+#include "../group/group_io.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+
+
+Vecptr *app_listGroupFiles_alloc(char *path, u16 order, i32 isCommutative)
+{
+  DIR *dir = opendir(path);
+  if(dir == 0) {
+    return 0;
+  }
+  struct dirent *ent = 0;
+  u16 fOrder = 0;
+  bool fIsComm = 0;
+  // Get the count of files fullfilling the requirements
+  u32 count = 0;
+  while((ent = readdir(dir)) != 0) {
+    bool validFile = group_checkGroupFileName(ent->d_name, &fOrder, &fIsComm);
+    validFile = validFile && ((order <= 0) || order == fOrder);
+    validFile = validFile && ((isCommutative < 0) || isCommutative == fIsComm);
+    if(validFile) {
+      count++;
+    }
+  }
+  rewinddir(dir);
+  Vecptr *fileNames = vecptr_alloc(count);
+  u32 ts = *(strrchr(path, '\0') - 1) == '/' ? 0 : 1;
+  u32 totalPathLen = strlen(path) + ts + GROUP_META_FILENAME_LEN;
+  i32 ind = 0;
+  while((ent = readdir(dir)) != 0) {
+    // also makes sure d_name is exactly GROUP_META_FILENAME_LEN long
+    bool validFile = group_checkGroupFileName(ent->d_name, &fOrder, &fIsComm);
+    validFile = validFile && ((order <= 0) || order == fOrder);
+    validFile = validFile && ((isCommutative < 0) || isCommutative == fIsComm);
+    if(validFile) {
+      char *fileName = malloc(totalPathLen + 1);
+      memset(fileName, '\0', totalPathLen + 1);
+      strcat(fileName, path);
+      if(ts == 1) {
+        strcat(fileName, "/");
+      }
+      strcat(fileName, ent->d_name);
+      *vecptr_at(fileNames, ind) = fileName;
+      ind++;
+    }
+  }
+  vecptr_resize(fileNames, ind);
+  closedir(dir);
+  return fileNames;
+}

+ 18 - 0
src/application/group_library.h

@@ -0,0 +1,18 @@
+#ifndef GROUP_LIBRARY
+#define GROUP_LIBRARY
+
+#include <elfc_common.h>
+#include <elfc_vecptr.h>
+
+
+/*
+ * Get a list of all group file names in directory path. Allocates vecptr and
+ * the contained strings
+ * If order > 0 and/or isCommutative == 0 or 1 these restrictions will be
+ * applied to file names found
+ * If order == 0 and/or isCommutative < 1 no such restrictions are applied
+ */
+Vecptr *app_listGroupFiles_alloc(char *path, u16 order, i32 isCommutative);
+
+
+#endif

+ 40 - 17
src/group/group_io.c

@@ -11,6 +11,9 @@
 
 static const f64 baseLog16 = 1.0 / log(16.0);
 
+// ---------------------------------------------------------------------------
+// Writing
+// ---------------------------------------------------------------------------
 
 bool group_writeToFile(Group *group, GroupMetaInfo meta, char *path)
 {
@@ -144,28 +147,48 @@ i32 group_sprintGroupMeta(char *buf, GroupMetaInfo meta)
 // Reading
 // ---------------------------------------------------------------------------
 
-u16 group_readOrderFromFileName(char *path)
-{
-  char *fileName = strchr(path, '/') + 1;
-  u16 order = 0xffff;
-  //TODO: Check sscanf return code
-  sscanf(fileName, "%5hu", &order);
-  return order;
-}
-
-bool group_readCommutativeFromFileName(char *path)
+bool group_checkGroupFileName(char *path, u16 *order, bool *isCommutative)
 {
-  char *fileName = strchr(path, '/') + 1;
-  return fileName[5] == 'c';
+  char *fileName = strrchr(path, '/');
+  if(fileName == 0) {
+    fileName = path; // Case where just the filename without any path is given
+  } else {
+    fileName++; // Account for "/" position from strrchr
+  }
+  if(strlen(fileName) != GROUP_META_FILENAME_LEN) {
+    return 0;
+  }
+  u16 ord = 0;
+  char commFlag = 0;
+  char sep = 0;
+  sscanf(fileName, "%5hu%c%c", &ord, &commFlag, &sep);
+  // Check for prefix and .txt file extension
+  bool ok = ord > 0 && (commFlag == 'c' || commFlag == 'n') && sep == '_';
+  if((fileName = strchr(fileName, '.')) == 0) {
+    return 0;
+  }
+  ok = ok && !strcmp(fileName, ".txt");
+  if(ok) {
+    if(order != 0) {
+      *order = ord;
+    }
+    if(isCommutative != 0) {
+      *isCommutative = commFlag == 'c' ? 1 : 0;
+    }
+  }
+  return ok;
 }
 
 Group *group_readGroupFromFile_alloc(char *path)
 {
+  u16 order = 0;
+  if(!group_checkGroupFileName(path, &order, 0)) {
+    return 0;
+  }
   FILE *f = 0;
   if((f = fopen(path, "r")) == 0) { // check if file exists
     return 0;
   }
-  u16 order = group_readOrderFromFileName(path);
   char c = fgetc(f);
   i64 startPos = -1;
   while(c == '#') {
@@ -213,19 +236,21 @@ Group *group_readGroupFromFile_alloc(char *path)
 // line is an array of size 81, see below
 void group_parseMetaLine(char *line, GroupMetaInfo *meta)
 {
+  // With all number parsing, enforce that no garbage follows the number
+  char dummy = 0;
   if(!strncmp(line, "# Group Name: ", 14)) {
     strncpy(meta->name, line + 14, GROUP_META_NAME_LEN - 1);
   }
   if(!strncmp(line, "# Group Order: ", 15)) {
     i32 ord = -1;
-    i32 ok = sscanf(line + 15, "%hu", &meta->order);
+    i32 ok = sscanf(line + 15, "%hu%c", &meta->order, &dummy) == 1;
     if(ok == 1 && ord > 0) {
       meta->order = ord;
     }
   }
   if(!strncmp(line, "# Group Commutative: ", 21)) {
     i32 isComm = -1;
-    i32 ok = sscanf(line + 21, "%i", &isComm);
+    i32 ok = sscanf(line + 21, "%i%c", &isComm, &dummy) == 1;
     if(ok == 1 && (isComm == 1 || isComm == 0)) {
       meta->isCommutative = isComm;
     }
@@ -238,8 +263,6 @@ void group_parseMetaLine(char *line, GroupMetaInfo *meta)
     bool ok = 1;
     u16 val = 0xffff;
     while(tok != 0) {
-      // Enforce that no character after the number occurs to avoid faulty inp
-      char dummy = 0;
       ok = ok && (sscanf(tok, " %hx%c", &val, &dummy) == 1);
       // If we cannot properly read or have too many values to read, abort
       if(!ok || meta->minGenSetSize >= GROUP_META_MINGENSET_LEN) {

+ 18 - 3
src/group/group_io.h

@@ -5,6 +5,7 @@
 
 
 #define GROUP_META_NAME_LEN 32
+#define GROUP_META_FILENAME_LEN 27 // 5 + 2 + 16 + 4
 #define GROUP_META_MINGENSET_LEN 16
 
 /*
@@ -19,6 +20,11 @@ struct GroupMetaInfo {
 };
 typedef struct GroupMetaInfo GroupMetaInfo;
 
+
+// ---------------------------------------------------------------------------
+// Writing
+// ---------------------------------------------------------------------------
+
 /*
  * Tries to write the group to a file according to the following procedure:
  *   > Determine the maximal space a base-16 encoded group element needs
@@ -27,7 +33,7 @@ typedef struct GroupMetaInfo GroupMetaInfo;
  *     to fill the maximal space.
  *   > Do this process again but without any padding and calculate
  *     hash_djb2Reverse on this new string to serve as part of the filename
- *   > Construct the filename by <group_order>_<hash>.asoc.txt where
+ *   > Construct the filename by <group_order>_<hash>.txt where
  *     group_order is base-10 encoded and 0-padded to 5 characters
  *     (65534 is the maximal group order due to u16 restriction)
  *     Prepended to the above scheme can be an "u" if the isomorphism class
@@ -56,8 +62,17 @@ i32 group_sprintPreamble(char *buf);
 i32 group_sprintFileMeta(char *buf);
 i32 group_sprintGroupMeta(char *buf, GroupMetaInfo meta);
 
-u16 group_readOrderFromFileName(char *path);
-bool group_readCommutativeFromFileName(char *path);
+
+// ---------------------------------------------------------------------------
+// Reading
+// ---------------------------------------------------------------------------
+
+/*
+ * Checks if the file name complies with the group file name requirements
+ * If order and isCommutative are not 0-pointers, this information will be
+ * written to the pointers
+ */
+bool group_checkGroupFileName(char *path, u16 *order, bool *isCommutative);
 
 Group *group_readGroupFromFile_alloc(char *path);
 GroupMetaInfo group_readMetaFromFile(char *path);

+ 16 - 2
src/main.c

@@ -14,6 +14,9 @@
 #include "group/group_hom.h"
 #include "group/group_io.h"
 
+#include "application/group_library.h"
+
+i32 main_9();
 i32 main_8();
 i32 main_7();
 i32 main_6();
@@ -25,12 +28,23 @@ i32 main_1();
 
 i32 main()
 {
-  return main_8();
+  return main_9();
+}
+
+i32 main_9()
+{
+  Vecptr *fns = app_listGroupFiles_alloc("./grplib", 24, 0);
+  for(i32 i = 0; i < fns->size; i++) {
+    printf("File name: %s\n", (char *) *vecptr_at(fns, i));
+    free(*vecptr_at(fns, i));
+  }
+  vecptr_free(fns);
+  return 0;
 }
 
 i32 main_8()
 {
-  GroupMetaInfo m = group_readMetaFromFile("./groups/00024n_078a417cf4412f95.txt");
+  GroupMetaInfo m = group_readMetaFromFile("./grplib/00024n_078a417cf4412f95.txt");
   printf("meta.name: :%s:\n", m.name);
   printf("meta.order: :%u:\n", m.order);
   printf("meta.isCommutative: :%u:\n", m.isCommutative);