Merge branch 'master' of https://github.com/jerome-benoit/TD_C
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 20 Mar 2017 14:30:58 +0000 (15:30 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 20 Mar 2017 14:30:58 +0000 (15:30 +0100)
76 files changed:
.gitignore [new file with mode: 0644]
README [new file with mode: 0644]
TP_11/exo1/Makefile [new file with mode: 0644]
TP_11/exo1/clist.c [new file with mode: 0644]
TP_11/exo1/clist.h [new file with mode: 0644]
TP_11/exo1/exo1.c [new file with mode: 0644]
TP_11/exo2/Makefile [new file with mode: 0644]
TP_11/exo2/lib/clist.c [new file with mode: 0644]
TP_11/exo2/lib/clist.h [new file with mode: 0644]
TP_11/exo2/lib/ui.c [new file with mode: 0644]
TP_11/exo2/lib/ui.h [new file with mode: 0644]
TP_11/exo2/src/main.c [new file with mode: 0644]
TP_11/exo3/Makefile [new file with mode: 0644]
TP_11/exo3/exo3.c [new file with mode: 0644]
TP_12/exo1/Makefile [new file with mode: 0644]
TP_12/exo1/exo1.c [new file with mode: 0644]
TP_12/exo2/Makefile [new file with mode: 0644]
TP_12/exo2/exo2.c [new file with mode: 0644]
TP_12/exo2/test_file [new file with mode: 0644]
TP_12/exo3/Makefile [new file with mode: 0644]
TP_12/exo3/exo3.c [new file with mode: 0644]
TP_12/exo3/file_src [new file with mode: 0644]
TP_13/exo1/Makefile [new file with mode: 0644]
TP_13/exo1/lib/array.c [new file with mode: 0644]
TP_13/exo1/lib/array.h [new file with mode: 0644]
TP_13/exo1/lib/io.c [new file with mode: 0644]
TP_13/exo1/lib/io.h [new file with mode: 0644]
TP_13/exo1/lib/macros.h [new file with mode: 0644]
TP_13/exo1/lib/sort.c [new file with mode: 0644]
TP_13/exo1/lib/sort.h [new file with mode: 0644]
TP_13/exo1/lib/utils.c [new file with mode: 0644]
TP_13/exo1/lib/utils.h [new file with mode: 0644]
TP_13/exo1/src/main.c [new file with mode: 0644]
TP_13/exo2/Makefile [new file with mode: 0644]
TP_13/exo2/README [new file with mode: 0644]
TP_13/exo2/lib/coordinates.c [new file with mode: 0644]
TP_13/exo2/lib/coordinates.h [new file with mode: 0644]
TP_13/exo2/lib/display.c [new file with mode: 0644]
TP_13/exo2/lib/display.h [new file with mode: 0644]
TP_13/exo2/lib/macros.h [new file with mode: 0644]
TP_13/exo2/lib/utils.c [new file with mode: 0644]
TP_13/exo2/lib/utils.h [new file with mode: 0644]
TP_13/exo2/src/main.c [new file with mode: 0644]
TP_7/exo1/Makefile [new file with mode: 0644]
TP_7/exo1/exo1.c [new file with mode: 0644]
TP_7/exo2/Makefile [new file with mode: 0644]
TP_7/exo2/exo2.c [new file with mode: 0644]
TP_7/exo3/Makefile [new file with mode: 0644]
TP_7/exo3/exo3.c [new file with mode: 0644]
TP_7_C/Makefile [new file with mode: 0644]
TP_7_C/README [new file with mode: 0644]
TP_7_C/exo1-base.c [new file with mode: 0644]
TP_7_C/exo1-extra.c [new file with mode: 0644]
TP_7_C/exo1-full.c [new file with mode: 0644]
TP_7_C/exo2-base.c [new file with mode: 0644]
TP_7_C/exo2-extra.c [new file with mode: 0644]
TP_7_C/exo2-full.c [new file with mode: 0644]
TP_7_C/exo3-base.c [new file with mode: 0644]
TP_7_C/exo3-extra.c [new file with mode: 0644]
TP_7_C/exo3-full.c [new file with mode: 0644]
TP_8/exo1/Makefile [new file with mode: 0644]
TP_8/exo1/exo1.c [new file with mode: 0644]
TP_8/exo2/Makefile [new file with mode: 0644]
TP_8/exo2/exo2.c [new file with mode: 0644]
TP_8/exo3/Makefile [new file with mode: 0644]
TP_8/exo3/exo3.c [new file with mode: 0644]
TP_9/exo1/Makefile [new file with mode: 0644]
TP_9/exo1/clist.c [new file with mode: 0644]
TP_9/exo1/clist.h [new file with mode: 0644]
TP_9/exo1/exo1.c [new file with mode: 0644]
TP_9/exo2/Makefile [new file with mode: 0644]
TP_9/exo2/clist.c [new file with mode: 0644]
TP_9/exo2/clist.h [new file with mode: 0644]
TP_9/exo2/exo2.c [new file with mode: 0644]
exo_skel/Makefile [new file with mode: 0644]
exo_skel/exo_skel.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e13bfde
--- /dev/null
@@ -0,0 +1,18 @@
+*.static
+*.dynamic
+# for cygwin  
+*.exe
+
+*.o
+
+*.so
+*.a
+
+# editor trash
+*.swp
+*~
+
+.build
+
+thumbs.db
+*.DS_Store
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..d78fddc
--- /dev/null
+++ b/README
@@ -0,0 +1,36 @@
+Introduction:
+-------------
+
+The whole purpose of the current C code is to solve the 
+Polytech'Marseille C tutorial exercices.
+
+The repositories organisation is pretty straightforward: 
+TP_#/exo?, where # is a digit representing the TP number and
+? is a digit representing the exercice number, is the repository
+where lies the solution to exercice ? TP #.
+
+Building the solution:
+-----------------------
+
+  cd TP_#/exo? && make
+
+Cleaning the solution:
+-----------------------
+
+  cd TP_#/exo? && make clean
+
+Running the solution:
+----------------------
+
+  cd TP_#/exo? && ./exo?
+
+Exercice skeleton:
+------------------
+
+It's the directory exo_skel with a basic Makefile inside
+
+To use it:
+  $ cp -a exo_skel TP_#/exo? (where # and ? are digits)
+  $ cd TP_#/exo? && cp exo_skel.c exo?.c
+  Edit the Makefile to change the TARGET variable to the
+  exercice name desired
diff --git a/TP_11/exo1/Makefile b/TP_11/exo1/Makefile
new file mode 100644 (file)
index 0000000..9720be9
--- /dev/null
@@ -0,0 +1,107 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo1
+LIBOBJS=clist.o # object to put in the library
+LIBRARY_NAME=libtpC
+#LDLIBS=-L. -ltpC
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME) $(BINARY_NAME).dynamic $(BINARY_NAME).staticlocal
+
+CC=gcc
+LD=gcc
+AR=ar
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+#FIXME: Add a way to better control the library build
+CFLAGS := -fPIC $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+LIBLDFLAGS := -shared $(LDFLAGS)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+OBJSLIB=$(addprefix $(OBJDIR)/,$(LIBOBJS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(LIBRARY_NAME).a: $(OBJSLIB)
+       @echo "[AR StO] $@"
+       @$(AR) rcs $@ $^
+
+$(LIBRARY_NAME).so: $(OBJSLIB)
+       @echo "[LD ShO] $@"
+       @$(LD) $(CFLAGS) $(LIBLDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+LOCALLDLIBS=-L. -ltpC
+$(BINARY_NAME).staticlocal: $(OBJDIR)/$(BINARY_NAME).o $(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LOCALLDLIBS) $(LDLIBS) -o $@
+
+$(BINARY_NAME).dynamic: $(OBJDIR)/$(BINARY_NAME).o $(LIBRARY_NAME).so
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LOCALLDLIBS) $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+       -@rm $(BINARY_NAME).staticlocal
+       -@rm $(BINARY_NAME).dynamic
+       -@rm $(LIBRARY_NAME).so
+       -@rm $(LIBRARY_NAME).a
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_11/exo1/clist.c b/TP_11/exo1/clist.c
new file mode 100644 (file)
index 0000000..244a687
--- /dev/null
@@ -0,0 +1,216 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "clist.h"
+
+link_t* list_new(int value) {
+    link_t* link_new;  
+    link_new = malloc(sizeof(link_t));
+    link_new->value = value;
+    link_new->next = NULL;
+    return link_new;
+}
+
+link_t* list_append(link_t* head, int value) {
+
+    if (head == NULL) { 
+        return head = list_new(value);
+    } else {
+        link_t* head_first = head;
+        while (head->next != NULL) {
+           head = head->next; 
+        }
+        head->next = list_new(value);
+        return head_first;
+    }
+}
+
+link_t* list_prepend(link_t* head, int value) {
+    link_t* first_link = list_new(value);
+    
+    first_link->next = head;
+    return first_link;
+}
+
+link_t* list_insert(link_t* head, unsigned index, int value) {
+
+    if (index == 0) {
+        return list_prepend(head, value);  
+    } else if (index == list_count(head)) {
+        return list_append(head, value);
+    } else {
+        link_t* link_insrt = list_new(value);  
+        link_t* head_first = head;
+        link_t* head_next = NULL;
+        for (unsigned i = 0; i < index-1; i++) {
+            head = head->next;
+        }
+        head_next = head->next;
+        head->next = link_insrt;
+        head = link_insrt;
+        head->next = head_next; 
+        return head_first;
+    }
+}
+
+link_t* list_delete(link_t* head, unsigned index) {
+    link_t* head_prev = NULL;
+    link_t* head_next = NULL;
+    link_t* head_ret = NULL;
+   
+    if (head == NULL) {
+        return NULL;
+    } else if (index == 0) {
+        head_next = head->next;
+        free(head);
+        head = head_next;
+        head_ret = head;
+    } else {
+        link_t* head_first = head;
+        for (unsigned i = 0; i < index-1; i++) {
+            head = head->next;
+        }
+        head_prev = head;
+        head = head->next;
+        head_next = head->next;
+        free(head);
+        head = head_prev;
+        head->next = head_next;
+        head_ret = head_first;
+    }
+    if (head_ret != NULL) {
+        return head_ret;
+    } else {
+        return NULL;
+    }
+}
+
+link_t* list_concat(link_t* first, link_t* second) {
+    link_t* head_first = first;
+
+    while (first->next != NULL) {
+        first = first->next;
+    }
+    first->next = second;
+    return head_first;
+}
+
+link_t* list_sort(link_t* head) {
+    int tmp;
+    bool isswaped;
+    link_t* head_first = head;
+
+    do {
+        isswaped = false;
+        while (head->next != NULL) {
+            if (head->value > head->next->value) {
+                tmp = head->value;
+                head->value = head->next->value;
+                head->next->value = tmp;
+               isswaped = true;
+            }
+           head = head->next;
+        }
+       /* Reloop at the beginning of the list until there's values swaped */
+       head = head_first;
+    } while (isswaped);
+    return head_first;
+}
+
+static link_t* _list_merge_sort(link_t* head1, link_t* head2) {
+    link_t* head_result = NULL;
+
+    if (head1 == NULL) {
+        return head2;
+    }
+    if (head2 == NULL) {
+        return head1;
+    }
+    if (head1->value < head2->value) {
+        head_result = head1;
+       head_result->next = _list_merge_sort(head1->next, head2);
+    } else {
+        head_result = head2;
+       head_result->next = _list_merge_sort(head1, head2->next);
+    }
+    return head_result;
+}
+
+link_t* list_merge_sort(link_t* head) {
+    link_t* head1;
+    link_t* head2;
+
+    if (head == NULL || head->next == NULL) {
+        return head;
+    }
+
+    head1 = head;
+    head2 = head->next;
+    while (head2 != NULL && head2->next != NULL) {
+        head = head->next;
+        head2 = head->next->next;
+    }
+    head2 = head->next;
+    head->next = NULL;
+
+    head1 = list_merge_sort(head1);
+    head2 = list_merge_sort(head2);
+    return _list_merge_sort(head1, head2);
+}
+
+unsigned list_count(link_t* head) {
+    unsigned count = 0;
+    
+    while (head != NULL) {
+        ++count;
+        head = head->next;
+    } 
+    return count;
+}
+
+void list_set(link_t* head, unsigned index, int value) {
+    unsigned count = 0;
+
+    while (head != NULL && count < index) {
+        ++count;
+        head = head->next;
+    }
+    if (head != NULL) { head->value = value; }
+}
+
+int list_get(link_t* head, unsigned index) {
+    unsigned count = 0;    
+
+    while (head != NULL && count < index) {
+        ++count;
+        head = head->next; 
+    }
+    if (head != NULL) { 
+        return head->value;
+    } else {
+        return -1;
+    }
+}
+
+void list_clear(link_t* head) {
+    link_t* next_link = NULL;
+
+    while (head != NULL) {
+        next_link = head->next;
+        free(head);
+        head = next_link;
+    }
+}
+
+void list_display_values(link_t* head) {
+    unsigned i = 0;
+
+    printf("------Begin------\n");
+    while (head != NULL) {
+        printf("value at [%d]=%d\n", i, head->value);
+       head = head->next;
+       i++;
+    }
+    printf("------End------\n");
+}
diff --git a/TP_11/exo1/clist.h b/TP_11/exo1/clist.h
new file mode 100644 (file)
index 0000000..2ca5752
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef CLIST_H
+#define CLIST_H
+
+/** Linked list of int */
+typedef struct link_s {
+    int value;
+    struct link_s* next;
+} link_t;
+
+link_t* list_new(int value); 
+link_t* list_append(link_t* head, int value); 
+link_t* list_prepend(link_t* head, int value); 
+link_t* list_insert(link_t* head, unsigned index, int value);
+link_t* list_delete(link_t* head, unsigned index);
+link_t* list_concat(link_t* first, link_t* second);
+link_t* list_sort(link_t* head);
+link_t* list_merge_sort(link_t* head);
+unsigned list_count(link_t* head);
+void list_set(link_t* head, unsigned index, int value);
+int list_get(link_t* head, unsigned index);
+void list_clear(link_t* head);
+void list_display_values(link_t* head);
+
+#endif /* CLIST_H */
diff --git a/TP_11/exo1/exo1.c b/TP_11/exo1/exo1.c
new file mode 100644 (file)
index 0000000..810bd9e
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+#include "clist.h"
+
+int main() {
+    link_t* head1 = NULL;
+    link_t* head2 = NULL;
+    link_t* head = NULL;
+
+    printf("Longueur de la liste: %d\n", list_count(head1));
+    head1 = list_append(head1, 1);
+    head1 = list_append(head1, 2);
+    head1 = list_append(head1, 3);
+    head1 = list_append(head1, 4);
+    printf("Longueur de la liste: %d\n", list_count(head1));
+    list_display_values(head1);
+    head1 = list_prepend(head1, 5);
+    printf("Longueur de la liste: %d\n", list_count(head1));
+    list_display_values(head1);
+    list_set(head1, 0, 78);
+    list_display_values(head1);
+    head1 = list_insert(head1, 2, 7);
+    list_display_values(head1);
+    head1 = list_delete(head1, 3);
+    list_display_values(head1);
+    head1 = list_append(head1, 5);
+    head1 = list_append(head1, 12);
+    head1 = list_append(head1, 65);
+    head1 = list_append(head1, 21);
+    head1 = list_sort(head1);
+    list_display_values(head1);
+    head2 = list_insert(head2, 0, 8);
+    head2 = list_append(head2, 6);
+    head2 = list_prepend(head2, 5);
+    list_display_values(head2);
+    head = list_concat(head1, head2);
+    list_display_values(head);
+    head = list_merge_sort(head);
+    //head = list_sort(head);
+    list_display_values(head);
+    //list_clear(head1);
+    //list_clear(head2);
+    list_clear(head);
+
+    return 0;
+}
diff --git a/TP_11/exo2/Makefile b/TP_11/exo2/Makefile
new file mode 100644 (file)
index 0000000..d8dd23a
--- /dev/null
@@ -0,0 +1,149 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# $(SRC_PATH) directory.
+#
+# This Makefile expect all embedded library source files (.c) to be at the same level, in the
+# $(LIBRARY_PATH) directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name linked against the library if necessary.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set LIBRARY_NAME to the name of the library file to build.
+# The default path for the library code and object is lib.
+# By default the linker will look for $(BINARY_NAME) library name.
+# Set BUILD_TYPE to either debug or release.
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo2
+SRC_PATH:=src
+LIBRARY_NAME=libexo2
+LIBRARY_PATH:=lib
+BUILD_TYPE=debug
+#BUILD_TYPE=release
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME) $(BINARY_NAME).dynamic $(BINARY_NAME).static
+
+CC=gcc
+LD=gcc
+AR=ar
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+UNAME := $(shell uname -o)
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+LTO_SUPPORT = yes
+GOLD_SUPPORT = yes
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+LTO_SUPPORT = yes
+GOLD_SUPPORT = yes
+endif
+
+ifeq ($(UNAME),Cygwin)
+GOLD_SUPPORT = no
+endif
+
+ifeq ($(LTO_SUPPORT),yes)
+CFLAGS_LTO = -flto -ffat-lto-objects
+LDFLAGS_LTO = -fuse-linker-plugin -flto
+endif
+
+ifeq ($(GOLD_SUPPORT),yes)
+LDFLAGS_GOLD = -fuse-ld=gold
+endif
+
+# Putting header files in the source directory is not the purpose of this INCLUDES variable
+INCLUDES := $(INCLUDES) -I$(LIBRARY_PATH)
+CFLAGS := $(CFLAGS) $(CFLAGS_LTO) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG) $(INCLUDES)
+LIBCFLAGS := -fPIC $(CFLAGS)
+LDFLAGS := $(LDFLAGS) $(LDFLAGS_LTO) $(LDFLAGS_GOLD) $(STRIP_FLAG)
+LIBLDFLAGS := -shared $(LDFLAGS)
+STATICLIBLDFLAGS := -static $(LDFLAGS)
+LDLIBS := $(LDLIBS) -L$(LIBRARY_PATH) -l$(BINARY_NAME)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard $(SRC_PATH)/*.c)
+LIBSRCS=$(wildcard $(LIBRARY_PATH)/*.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SRCS)))
+LIBOBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(LIBSRCS)))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$(notdir $*).Td
+POSTCOMPILE = mv -f $(DEPDIR)/$(notdir $*).Td $(DEPDIR)/$(notdir $*).d
+
+$(LIBRARY_PATH)/$(LIBRARY_NAME).a: $(LIBOBJS)
+       @echo "[AR StO] $@"
+       @$(AR) rcs $@ $^
+
+$(LIBRARY_PATH)/$(LIBRARY_NAME).so: $(LIBOBJS)
+       @echo "[LD ShO] $@"
+       @$(LD) $(LIBCFLAGS) $(LIBLDFLAGS) $^ -o $@
+
+#$(BINARY_NAME): $(OBJS) $(LIBOBJS)
+#      @echo "[LD ] $@"
+#      @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME): $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME).static: $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(STATICLIBLDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME).dynamic: $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).so
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: $(SRC_PATH)/%.c $(DEPDIR)/%.d
+       @echo "[C  ] $(notdir $*)"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+$(OBJDIR)/%.o: $(LIBRARY_PATH)/%.c $(DEPDIR)/%.d
+       @echo "[C  ] $(notdir $*)"
+       @$(CC) $(DEPFLAGS) $(LIBCFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(LIBSRCS))))
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+#FIXME: add an install target
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+       -@rm $(BINARY_NAME).static
+       -@rm $(BINARY_NAME).dynamic
+       -@rm $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       -@rm $(LIBRARY_PATH)/$(LIBRARY_NAME).so
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_11/exo2/lib/clist.c b/TP_11/exo2/lib/clist.c
new file mode 100644 (file)
index 0000000..3031154
--- /dev/null
@@ -0,0 +1,217 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "clist.h"
+
+link_t* list_new(int value) {
+    link_t* link_new;  
+    link_new = malloc(sizeof(link_t));
+    link_new->value = value;
+    link_new->next = NULL;
+    return link_new;
+}
+
+link_t* list_append(link_t* head, int value) {
+
+    if (head == NULL) { 
+        return head = list_new(value);
+    } else {
+        link_t* head_first = head;
+        while (head->next != NULL) {
+           head = head->next; 
+        }
+        head->next = list_new(value);
+        return head_first;
+    }
+}
+
+link_t* list_prepend(link_t* head, int value) {
+    link_t* first_link = list_new(value);
+    
+    first_link->next = head;
+    return first_link;
+}
+
+link_t* list_insert(link_t* head, unsigned index, int value) {
+    unsigned max_index = list_count(head);
+
+    if (index == 0) {
+        return list_prepend(head, value);  
+    } else if (index == max_index) {
+        return list_append(head, value);
+    } else {
+        link_t* link_insrt = list_new(value);  
+        link_t* head_first = head;
+        link_t* head_next = NULL;
+        for (unsigned i = 0; i < index-1; i++) {
+            head = head->next;
+        }
+        head_next = head->next;
+        head->next = link_insrt;
+        head = link_insrt;
+        head->next = head_next; 
+        return head_first;
+    }
+}
+
+link_t* list_delete(link_t* head, unsigned index) {
+    link_t* head_prev = NULL;
+    link_t* head_next = NULL;
+    link_t* head_ret = NULL;
+
+    if (head == NULL) {
+        return NULL;
+    } else if (index == 0) {
+        head_next = head->next;
+        free(head);
+        head = head_next;
+        head_ret = head;
+    } else {
+        link_t* head_first = head;
+        for (unsigned i = 0; i < index-1; i++) {
+            head = head->next;
+        }
+        head_prev = head;
+        head = head->next;
+        head_next = head->next;
+        free(head);
+        head = head_prev;
+        head->next = head_next;
+        head_ret = head_first;
+    }
+    if (head_ret != NULL) {
+        return head_ret;
+    } else {
+        return NULL;
+    }
+}
+
+link_t* list_concat(link_t* first, link_t* second) {
+    link_t* head_first = first;
+
+    while (first->next != NULL) {
+        first = first->next;
+    }
+    first->next = second;
+    return head_first;
+}
+
+link_t* list_sort(link_t* head) {
+    int tmp;
+    bool isswaped;
+    link_t* head_first = head;
+
+    do {
+        isswaped = false;
+        while (head->next != NULL) {
+            if (head->value > head->next->value) {
+                tmp = head->value;
+                head->value = head->next->value;
+                head->next->value = tmp;
+               isswaped = true;
+            }
+           head = head->next;
+        }
+       /* Reloop at the beginning of the list until there's values swaped */
+       head = head_first;
+    } while (isswaped);
+    return head_first;
+}
+
+static link_t* _list_merge_sort(link_t* head1, link_t* head2) {
+    link_t* head_result = NULL;
+
+    if (head1 == NULL) {
+        return head2;
+    }
+    if (head2 == NULL) {
+        return head1;
+    }
+    if (head1->value < head2->value) {
+        head_result = head1;
+       head_result->next = _list_merge_sort(head1->next, head2);
+    } else {
+        head_result = head2;
+       head_result->next = _list_merge_sort(head1, head2->next);
+    }
+    return head_result;
+}
+
+link_t* list_merge_sort(link_t* head) {
+    link_t* head1;
+    link_t* head2;
+
+    if (head == NULL || head->next == NULL) {
+        return head;
+    }
+
+    head1 = head;
+    head2 = head->next;
+    while (head2 != NULL && head2->next != NULL) {
+        head = head->next;
+        head2 = head->next->next;
+    }
+    head2 = head->next;
+    head->next = NULL;
+
+    head1 = list_merge_sort(head1);
+    head2 = list_merge_sort(head2);
+    return _list_merge_sort(head1, head2);
+}
+
+unsigned list_count(link_t* head) {
+    unsigned count = 0;
+    
+    while (head != NULL) {
+        ++count;
+        head = head->next;
+    } 
+    return count;
+}
+
+void list_set(link_t* head, unsigned index, int value) {
+    unsigned count = 0;
+
+    while (head != NULL && count < index) {
+        ++count;
+        head = head->next;
+    }
+    if (head != NULL) { head->value = value; }
+}
+
+int list_get(link_t* head, unsigned index) {
+    unsigned count = 0;    
+
+    while (head != NULL && count < index) {
+        ++count;
+        head = head->next; 
+    }
+    if (head != NULL) { 
+        return head->value;
+    } else {
+        return -1;
+    }
+}
+
+void list_clear(link_t* head) {
+    link_t* next_link = NULL;
+
+    while (head != NULL) {
+        next_link = head->next;
+        free(head);
+        head = next_link;
+    }
+}
+
+void list_display_values(link_t* head) {
+    unsigned i = 0;
+
+    printf("------Begin------\n");
+    while (head != NULL) {
+        printf("value at [%d]=%d\n", i, head->value);
+        head = head->next;
+        i++;
+    }
+    printf("------End------\n");
+}
diff --git a/TP_11/exo2/lib/clist.h b/TP_11/exo2/lib/clist.h
new file mode 100644 (file)
index 0000000..2ca5752
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef CLIST_H
+#define CLIST_H
+
+/** Linked list of int */
+typedef struct link_s {
+    int value;
+    struct link_s* next;
+} link_t;
+
+link_t* list_new(int value); 
+link_t* list_append(link_t* head, int value); 
+link_t* list_prepend(link_t* head, int value); 
+link_t* list_insert(link_t* head, unsigned index, int value);
+link_t* list_delete(link_t* head, unsigned index);
+link_t* list_concat(link_t* first, link_t* second);
+link_t* list_sort(link_t* head);
+link_t* list_merge_sort(link_t* head);
+unsigned list_count(link_t* head);
+void list_set(link_t* head, unsigned index, int value);
+int list_get(link_t* head, unsigned index);
+void list_clear(link_t* head);
+void list_display_values(link_t* head);
+
+#endif /* CLIST_H */
diff --git a/TP_11/exo2/lib/ui.c b/TP_11/exo2/lib/ui.c
new file mode 100644 (file)
index 0000000..b8233b5
--- /dev/null
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+#include "ui.h"
+
+int promptValue(const char* msg, int* result) { 
+    puts(msg); 
+    int retVal = scanf("%d", result); 
+    return (retVal == 1) ? 0 : 1; 
+}
+
+void displayArray(const int array[], unsigned length) {
+    printf("--Begin--\n");
+    for (unsigned i = 0; i < length; i++) {
+        printf("array[%d]=%d\n", i, array[i]);
+    }
+    printf("--End--\n");
+}
+
+void displayList(link_t* head) {
+    printf("--Begin--\n");
+    for (unsigned i = 0, length = list_count(head); i < length; i++) {
+        printf("value at [%d]=%d\n", i, list_get(head, i));
+    }
+    printf("--End--\n");
+}
diff --git a/TP_11/exo2/lib/ui.h b/TP_11/exo2/lib/ui.h
new file mode 100644 (file)
index 0000000..afb35df
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef UI_H
+#define UI_H
+
+#include "clist.h"
+
+int promptValue(const char* msg, int* result);
+void displayArray(const int array[], unsigned length);
+void displayList(link_t* head);
+
+#endif /* UI_H */
diff --git a/TP_11/exo2/src/main.c b/TP_11/exo2/src/main.c
new file mode 100644 (file)
index 0000000..65e791b
--- /dev/null
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "ui.h"
+
+int main() {
+    link_t* head = NULL;
+    unsigned counter = 0;
+    int value = 0;
+    int promptrtVal = 0;
+    int* array = NULL;
+
+    while (true) {
+       promptrtVal = promptValue("Saisir une valeur:", &value);
+       if (promptrtVal != 0)
+           break;
+       head = list_append(head, value);
+       counter++;
+    }
+    printf("Liste:\n");
+    displayList(head);
+    array = malloc(counter*sizeof(int));
+    array[0] = list_get(head, 0);
+    for (unsigned i = 1; i < counter; i++) {
+        array[i] = array[i-1] + list_get(head, i);
+    }
+    printf("Tableau des sommes:\n");
+    displayArray(array, counter);
+    list_clear(head);
+    free(array);
+
+    return 0;
+}
diff --git a/TP_11/exo3/Makefile b/TP_11/exo3/Makefile
new file mode 100644 (file)
index 0000000..ede673f
--- /dev/null
@@ -0,0 +1,79 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo3
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME)
+
+CC=gcc
+LD=gcc
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_11/exo3/exo3.c b/TP_11/exo3/exo3.c
new file mode 100644 (file)
index 0000000..a1aedde
--- /dev/null
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[]) {
+    printf("argc=%d\n", argc);
+    for (int i = 0; i < argc; i++) {
+        printf("argv[%d]=\"%s\"\n", i, argv[i]);
+    }
+
+    return 0;
+}
diff --git a/TP_12/exo1/Makefile b/TP_12/exo1/Makefile
new file mode 100644 (file)
index 0000000..eb33b06
--- /dev/null
@@ -0,0 +1,79 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo1
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME)
+
+CC=gcc
+LD=gcc
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_12/exo1/exo1.c b/TP_12/exo1/exo1.c
new file mode 100644 (file)
index 0000000..900c5b2
--- /dev/null
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+typedef bool(*compare_cb)(int a, int b);
+
+bool ascending(int a, int b) {
+    return a > b;
+}
+
+bool descending(int a, int b) {
+    return a < b;
+}
+
+void swap(int* v1, int* v2) {
+    int tmp = *v1;
+    *v1 = *v2;
+    *v2 = tmp;
+}
+
+void displayArray(int* array, int count) {
+    for (int i = 0; i < count; i++) {
+        printf("Value in array at index[%d]= %d\n", i, array[i]);
+    }
+}
+
+bool sortFirst(int* array, int length, compare_cb compare) {
+    bool rt = false;
+    for (int i = 0; i < length-1; i++) {
+        if (compare(array[i], array[i+1])) {
+            swap(&array[i], &array[i+1]);
+            if (!rt) { rt = true; };
+        }
+    }
+    return rt;
+}
+
+void sortArray(int* array, int length, compare_cb compare) {
+    bool rt; 
+    do {
+        rt = sortFirst(array, length, compare);
+    } while (rt);
+}
+
+int main() {
+    const int tab_size = 10;
+    int tab[10] = {4, 6, 2, 9, 5, 7, 1, 3, 8, 0};
+
+    printf("\nView array content unsorted:\n");
+    displayArray(tab, tab_size);
+    printf("\nNow, sorting the array ascending...\n");
+    sortArray(tab, tab_size, ascending);
+    printf("\nView array content sorted:\n");
+    displayArray(tab, tab_size);
+    printf("\nNow, sorting the array descending...\n");
+    sortArray(tab, tab_size, descending);
+    printf("\nView array content sorted:\n");
+    displayArray(tab, tab_size);
+
+    return 0;
+}
diff --git a/TP_12/exo2/Makefile b/TP_12/exo2/Makefile
new file mode 100644 (file)
index 0000000..8c707d7
--- /dev/null
@@ -0,0 +1,79 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo2
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME)
+
+CC=gcc
+LD=gcc
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_12/exo2/exo2.c b/TP_12/exo2/exo2.c
new file mode 100644 (file)
index 0000000..f8dea49
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+    char ch;
+    char* fname;
+    FILE* fp;
+
+    printf("Enter the name of the file you wish to see\n");
+    scanf("%s", fname);
+
+    fp = fopen(fname, "r"); /* read mode */
+    if (fp == NULL) {
+        perror("Error while opening the file.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    printf("The content of %s file is :\n", fname);
+
+    while((ch = fgetc(fp)) != EOF)
+         printf("%c", ch);
+
+    fclose(fp);
+
+    return EXIT_SUCCESS;
+}
diff --git a/TP_12/exo2/test_file b/TP_12/exo2/test_file
new file mode 100644 (file)
index 0000000..341dcec
--- /dev/null
@@ -0,0 +1,3 @@
+Bonjour,
+
+Je suis un fichier texte de test, ouvrez moi, demonter moi.
diff --git a/TP_12/exo3/Makefile b/TP_12/exo3/Makefile
new file mode 100644 (file)
index 0000000..ede673f
--- /dev/null
@@ -0,0 +1,79 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo3
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME)
+
+CC=gcc
+LD=gcc
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_12/exo3/exo3.c b/TP_12/exo3/exo3.c
new file mode 100644 (file)
index 0000000..3e5560a
--- /dev/null
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char** argv) {
+    char* fnamesrc = (char*)argv[1], fnamedest = (char*)argv[2];
+    FILE* fpsrc, fpdest;
+
+    if (argc < 3) {
+        puts("Please enter two arguments separated by a space: file_name_src file_name_dest");
+        exit(EXIT_FAILURE);
+    }
+
+    fpsrc = fopen(fnamesrc, "r"); /* read mode */
+    if (fpsrc == NULL) {
+        perror("Error while opening the source file.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    fclose(fpsrc);
+
+    return EXIT_SUCCESS;
+}
diff --git a/TP_12/exo3/file_src b/TP_12/exo3/file_src
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/TP_13/exo1/Makefile b/TP_13/exo1/Makefile
new file mode 100644 (file)
index 0000000..152498c
--- /dev/null
@@ -0,0 +1,149 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# $(SRC_PATH) directory.
+#
+# This Makefile expect all embedded library source files (.c) to be at the same level, in the
+# $(LIBRARY_PATH) directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name linked against the library if necessary.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set LIBRARY_NAME to the name of the library file to build.
+# The default path for the library code and object is lib.
+# By default the linker will look for $(BINARY_NAME) library name.
+# Set BUILD_TYPE to either debug or release.
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo1
+SRC_PATH:=src
+LIBRARY_NAME=libexo1
+LIBRARY_PATH:=lib
+BUILD_TYPE=debug
+#BUILD_TYPE=release
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME) $(BINARY_NAME).dynamic $(BINARY_NAME).static
+
+CC=gcc
+LD=gcc
+AR=ar
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+UNAME := $(shell uname -o)
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+LTO_SUPPORT = yes
+GOLD_SUPPORT = yes
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+LTO_SUPPORT = yes
+GOLD_SUPPORT = yes
+endif
+
+ifeq ($(UNAME),Cygwin)
+GOLD_SUPPORT = no
+endif
+
+ifeq ($(LTO_SUPPORT),yes)
+CFLAGS_LTO = -flto -ffat-lto-objects
+LDFLAGS_LTO = -fuse-linker-plugin -flto
+endif
+
+ifeq ($(GOLD_SUPPORT),yes)
+LDFLAGS_GOLD = -fuse-ld=gold
+endif
+
+# Putting header files in the source directory is not the purpose of this INCLUDES variable
+INCLUDES := $(INCLUDES) -I$(LIBRARY_PATH)
+CFLAGS := $(CFLAGS) $(CFLAGS_LTO) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG) $(INCLUDES)
+LIBCFLAGS := -fPIC $(CFLAGS)
+LDFLAGS := $(LDFLAGS) $(LDFLAGS_LTO) $(LDFLAGS_GOLD) $(STRIP_FLAG)
+LIBLDFLAGS := -shared $(LDFLAGS)
+STATICLIBLDFLAGS := -static $(LDFLAGS)
+LDLIBS := $(LDLIBS) -L$(LIBRARY_PATH) -l$(BINARY_NAME)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard $(SRC_PATH)/*.c)
+LIBSRCS=$(wildcard $(LIBRARY_PATH)/*.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SRCS)))
+LIBOBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(LIBSRCS)))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$(notdir $*).Td
+POSTCOMPILE = mv -f $(DEPDIR)/$(notdir $*).Td $(DEPDIR)/$(notdir $*).d
+
+$(LIBRARY_PATH)/$(LIBRARY_NAME).a: $(LIBOBJS)
+       @echo "[AR StO] $@"
+       @$(AR) rcs $@ $^
+
+$(LIBRARY_PATH)/$(LIBRARY_NAME).so: $(LIBOBJS)
+       @echo "[LD ShO] $@"
+       @$(LD) $(LIBCFLAGS) $(LIBLDFLAGS) $^ -o $@
+
+#$(BINARY_NAME): $(OBJS) $(LIBOBJS)
+#      @echo "[LD ] $@"
+#      @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME): $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME).static: $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(STATICLIBLDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME).dynamic: $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).so
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: $(SRC_PATH)/%.c $(DEPDIR)/%.d
+       @echo "[C  ] $(notdir $*)"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+$(OBJDIR)/%.o: $(LIBRARY_PATH)/%.c $(DEPDIR)/%.d
+       @echo "[C  ] $(notdir $*)"
+       @$(CC) $(DEPFLAGS) $(LIBCFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(LIBSRCS))))
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+#FIXME: add an install target
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+       -@rm $(BINARY_NAME).static
+       -@rm $(BINARY_NAME).dynamic
+       -@rm $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       -@rm $(LIBRARY_PATH)/$(LIBRARY_NAME).so
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_13/exo1/lib/array.c b/TP_13/exo1/lib/array.c
new file mode 100644 (file)
index 0000000..db8ab7e
--- /dev/null
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "array.h"
+
+int* create_tab(int tab[], unsigned tab_size) {
+    tab = malloc(sizeof(int) * tab_size);
+    if (tab != NULL) {
+        /* initialize to zero the integer array */
+        for (unsigned i = 0; i < tab_size; i++) {
+            tab[i] = 0;
+        }
+    }
+    return tab;
+}
+
+void free_tab(int tab[]) {
+    free(tab);
+}
+
+/* we suppose both tabs are already created */
+static void copy_tab(int src_tab[], int dest_tab[], unsigned src_tab_size, unsigned index_offset) {
+    /* FIXME: I think it's worth doing some sanity checks on the array size:
+     * dest_tab_size >= src_tab_size */
+    if (src_tab == NULL || dest_tab == NULL) {
+        printf("please ensure you have created both arrays beforehand\n");
+        return;
+    }
+    for (unsigned i = 0; i < src_tab_size; i++) {
+        dest_tab[i + index_offset] = src_tab[i];
+    }
+}
+
+/* one must free the two source tabs in case they will be unused after to concatenation  */
+int* concat_tab(int tab1[], unsigned tab_size1, int tab2[], unsigned tab_size2) {
+    int* tab_dest = NULL;
+    tab_dest = create_tab(tab_dest, tab_size1 + tab_size2);
+
+    copy_tab(tab1, tab_dest, tab_size1, 0);
+    copy_tab(tab2, tab_dest, tab_size2, tab_size1);
+    return tab_dest;
+}
+
+int* resize_tab(int tab[], unsigned old_tab_size, unsigned new_tab_size) {
+    tab = realloc(tab, sizeof(int) * new_tab_size);
+    if (old_tab_size < new_tab_size) {
+        for (unsigned i = old_tab_size; i < new_tab_size; i++) {
+            tab[i] = 0;
+        }
+    }
+    return tab;
+}
+
+/* number of occurences of an element in an unsorted array  */
+unsigned count_tab_element(int tab[], unsigned tab_size, int element) {
+    unsigned el_count = 0;
+
+    for (unsigned i = 0; i < tab_size; i++) {
+        if (tab[i] == element) {
+            el_count++;
+        }
+    }
+    return el_count;
+}
+
+unsigned count_tab_criteria(int tab[], unsigned tab_size, c_criteria_cb c_criteria) {
+    unsigned cr_count = 0;
+
+    for (unsigned i = 0; i < tab_size; i++) {
+        if (c_criteria(tab[i])) {
+            cr_count++;
+        }
+    }
+    return cr_count;
+}
+
+bool is_even(int a) {
+    return (a % 2 == 0);
+}
+
+bool is_odd(int a) {
+    return (a % 2 != 0);
+
+}
+
+void sort_tab(int tab[], unsigned tab_size, s_criteria_cb sort_criteria) {
+    sort_bubble_array(tab, tab_size, sort_criteria);
+}
diff --git a/TP_13/exo1/lib/array.h b/TP_13/exo1/lib/array.h
new file mode 100644 (file)
index 0000000..4e58754
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include <stdbool.h>
+
+#include "sort.h"
+
+typedef bool(*c_criteria_cb)(int a);
+
+bool is_even(int a);
+bool is_odd(int a);
+
+int* create_tab(int tab[], unsigned tab_size);
+void free_tab(int tab[]);
+int* concat_tab(int tab1[], unsigned tab_size1, int tab2[], unsigned tab_size2);
+int* resize_tab(int tab[], unsigned old_tab_size, unsigned new_tab_size);
+unsigned count_tab_element(int tab[], unsigned tab_size, int element);
+unsigned count_tab_criteria(int tab[], unsigned tab_size, c_criteria_cb c_criteria);
+void sort_tab(int tab[], unsigned tab_size, s_criteria_cb sort_criteria);
+
+#endif /* ARRAY_H */
diff --git a/TP_13/exo1/lib/io.c b/TP_13/exo1/lib/io.c
new file mode 100644 (file)
index 0000000..69b13d7
--- /dev/null
@@ -0,0 +1,129 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "io.h"
+#include "array.h"
+
+int prompt_value(const char* msg, int* result) {
+    puts(msg);
+    int retVal = scanf("%d", result);
+    return (retVal == 1) ? 0 : 1;
+}
+
+int* prompt_array(int array[], unsigned* size) {
+    int errno = prompt_value("Taille du tableau?", (int*)size);
+    array = create_tab(array, *size);
+    for (unsigned i = 0; i < *size; i++) {
+       errno += prompt_value("Valeur?", &array[i]);
+    }
+    /* error might have occured */
+    handle_prompt_error(errno);
+    return array;
+}
+
+void display_choice_menu() {
+    printf("\n=== Menu ===\n\n");
+    printf("1) Saisir puis concatener un autre tableau.\n");
+    printf("2) Trier le tableau.\n");
+    printf("3) Afficher le tableau.\n");
+    printf("4) Compter le nombre d'occurence d'un entier dans le tableau.\n");
+    printf("5) Compter le nombre d'entiers pairs dans le tableau.\n");
+    printf("6) Compter le nombre d'entiers impairs dans le tableau.\n");
+    printf("7) Redimensionner le tableau.\n");
+    printf("8) Quitter.\n");
+}
+
+int* do_concat(int array[], unsigned* size) {
+    int* tab_to_concat = NULL;
+    unsigned tab_to_concat_size = 0;
+    printf("\n=== Saisie d'un tableau ===\n\n");
+    tab_to_concat = prompt_array(tab_to_concat, &tab_to_concat_size);
+    int* tab_concat = concat_tab(array, *size, tab_to_concat, tab_to_concat_size);
+    *size += tab_to_concat_size;
+    free_tab(array);
+    free_tab(tab_to_concat);
+    return tab_concat;
+}
+
+void do_sort(int array[], unsigned size) {
+    int errno = 0;
+    int choice = 0;
+    bool done = false;
+    s_criteria_cb sort_criteria;
+
+    printf("\n=== Menu de tri ===\n\n");
+    printf("1) Croissant.\n");
+    printf("2) Decroissant.\n");
+    printf("3) Croissant pairs en premier.\n");
+    printf("4) Croissant impairs en premier.\n");
+    do {
+        errno = prompt_value("Choix?", &choice);
+        handle_prompt_error(errno);
+        done = true;
+        if (1 > choice || 4 < choice) {
+            printf("\nFaire un choix compris entre 1 et 4\n");
+            done = false;
+        }
+    } while (!done);
+    switch (choice) {
+        case 1:
+            sort_criteria = ascending;
+            break;
+        case 2:
+            sort_criteria = descending;
+            break;
+        case 3:
+            sort_criteria = ascending_and_even;
+            break;
+        case 4:
+            sort_criteria = ascending_and_odd;
+            break;
+        default:
+            /* sort ascending by default, unused code path */
+            sort_criteria = ascending;
+            break;
+    }
+    sort_tab(array, size, sort_criteria);
+}
+
+void do_count(int array[], unsigned size) {
+    int errno = 0;
+    int search_value = 0;
+
+    errno = prompt_value("\nValeur a chercher?", &search_value);
+    handle_prompt_error(errno);
+    printf("La valeur %d est presente %d fois dans le tableau\n", search_value, count_tab_element(array, size, search_value));
+}
+
+void do_resize(int array[], unsigned* old_size) {
+    int errno = 0;
+    unsigned new_size = 0;
+
+    errno = prompt_value("\nNouvelle taille?", (int*)&new_size);
+    handle_prompt_error(errno);
+    /* FIXME: one should able the set the array new content if new_size > *old_size 
+     * for now, new values are zeroed */
+    array = resize_tab(array, *old_size, new_size);
+    *old_size = new_size;
+}
+
+void handle_prompt_error(int errno) {
+    if (errno != 0) {
+        printf("\nMerci de saisir un nombre entier, exiting\n");
+        /* it's somewhat violent but better than looping forever */
+        exit(EXIT_FAILURE);
+    }
+}
+
+void display_array(int array[], unsigned size) {
+    if (array != NULL) {
+        printf("\n--array begin--\n");
+        for (unsigned i = 0; i < size; i++) {
+            printf("value in array at index[%d]=%d\n", i, array[i]);
+        }
+        printf("--array end--\n");
+    } else {
+        printf("\n--array NULL--\n");
+    }
+}
diff --git a/TP_13/exo1/lib/io.h b/TP_13/exo1/lib/io.h
new file mode 100644 (file)
index 0000000..6dfc77a
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef IO_H
+#define IO_H
+
+int prompt_value(const char* msg, int* result);
+int* prompt_array(int array[], unsigned* size);
+void handle_prompt_error(int errno);
+
+void display_choice_menu();
+
+int* do_concat(int array[], unsigned* size);
+void do_sort(int array[], unsigned size);
+void do_count(int array[], unsigned size);
+void do_resize(int array[], unsigned* size);
+
+void display_array(int array[], unsigned size);
+
+#endif /* IO_H */
diff --git a/TP_13/exo1/lib/macros.h b/TP_13/exo1/lib/macros.h
new file mode 100644 (file)
index 0000000..3c0ad02
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  macros.h
+ *
+ *    Description:  Some useful macros 
+ *
+ *        Version:  1.0
+ *        Created:  09/03/2017 15:28:46
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
+ *   Organization:  Piment Noir
+ *
+ * =====================================================================================
+ */
+
+#ifndef MACROS_H
+#define MACROS_H
+
+#include <stdlib.h>
+
+/* definition to expand macro then apply to pragma message */
+#define VALUE_TO_STRING(x) #x
+#define VALUE(x) VALUE_TO_STRING(x)
+#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
+
+/* FIXME: ensure we manipulate real array */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
+
+#endif /*  MACROS_H */
diff --git a/TP_13/exo1/lib/sort.c b/TP_13/exo1/lib/sort.c
new file mode 100644 (file)
index 0000000..78625b6
--- /dev/null
@@ -0,0 +1,39 @@
+#include "utils.h"
+#include "sort.h"
+
+bool ascending(int a, int b) {
+    return a > b;
+}
+
+bool descending(int a, int b) {
+    return a < b;
+}
+
+bool ascending_and_even(int a, int b) {
+    return (((a % 2 != 0) && (b % 2 == 0)) || ((a % 2 == 0) && (b % 2 == 0) && ascending(a, b)) \
+                || ((a % 2 != 0) && (b % 2 != 0) && ascending(a, b)));
+}
+
+bool ascending_and_odd(int a, int b) {
+    return (((a % 2 == 0) && (b % 2 != 0)) || ((a % 2 == 0) && (b % 2 == 0) && ascending(a, b)) \
+                || ((a % 2 != 0) && (b % 2 != 0) && ascending(a, b)));
+}
+
+static bool sort_first(int* array, unsigned length, s_criteria_cb sort_criteria) {
+    bool rt = false;
+    for (unsigned i = 0; i < length-1; i++) {
+        if (sort_criteria(array[i], array[i+1])) {
+            swap_int(&array[i], &array[i+1]);
+            rt = true;
+        }
+    }
+    return rt;
+}
+
+/* the feature of this function is awaited in the array.c file */
+void sort_bubble_array(int* array, unsigned length, s_criteria_cb sort_criteria) {
+    bool rt;
+    do {
+        rt = sort_first(array, length, sort_criteria);
+   } while (rt);
+}
diff --git a/TP_13/exo1/lib/sort.h b/TP_13/exo1/lib/sort.h
new file mode 100644 (file)
index 0000000..3c499f7
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef SORT_H
+#define SORT_H
+
+#include <stdbool.h>
+
+typedef bool(*s_criteria_cb)(int a, int b);
+
+/* sort criteria */
+bool ascending(int a, int b);
+bool descending(int a, int b);
+bool ascending_and_even(int a, int b);
+bool ascending_and_odd(int a, int b);
+
+void sort_bubble_array(int* array, unsigned length, s_criteria_cb sort_criteria);
+
+#endif /* SORT_H */
diff --git a/TP_13/exo1/lib/utils.c b/TP_13/exo1/lib/utils.c
new file mode 100644 (file)
index 0000000..1f0b140
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+#include "utils.h"
+
+void swap_int(int* v1, int* v2) {
+    int tmp = *v1;
+    *v1 = *v2;
+    *v2 = tmp;
+}
+
+void swap_ptr(void* v1, void* v2) {
+    void* tmp = v1;
+    v1 = v2;
+    v2 = tmp;
+}
diff --git a/TP_13/exo1/lib/utils.h b/TP_13/exo1/lib/utils.h
new file mode 100644 (file)
index 0000000..03f1226
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#include "macros.h"
+
+void swap_int(int* v1, int* v2);
+void swap_ptr(void* v1, void* v2);
+
+#endif /* UTILS_H */
diff --git a/TP_13/exo1/src/main.c b/TP_13/exo1/src/main.c
new file mode 100644 (file)
index 0000000..ef4d545
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "array.h"
+#include "utils.h"
+#include "io.h"
+
+int main() {
+    int* tab = NULL;
+    unsigned tab_size = 0;
+    int errno = 0;
+    int choice = 0;
+
+    printf("=== Saisie initiale ===\n\n");
+    tab = prompt_array(tab, &tab_size);
+
+    do {
+        display_choice_menu();
+        errno = prompt_value("Choix?", &choice);
+        handle_prompt_error(errno);
+        if (1 > choice || 8 < choice) {
+            printf("\nFaire un choix compris entre 1 et 8\n");
+            continue;
+        }
+        switch (choice) {
+            case 1:
+                tab = do_concat(tab, &tab_size);
+                break;
+            case 2:
+                do_sort(tab, tab_size);
+                break;
+            case 3:
+                display_array(tab, tab_size);
+                break;
+            case 4:
+                do_count(tab, tab_size);
+                break;
+            case 5:
+                printf("\nLe nombre d'entiers pairs dans le tableau est %d\n", count_tab_criteria(tab, tab_size, is_even));
+                break;
+            case 6:
+                printf("\nLe nombre d'entiers impairs dans le tableau est %d\n", count_tab_criteria(tab, tab_size, is_odd));
+                break;
+            case 7:
+                do_resize(tab, &tab_size);
+                break;
+            default:
+                /* do nothing, unused code path */
+                break;
+        }
+    } while (choice != 8);
+
+    free_tab(tab);
+    exit(EXIT_SUCCESS);
+}
diff --git a/TP_13/exo2/Makefile b/TP_13/exo2/Makefile
new file mode 100644 (file)
index 0000000..2fa2084
--- /dev/null
@@ -0,0 +1,150 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# $(SRC_PATH) directory.
+#
+# This Makefile expect all embedded library source files (.c) to be at the same level, in the
+# $(LIBRARY_PATH) directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name linked against the library if necessary.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set LIBRARY_NAME to the name of the library file to build.
+# The default path for the library code and object is lib.
+# By default the linker will look for $(BINARY_NAME) library name.
+# Set BUILD_TYPE to either debug or release.
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo2
+SRC_PATH:=src
+LIBRARY_NAME=libexo2
+LIBRARY_PATH:=lib
+LDLIBS=-lncurses -ltinfo
+BUILD_TYPE=debug
+#BUILD_TYPE=release
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME) $(BINARY_NAME).dynamic $(BINARY_NAME).static
+
+CC=gcc
+LD=gcc
+AR=ar
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+UNAME := $(shell uname -o)
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+LTO_SUPPORT = yes
+GOLD_SUPPORT = yes
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+LTO_SUPPORT = yes
+GOLD_SUPPORT = yes
+endif
+
+ifeq ($(UNAME),Cygwin)
+GOLD_SUPPORT = no
+endif
+
+ifeq ($(LTO_SUPPORT),yes)
+CFLAGS_LTO = -flto -ffat-lto-objects
+LDFLAGS_LTO = -fuse-linker-plugin -flto
+endif
+
+ifeq ($(GOLD_SUPPORT),yes)
+LDFLAGS_GOLD = -fuse-ld=gold
+endif
+
+# Putting header files in the source directory is not the purpose of this INCLUDES variable
+INCLUDES := $(INCLUDES) -I$(LIBRARY_PATH)
+CFLAGS := $(CFLAGS) $(CFLAGS_LTO) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG) $(INCLUDES)
+LIBCFLAGS := -fPIC $(CFLAGS)
+LDFLAGS := $(LDFLAGS) $(LDFLAGS_LTO) $(LDFLAGS_GOLD) $(STRIP_FLAG)
+LIBLDFLAGS := -shared $(LDFLAGS)
+STATICLIBLDFLAGS := -static $(LDFLAGS)
+LDLIBS := $(LDLIBS) -L$(LIBRARY_PATH) -l$(BINARY_NAME)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard $(SRC_PATH)/*.c)
+LIBSRCS=$(wildcard $(LIBRARY_PATH)/*.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SRCS)))
+LIBOBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(LIBSRCS)))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$(notdir $*).Td
+POSTCOMPILE = mv -f $(DEPDIR)/$(notdir $*).Td $(DEPDIR)/$(notdir $*).d
+
+$(LIBRARY_PATH)/$(LIBRARY_NAME).a: $(LIBOBJS)
+       @echo "[AR StO] $@"
+       @$(AR) rcs $@ $^
+
+$(LIBRARY_PATH)/$(LIBRARY_NAME).so: $(LIBOBJS)
+       @echo "[LD ShO] $@"
+       @$(LD) $(LIBCFLAGS) $(LIBLDFLAGS) $^ -o $@
+
+#$(BINARY_NAME): $(OBJS) $(LIBOBJS)
+#      @echo "[LD ] $@"
+#      @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME): $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME).static: $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(STATICLIBLDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BINARY_NAME).dynamic: $(OBJS) $(LIBRARY_PATH)/$(LIBRARY_NAME).so
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: $(SRC_PATH)/%.c $(DEPDIR)/%.d
+       @echo "[C  ] $(notdir $*)"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+$(OBJDIR)/%.o: $(LIBRARY_PATH)/%.c $(DEPDIR)/%.d
+       @echo "[C  ] $(notdir $*)"
+       @$(CC) $(DEPFLAGS) $(LIBCFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(LIBSRCS))))
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+#FIXME: add an install target
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+       -@rm $(BINARY_NAME).static
+       -@rm $(BINARY_NAME).dynamic
+       -@rm $(LIBRARY_PATH)/$(LIBRARY_NAME).a
+       -@rm $(LIBRARY_PATH)/$(LIBRARY_NAME).so
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_13/exo2/README b/TP_13/exo2/README
new file mode 100644 (file)
index 0000000..10090fe
--- /dev/null
@@ -0,0 +1,10 @@
+Tic-tac-toe
+-----------
+
+Touches correspondantes au case de la grille:
+
+a|z|e
+-+-+-
+q|s|d
+-+-+-
+w|x|c
diff --git a/TP_13/exo2/lib/coordinates.c b/TP_13/exo2/lib/coordinates.c
new file mode 100644 (file)
index 0000000..a9d8159
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  coordinates.c
+ *
+ *    Description:  Data definition and functions to manipulate elements in the grid
+ *
+ *        Version:  1.0
+ *        Created:  16/03/2017 19:05:02
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
+ *   Organization:  Piment Noir
+ *
+ * =====================================================================================
+ */
+
+#include "coordinates.h"
+
+void init_coordinates(coordinates_t* coordinates_array) {
+    for (unsigned i = 0; i < MAX_COORDINATES; i++) {
+        coordinates_array[i] = set_coordinates(0, 0, 0);
+    }
+}
+
+coordinates_t set_coordinates(int y, int x, unsigned type) {
+    coordinates_t new_coordinates;
+
+    new_coordinates.y = y;
+    new_coordinates.x = x;
+    new_coordinates.type = type;
+    return new_coordinates;
+}
+
+/* the function do a lot of sanity checks before adding new board elements,
+ * hence the loop. moving the checks in the main loop is also possible */
+unsigned add_coordinates(coordinates_t new_coordinates, coordinates_t* coordinates_array, unsigned round) {
+    /* valid coordinates are in the [1-3] range */
+    if (new_coordinates.y < 1 || new_coordinates.y > 3 || new_coordinates.x < 1 || new_coordinates.x > 3) {
+        return 3; /* error value for invalid coordinates */
+    } else if (round == MAX_COORDINATES + 1) {
+        return 1; /* error value for full array */
+    }
+
+    for (unsigned i = 0; i < MAX_COORDINATES; i++) {
+        /* check if already entered */
+        if (new_coordinates.y == (coordinates_array + i)->y && new_coordinates.x == (coordinates_array + i)->x) {
+            return 2; /* error value for duplicates */
+        } else if ((coordinates_array + i)->y == 0 && (coordinates_array + i)->x == 0) {
+            coordinates_array[i] = new_coordinates;
+            return 0; /* error value when everything if fine */
+        }
+    }
+    return 4; /* error value for unknown error case - should never happen - */
+}
+
+bool chk_win_conditions(coordinates_t* coordinates_array) {
+    for (unsigned i = 0; i < MAX_COORDINATES; i++) {
+
+    }
+    return false;
+}
diff --git a/TP_13/exo2/lib/coordinates.h b/TP_13/exo2/lib/coordinates.h
new file mode 100644 (file)
index 0000000..3a17ade
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  coordinates.h
+ *
+ *    Description:  Header for data definition and functions to manipulate elements in the grid
+ *
+ *        Version:  1.0
+ *        Created:  16/03/2017 19:06:16
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
+ *   Organization:  Piment Noir
+ *
+ * =====================================================================================
+ */
+
+#ifndef COORDINATES_H
+#define COORDINATES_H
+
+#include <stdbool.h>
+
+/* we only have nine elements in the grid */
+#define MAX_COORDINATES 9
+
+typedef struct coordinates_s {
+    int y;
+    int x;
+    unsigned type; /* 0 = O, 1 = X */
+} coordinates_t;
+
+void init_coordinates(coordinates_t* coordinates_array);
+coordinates_t set_coordinates(int y, int x, unsigned type);
+unsigned add_coordinates(coordinates_t new_coordinates, coordinates_t* coordinates_array, unsigned round);
+bool chk_win_conditions(coordinates_t* coordinates_array);
+
+#endif /* COORDINATES_H */
diff --git a/TP_13/exo2/lib/display.c b/TP_13/exo2/lib/display.c
new file mode 100644 (file)
index 0000000..1e5def8
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  display.c
+ *
+ *    Description:  Routines to handle the display 
+ *
+ *        Version:  1.0
+ *        Created:  15/03/2017 20:06:11
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
+ *   Organization:  Piment Noir
+ *
+ * =====================================================================================
+ */
+
+#include <ncurses.h>
+
+#include "display.h"
+
+/* in all print routine, y and x are the coordinates of the first character of the shape
+ * which can be a space ' ' */
+
+void print_board(int y, int x) {
+    mvprintw(y, x, "    |    |");
+    mvprintw(y+1, x, "    |    |");
+    mvprintw(y+2, x, "----+----+----");
+    mvprintw(y+3, x, "    |    |");
+    mvprintw(y+4, x, "    |    |");
+    mvprintw(y+5, x, "----+----+----");
+    mvprintw(y+6, x, "    |    |");
+    mvprintw(y+7, x, "    |    |");
+}
+
+/* there's only nine valid (y, x) 2-uplets for this two shapes 
+ * that are : - base_y, base_x +1
+ *            - base_y, base_x + 6
+ *            - base_y, base_x + 11 
+ *            - base_y + 3, base_x + 1 
+ *            - base_y + 6, base_x + 1 
+ *            - base_y + 3, base_x + 6 
+ *            - base_y + 3, base_x + 11 
+ *            - base_y + 6, base_x + 6 
+ *            - base_y + 6, base_x + 11 
+ * The added (y, x) couple values can be {0, 3, 6}x{1, 6, 11}
+ */
+
+void print_x(int y, int x) {
+    mvprintw(y, x, "\\/");
+    mvprintw(y+1, x,"/\\");
+}
+
+void print_o(int y, int x) {
+    mvprintw(y, x, "/\\");
+    mvprintw(y+1, x, "\\/");
+}
+
+/* y: 1 -> +0  x: 1 -> +1
+ *    2 -> +3     2 -> +6
+ *    3 -> +6     3 -> +11 */
+static int remap_y(int y) {
+    if (y == 1) {
+        return 0;
+    } else if (y == 2) {
+        return 3;
+    } else {
+        return 6;
+    }
+}
+
+static int remap_x(int x) {
+    if (x == 1) {
+        return 1;
+    } else if (x == 2) {
+        return 6;
+    } else {
+        return 11;
+    }
+}
+
+void print_coordinates(coordinates_t coordinates_array[], int base_y, int base_x) {
+    unsigned i = 0;
+    while ((coordinates_array + i)->y != 0 && (coordinates_array + i)->x != 0) {
+        if ((coordinates_array + i)->type == 0) {
+            print_o(base_y + remap_y((coordinates_array + i)->y), base_x + remap_x((coordinates_array + i)->x));
+        } else {
+            print_x(base_y + remap_y((coordinates_array + i)->y), base_x + remap_x((coordinates_array + i)->x));
+        }
+        i++;
+    }
+}
diff --git a/TP_13/exo2/lib/display.h b/TP_13/exo2/lib/display.h
new file mode 100644 (file)
index 0000000..c3390fe
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  display.h
+ *
+ *    Description:  Headers for display routines 
+ *
+ *        Version:  1.0
+ *        Created:  15/03/2017 20:07:12
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
+ *   Organization:  Piment Noir
+ *
+ * =====================================================================================
+ */
+
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#include "coordinates.h"
+
+void print_board(int y, int x);
+void print_x(int y, int x);
+void print_o(int y, int x);
+void print_coordinates(coordinates_t coordinates_array[], int base_y, int base_x);
+
+#endif /* DISPLAY_H */
diff --git a/TP_13/exo2/lib/macros.h b/TP_13/exo2/lib/macros.h
new file mode 100644 (file)
index 0000000..3c0ad02
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  macros.h
+ *
+ *    Description:  Some useful macros 
+ *
+ *        Version:  1.0
+ *        Created:  09/03/2017 15:28:46
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
+ *   Organization:  Piment Noir
+ *
+ * =====================================================================================
+ */
+
+#ifndef MACROS_H
+#define MACROS_H
+
+#include <stdlib.h>
+
+/* definition to expand macro then apply to pragma message */
+#define VALUE_TO_STRING(x) #x
+#define VALUE(x) VALUE_TO_STRING(x)
+#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
+
+/* FIXME: ensure we manipulate real array */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
+
+#endif /*  MACROS_H */
diff --git a/TP_13/exo2/lib/utils.c b/TP_13/exo2/lib/utils.c
new file mode 100644 (file)
index 0000000..04a20e4
--- /dev/null
@@ -0,0 +1,13 @@
+#include "utils.h"
+
+void swap_int(int* v1, int* v2) {
+    int tmp = *v1;
+    *v1 = *v2;
+    *v2 = tmp;
+}
+
+void swap_ptr(void* v1, void* v2) {
+    void* tmp = v1;
+    v1 = v2;
+    v2 = tmp;
+}
diff --git a/TP_13/exo2/lib/utils.h b/TP_13/exo2/lib/utils.h
new file mode 100644 (file)
index 0000000..03f1226
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#include "macros.h"
+
+void swap_int(int* v1, int* v2);
+void swap_ptr(void* v1, void* v2);
+
+#endif /* UTILS_H */
diff --git a/TP_13/exo2/src/main.c b/TP_13/exo2/src/main.c
new file mode 100644 (file)
index 0000000..390bc40
--- /dev/null
@@ -0,0 +1,111 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ncurses.h>
+
+#include "display.h"
+#include "coordinates.h"
+
+int main() {
+    int row, col, errno = 0, round = 0, player = 0, key_pressed;
+    const int str_max_length = 255;
+    char* top_msg = malloc(str_max_length * sizeof(char));
+    char* back_msg = malloc(str_max_length * sizeof(char));
+
+    initscr();
+    getmaxyx(stdscr, row, col);
+    noecho();
+    curs_set(0);
+
+    /* array of the active coordinates in the entered order */
+    coordinates_t coordinates_array[MAX_COORDINATES];
+    init_coordinates(coordinates_array);
+    coordinates_t new_coordinates = {0, 0, 0};
+
+    /* center base coordinates for the board */
+    int base_y = row/2 - 4;
+    int base_x = col/2 - 7;
+
+    print_board(base_y, base_x);
+
+    do {
+        if (errno == 0) round++;
+
+        if (round % 2 == 0) {
+            player = 1;
+            top_msg = "Joueur 2 joue";
+        } else {
+            player = 0;
+            top_msg = "Joueur 1 joue";
+        }
+
+        mvprintw(base_y - 2, (base_x + 7 - strlen(top_msg)/2), top_msg);
+
+        print_coordinates(coordinates_array, base_y, base_x);
+
+        /* getch() is blocking */
+        key_pressed = getch();
+        switch (key_pressed) {
+            case 'a':
+                new_coordinates = set_coordinates(1, 1, player);
+                break;
+            case 'z':
+                new_coordinates = set_coordinates(1, 2, player);
+                break;
+            case 'e':
+                new_coordinates = set_coordinates(1, 3, player);
+                break;
+            case 'q':
+                new_coordinates = set_coordinates(2, 1, player);
+                break;
+            case 's':
+                new_coordinates = set_coordinates(2, 2, player);
+                break;
+            case 'd':
+                new_coordinates = set_coordinates(2, 3, player);
+                break;
+            case 'w':
+                new_coordinates = set_coordinates(3, 1, player);
+                break;
+            case 'x':
+                new_coordinates = set_coordinates(3, 2, player);
+                break;
+            case 'c':
+                new_coordinates = set_coordinates(3, 3, player);
+                break;
+            default:
+                /* set invalid coordinates */
+                new_coordinates = set_coordinates(0, 0, player);
+                break;
+        }
+
+        errno = add_coordinates(new_coordinates, coordinates_array, round);
+
+        if (errno == 2) {
+            back_msg = "Choisir une case vide";
+        } else if (errno == 3) {
+            back_msg = "Coordonnees invalides";
+        } else if (errno == 1) {
+            back_msg = "Tableau rempli sans gagnant: egalite";
+        } else if (errno == 4) {
+            back_msg = "Erreur inconnue";
+        } else if (errno == 0) {
+            /* FIXME: properly zero the string */
+            back_msg = "";
+        }
+
+        mvprintw(base_y + 10, (base_x + 7 - strlen(back_msg)/2), back_msg);
+
+        refresh();
+
+    } while (errno != 1);
+
+    if (!top_msg)
+        free(top_msg);
+    if (!back_msg)
+        free(back_msg);
+
+    endwin();
+
+    exit(EXIT_SUCCESS);
+}
diff --git a/TP_7/exo1/Makefile b/TP_7/exo1/Makefile
new file mode 100644 (file)
index 0000000..b24c120
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo1
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall
+LDFLAGS = -g -Wall
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_7/exo1/exo1.c b/TP_7/exo1/exo1.c
new file mode 100644 (file)
index 0000000..6509b06
--- /dev/null
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+//FIXME: Comment the code !!!
+
+void promptValue(int* addr) {
+    scanf("%d", addr);
+}
+
+// The efficiency of this swap alternative is debatable ..
+void xorSwap (int *v1, int *v2) {
+    if (v1 != v2) {
+        *v1 ^= *v2;
+        *v2 ^= *v1;
+        *v1 ^= *v2;
+    }
+}
+
+void swap(int* v1, int* v2) {
+    int tmp = *v1;
+    *v1 = *v2;
+    *v2 = tmp;
+}
+
+void displayArray(int* array, int count) {
+    for (int i = 0; i < count; i++) {
+        printf("Value in array at index[%d]= %d\n", i, array[i]);
+    }
+}
+
+bool sortFirst(int* array, int length) {
+    bool rt = false;
+    // This loop could probably be replaced by a while loop with conditions
+    // on the array values permutation AND the iteration value, later ...
+    for (int i = 0; i < length-1; i++) {
+        if (array[i] > array[i+1]) {
+            swap(&array[i], &array[i+1]);
+            //xorSwap(&array[i], &array[i+1]);
+            if (!rt) { rt = true; };
+        }
+    }
+    return rt;
+}
+
+void sortArray(int* array, int length) {
+    bool rt; 
+    do {
+        rt = sortFirst(array, length);
+    } while (rt);
+}
+
+int main() {
+    int tab_length = 10;
+    int tab[tab_length];
+    for (int i = 0; i < tab_length; i++) {
+        tab[i] = 0;
+    }
+   
+    for (int i = 0; i < tab_length; i++) {
+        printf("Enter integer value at array's index[%d]? ", i);
+        /* En langage C, une ligne doit être terminée par le caractère '\n'. Tant que       */
+        /* la ligne n'est pas terminée et que le tampon associé au fichier n'est pas plein, */
+        /* les caractères transmis ne seront pas effectivement écrits mais tout simplement  */
+        /* placés dans le tampon. On peut cependant forcer le vidage de ce tampon à l'aide  */
+        /* de la fonction fflush.                                                           */
+        fflush(stdout);
+        promptValue(&tab[i]);
+    }
+
+    printf("\nView array content unsorted:\n");
+    displayArray(tab, tab_length);
+    printf("\nNow, sorting the array...\n");
+    sortArray(tab, tab_length);
+    printf("\nView array content sorted:\n");
+    displayArray(tab, tab_length);
+
+    return 0;
+}
diff --git a/TP_7/exo2/Makefile b/TP_7/exo2/Makefile
new file mode 100644 (file)
index 0000000..184cdd5
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo2
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall
+LDFLAGS = -g -Wall
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_7/exo2/exo2.c b/TP_7/exo2/exo2.c
new file mode 100644 (file)
index 0000000..7a97f69
--- /dev/null
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+//FIXME: Comment the code !!!
+
+void displayMenuEntry(int num, const char* option) {
+    printf("%d - %s\n", num, option);
+}
+
+void displayMenu() {
+    displayMenuEntry(1, "Addition");
+    displayMenuEntry(2, "Soustraction");
+    displayMenuEntry(3, "Multiplication");
+    displayMenuEntry(4, "Division");
+    displayMenuEntry(5, "Puissance");
+    displayMenuEntry(6, "Quitter");
+}
+
+int promptValue(const char* invite) {
+    int value = 0;
+    puts(invite);    
+    scanf("%d", &value);
+    return value;
+}
+
+int promptOperation() {
+    displayMenu();
+    return promptValue("Veuillez choisir une operation ?");
+}
+
+int doAddition(int val1, int val2) {
+    return val1 + val2;
+}
+
+int doSubstraction(int val1, int val2) {
+    return val1 - val2; 
+}
+
+int doMultiplication(int val1, int val2) {
+    return val1 * val2;
+}
+
+int doDivision(int val1, int val2) {
+    //FIXME: Useless code path given the exit main loop condition
+    if (val2 == 0) {
+        printf("Division par zero !\n");
+        // FIXME: I'm not very fond of this convention ...
+        return 0;
+    } else {
+        return val1 / val2;
+    }
+}
+
+int doPuissance(int base, int expo) {
+    int power;
+    if ( expo == 1) {
+        power = base;               
+    } else if ( expo % 2 == 0 ) {
+        power = doPuissance(base*base, expo/2);    
+    } else {
+        power = base*doPuissance(base*base,(expo-1)/2);
+    }
+    return power;
+}
+
+int doOperation(int selection, int val1, int val2) {
+    int op_result;
+    switch (selection) {
+        case 1:
+            op_result = doAddition(val1, val2);
+            break;
+        case 2:
+            op_result = doSubstraction(val1, val2);
+            break;
+        case 3:
+            op_result = doMultiplication(val1, val2);
+            break;
+        case 4:
+            op_result = doDivision(val1, val2);
+            break;
+        case 5:
+            op_result = doPuissance(val1, val2);
+            break;
+        case 6:
+            break;
+        default:
+            puts("Faire un choix compris entre 1 et 6");
+    }       
+    return op_result;
+}
+
+int main() {
+    int choice = promptOperation();
+    int value1 = promptValue("Veuillez saisir une valeur entiere initiale ?");
+    int value2 = 0, result = 0; 
+    bool first_loop = true;
+    
+    for (;;) {
+        if (choice == 6) break;
+        if (first_loop) {
+            value2 = promptValue("Veuillez saisir une valeur entiere avec laquelle l'operation sera effectuee ?");
+            if (value2 == 0) break;
+            result = doOperation(choice, value1, value2);
+            first_loop = false;
+        } else {
+            value2 = promptValue("Veuillez saisir la prochaine valeur entiere avec laquelle l'operation sera effectuee sur l'ancien resultat ?");
+            if (value2 == 0) break;
+            result = doOperation(choice, result, value2); 
+        }
+        printf("Le resultat de l'operation choisie est %d\n\n", result);
+    }
+
+    return 0;
+}
diff --git a/TP_7/exo3/Makefile b/TP_7/exo3/Makefile
new file mode 100644 (file)
index 0000000..c31747a
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo3
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall
+LDFLAGS = -g -Wall
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_7/exo3/exo3.c b/TP_7/exo3/exo3.c
new file mode 100644 (file)
index 0000000..03d6390
--- /dev/null
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <ctype.h>
+
+//FIXME: Comment the code !!!
+
+void swap(char* v1, char* v2) {
+    if (v1 != v2) {
+        char tmp = *v1;
+        *v1 = *v2;
+        *v2 = tmp;
+    }
+}
+
+int stringLength(const char* str) {
+    int length;
+
+    for(length = 0; str[length] != '\0'; ++length);
+    return length;
+}
+
+// FIXME: this function have issues with non english characters
+void reverseString(char* str) {
+    int length = stringLength(str);
+
+    for (int i = length - 1; i >= length/2; --i) {
+        swap(&str[i], &str[(length - 1) - i]);
+    }
+}
+
+// FIXME: this function have issues with non english characters
+void permAlphaChar(char* str, int key) {
+    char alphabet[26] = "abcdefghijklmnopqrstuvwxyz";
+    int str_length = stringLength(str);
+
+    for (int i = 0; i < str_length; i++) { 
+        //if (str[i] == ' ') continue;
+        for (int j = 0; j < 26; j++) {
+            if (str[i] == alphabet[j]) {
+                str[i] = alphabet[(j+key) % 26];
+                break;
+             } else if (str[i] == toupper(alphabet[j])) {
+                str[i] = toupper(alphabet[(j+key) % 26]);
+                break;
+            }
+        }
+    }
+}
+
+int main() {
+    char rev_msg[] = "Bonjour le monde";
+    int rev_length = stringLength(rev_msg); 
+    char perm_msg[] = "Bonjour a tous et toutes";
+    int perm_length = stringLength(perm_msg); 
+
+    printf("La chaine de caracteres a inverser est \"%s\" et a pour longueur %d caractere(s)\n", rev_msg, rev_length);
+    reverseString(rev_msg);
+    printf("La chaine inversee de caracteres est \"%s\"\n", rev_msg);
+
+    printf("\n");
+   
+    printf("La chaine de caracteres a permuter est \"%s\" et a pour longueur %d caractere(s)\n", perm_msg, perm_length);
+    permAlphaChar(perm_msg, 13);
+    printf("La chaine permutee de caracteres est \"%s\"\n", perm_msg);
+
+    return 0;
+}
diff --git a/TP_7_C/Makefile b/TP_7_C/Makefile
new file mode 100644 (file)
index 0000000..d2c843b
--- /dev/null
@@ -0,0 +1,27 @@
+all: \
+       exo1-base \
+       exo1-full \
+       exo1-extra \
+       exo2-base \
+       exo2-full \
+       exo2-extra \
+       exo3-base \
+       exo3-full \
+       exo3-extra \
+
+
+%:%.c
+       gcc $< -std=c99 -Wall -g -o $@
+
+clean:
+       @rm -f \
+       exo1-base \
+        exo1-full \
+        exo1-extra \
+        exo2-base \
+        exo2-full \
+        exo2-extra \
+        exo3-base \
+        exo3-full \
+        exo3-extra \
+       
diff --git a/TP_7_C/README b/TP_7_C/README
new file mode 100644 (file)
index 0000000..e452c5b
--- /dev/null
@@ -0,0 +1,9 @@
+Correction du TP noté de C
+
+Pour compiler, utiliser make directement:
+
+$ make
+
+Les fichiers -base contiennent l'exercice de base, les fichiers -full contiennent les points optionels.
+
+Les fichiers -extra contiennent une version alternative. Cette version n'est pas nécessairement plus efficace (voir elle est parfois moins efficace!) et n'est pas non plus aussi lisible; de manière générale les "astuces" utilisées ne sont pas conseillées quand elles réduisent la lisibilité sans apporter d'avantage réel.
diff --git a/TP_7_C/exo1-base.c b/TP_7_C/exo1-base.c
new file mode 100644 (file)
index 0000000..a30362c
--- /dev/null
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+void swap(int* v1, int* v2) {
+    int tempValue = *v1;
+    *v1 = *v2;
+    *v2 = tempValue;
+}
+
+/** Display the array on standard output. */
+void displayArray(int* array, int count) {
+    for (int tabIndex = 0; tabIndex < count; ++tabIndex) {
+        printf("array[%d] = %d\n", tabIndex, array[tabIndex]);
+    }
+}
+
+/** Perform one swap on the first two values not in increasing order.
+ *
+ * @return true if a swap was performed, false if the whole array is ordered.
+ */
+bool sortFirst(int* array, int length) {
+    for (int tabIndex = 0; tabIndex < (length - 1); ++tabIndex) {
+        if (array[tabIndex] > array[tabIndex + 1]) {
+            swap(&array[tabIndex], &array[tabIndex + 1]);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void sortArray(int* array, int length) {
+    bool swappedValues;
+
+    do {
+        swappedValues = sortFirst(array, length);
+    } while (swappedValues);
+}
+
+int main() {
+    int arr[10] = {23, 2, 0, 4, 56, 3, 7, 8, 98, 1};
+    sortArray(arr, 10);
+    displayArray(arr, 10);
+}
diff --git a/TP_7_C/exo1-extra.c b/TP_7_C/exo1-extra.c
new file mode 100644 (file)
index 0000000..3d191f0
--- /dev/null
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+void swap(int* v1, int* v2) {
+    int tempValue = *v1;
+    *v1 = *v2;
+    *v2 = tempValue;
+}
+
+/** Display the array on standard output. */
+void displayArray(int* array, int count) {
+    for (int tabIndex = 0; tabIndex < count; ++tabIndex) {
+        printf("array[%d] = %d\n", tabIndex, *(array++));
+    }
+}
+
+/** Swap every out-of-order cells at most once.
+ *
+ * @return true if a swap was performed, false if the whole array is ordered.
+ */
+bool sortFirst(int* array, int length) {
+    bool swappedValues = false;
+    int* cursor = array;
+
+    while (--length) {
+        if (*cursor > *(cursor + 1)) {
+            swap(cursor, cursor + 1);
+            swappedValues = true;
+        }
+
+        ++cursor;
+    }
+
+    return swappedValues;
+}
+
+void sortArray(int* array, int length) {
+    while (sortFirst(array, length));
+}
+
+/** Fill the array with user input. */
+void promptArray(int* array, int length) {
+    for (int tabIndex = 0; tabIndex < length; ++tabIndex) {
+        printf("Enter value for index %d:\n", tabIndex);
+        scanf("%d", array++);
+    }
+}
+
+int main() {
+    int arr[10];
+    promptArray(arr, 10);
+    sortArray(arr, 10);
+    displayArray(arr, 10);
+}
diff --git a/TP_7_C/exo1-full.c b/TP_7_C/exo1-full.c
new file mode 100644 (file)
index 0000000..451816b
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+void swap(int* v1, int* v2) {
+    int tempValue = *v1;
+    *v1 = *v2;
+    *v2 = tempValue;
+}
+
+/** Display the array on standard output. */
+void displayArray(int* array, int count) {
+    for (int tabIndex = 0; tabIndex < count; ++tabIndex) {
+        printf("array[%d] = %d\n", tabIndex, array[tabIndex]);
+    }
+}
+
+/** Swap every out-of-order cells at most once.
+ *
+ * @return true if a swap was performed, false if the whole array is ordered.
+ */
+bool sortFirst(int* array, int length) {
+    bool swappedValues = false;
+
+    for (int tabIndex = 0; tabIndex < (length - 1); ++tabIndex) {
+        if (array[tabIndex] > array[tabIndex + 1]) {
+            swap(&array[tabIndex], &array[tabIndex + 1]);
+            swappedValues = true;
+        }
+    }
+
+    return swappedValues;
+}
+
+void sortArray(int* array, int length) {
+    bool swappedValues;
+
+    do {
+        swappedValues = sortFirst(array, length);
+    } while (swappedValues);
+}
+
+/** Fill the array with user input. */
+void promptArray(int* array, int length) {
+    for (int tabIndex = 0; tabIndex < length; ++tabIndex) {
+        printf("Enter value for index %d:\n", tabIndex);
+        scanf("%d", &array[tabIndex]);
+    }
+}
+
+int main() {
+    int arr[10];
+    promptArray(arr, 10);
+    sortArray(arr, 10);
+    displayArray(arr, 10);
+}
diff --git a/TP_7_C/exo2-base.c b/TP_7_C/exo2-base.c
new file mode 100644 (file)
index 0000000..7212cfc
--- /dev/null
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+/** Display a prompt to the user then wait for an integer input. */
+int promptValue(const char* prompt) {
+    printf("%s:\n", prompt);
+    int result;
+    scanf("%d", &result);
+    return result;
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+void displayMenu() {
+    displayMenuEntry(1, "Addition");
+    displayMenuEntry(2, "Substraction");
+    displayMenuEntry(3, "Multiplication");
+    displayMenuEntry(4, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. No invalid value can be returned.
+ */
+int promptOperation() {
+    displayMenu();
+    int result;
+
+    do {
+        result = promptValue("Choose an option");
+
+        if (result >= 1 && result <= 4) {
+            break;
+        }
+
+        puts("Please choose a valid option (1-4)");
+    } while (true);
+
+    return result;
+}
+
+int main() {
+    int operation = promptOperation();
+
+    if (operation == 4) {
+        return 0;
+    }
+
+    int initialValue = promptValue("Initial value");
+
+    do {
+        int nextValue = promptValue("Next value");
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        switch (operation) {
+        // Addition
+        case 1:
+            initialValue += nextValue;
+            break;
+
+        // Substraction
+        case 2:
+            initialValue -= nextValue;
+            break;
+
+        // Multiplication
+        case 3:
+            initialValue *= nextValue;
+            break;
+        }
+
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}
diff --git a/TP_7_C/exo2-extra.c b/TP_7_C/exo2-extra.c
new file mode 100644 (file)
index 0000000..2250cfd
--- /dev/null
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/** Pointer to a function with this profile */
+typedef int(*operation_cb)(int v1, int v2);
+
+/** Describe a single operation */
+typedef struct {
+    const char* label;
+    operation_cb cb;
+} operation_t;
+
+int doAddition(int v1, int v2);
+int doSubstraction(int v1, int v2);
+int doMultiplication(int v1, int v2);
+int doXOR(int v1, int v2);
+
+/** All available operations */
+operation_t operations[4] = {
+    {
+        "Addition",
+        doAddition
+    },
+    {
+        "Substraction",
+        doSubstraction
+    },
+    {
+        "Multiplication",
+        doMultiplication
+    },
+    {
+        "XOR",
+        doXOR
+    }
+};
+#define operations_count ((int) (sizeof(operations) / sizeof(operations[0])))
+
+/** Display a prompt to the user then wait for an integer input. */
+void promptValue(const char* prompt, int* value) {
+    printf("%s:\n", prompt);
+    scanf("%d", value);
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+/** Display all available operations and an EXIT option. */
+void displayMenu() {
+    for (int menuIndex = 0; menuIndex < operations_count; ++menuIndex) {
+        displayMenuEntry(menuIndex + 1, operations[menuIndex].label);
+    }
+
+    displayMenuEntry(operations_count + 1, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. If the exit option is chosen, return NULL
+ */
+operation_t* promptOperation() {
+    displayMenu();
+
+    do {
+        int result;
+        promptValue("Choose an option", &result);
+
+        if (result == (operations_count + 1)) {
+            return NULL;
+        }
+
+        if (result >= 1 && result <= operations_count) {
+            return &operations[result - 1];
+        }
+
+        printf("Please choose a valid option (1-%d)\n", operations_count);
+    } while (true);
+}
+
+int doAddition(int v1, int v2) {
+    return v1 + v2;
+}
+
+int doSubstraction(int v1, int v2) {
+    return v1 - v2;
+}
+
+int doMultiplication(int v1, int v2) {
+    return v1 * v2;
+}
+
+int doXOR(int v1, int v2) {
+    return v1 ^ v2;
+}
+
+int main() {
+    operation_t* operation = promptOperation();
+
+    if (operation == NULL) {
+        return 0;
+    }
+
+    int initialValue;
+    promptValue("Initial value", &initialValue);
+
+    do {
+        int nextValue;
+        promptValue("Next value", &nextValue);
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        initialValue = operation->cb(initialValue, nextValue);
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}
diff --git a/TP_7_C/exo2-full.c b/TP_7_C/exo2-full.c
new file mode 100644 (file)
index 0000000..acbe4a3
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+/** Display a prompt to the user then wait for an integer input. */
+int promptValue(const char* prompt) {
+    printf("%s:\n", prompt);
+    int result;
+    scanf("%d", &result);
+    return result;
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+void displayMenu() {
+    displayMenuEntry(1, "Addition");
+    displayMenuEntry(2, "Substraction");
+    displayMenuEntry(3, "Multiplication");
+    displayMenuEntry(4, "XOR");
+    displayMenuEntry(5, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. No invalid value can be returned.
+ */
+int promptOperation() {
+    displayMenu();
+    int result;
+
+    do {
+        result = promptValue("Choose an option");
+
+        if (result >= 1 && result <= 5) {
+            break;
+        }
+
+        puts("Please choose a valid option (1-5)");
+    } while (true);
+
+    return result;
+}
+
+int main() {
+    int operation = promptOperation();
+
+    if (operation == 5) {
+        return 0;
+    }
+
+    int initialValue = promptValue("Initial value");
+
+    do {
+        int nextValue = promptValue("Next value");
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        switch (operation) {
+        // Addition
+        case 1:
+            initialValue += nextValue;
+            break;
+
+        // Substraction
+        case 2:
+            initialValue -= nextValue;
+            break;
+
+        // Multiplication
+        case 3:
+            initialValue *= nextValue;
+            break;
+
+        // XOR
+        case 4:
+            initialValue ^= nextValue;
+            break;
+        }
+
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}
diff --git a/TP_7_C/exo3-base.c b/TP_7_C/exo3-base.c
new file mode 100644 (file)
index 0000000..c50753c
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int stringLength(const char* str) {
+    int result = 0;
+
+    while (str[result] != '\0') {
+        ++result;
+    }
+
+    return result;
+}
+
+void swap(char* v1, char* v2) {
+    char temp = *v1;
+    *v1 = *v2;
+    *v2 = temp;
+}
+
+void reverseString(char* str) {
+    int length = stringLength(str);
+    int halfLength = length / 2;
+
+    for (int charId = 0; charId < halfLength; ++charId) {
+        swap(&str[charId], &str[length - charId - 1]);
+    }
+}
+
+int main() {
+    char msg[] = "Votre message";
+    printf("Initial value: \"%s\"\n", msg);
+    reverseString(msg);
+    printf("Reversed     : \"%s\"\n", msg);
+}
diff --git a/TP_7_C/exo3-extra.c b/TP_7_C/exo3-extra.c
new file mode 100644 (file)
index 0000000..36fdb64
--- /dev/null
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int stringLength(const char* str) {
+    int result = 0;
+
+    for (; str[result]; ++result);
+
+    return result;
+}
+
+void swap(char* v1, char* v2) {
+    char temp = *v1;
+    *v1 = *v2;
+    *v2 = temp;
+}
+
+void reverseString(char* str) {
+    char* begin = str;
+    char* end = str + stringLength(str) - 1;
+
+    while (begin < end) {
+        swap(begin++, end--);
+    }
+}
+
+/** Perform a classical ROT13 permutation in-place */
+void rot13(char* str) {
+    char* cursor = str;
+    char* end = str + stringLength(str);
+
+    while (cursor < end) {
+        if (*cursor >= 'a' && *cursor <= 'z') {
+            *cursor = (*cursor - 'a' + 13) % 26 + 'a';
+        } else if (*cursor >= 'A' && *cursor <= 'Z') {
+            *cursor = (*cursor - 'A' + 13) % 26 + 'A';
+        }
+
+        ++cursor;
+    }
+}
+
+int main() {
+    char* msg;
+    puts("Enter your message:");
+    int readValue = scanf("%ms", &msg);
+
+    if (readValue == 0) {
+        puts("oops");
+        return 0;
+    }
+
+    printf("Initial value: \"%s\"\n", msg);
+    reverseString(msg);
+    printf("Reversed     : \"%s\"\n", msg);
+    reverseString(msg); // Restore the original message
+    rot13(msg);
+    printf("ROT13        : \"%s\"\n", msg);
+    free(msg); // scanf("%ms") allocate dynamic memory
+}
diff --git a/TP_7_C/exo3-full.c b/TP_7_C/exo3-full.c
new file mode 100644 (file)
index 0000000..4f6eca0
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+
+int stringLength(const char* str) {
+    int result = 0;
+
+    while (str[result] != '\0') {
+        ++result;
+    }
+
+    return result;
+}
+
+void swap(char* v1, char* v2) {
+    char temp = *v1;
+    *v1 = *v2;
+    *v2 = temp;
+}
+
+void reverseString(char* str) {
+    int length = stringLength(str);
+    int halfLength = length / 2;
+
+    for (int charId = 0; charId < halfLength; ++charId) {
+        swap(&str[charId], &str[length - charId - 1]);
+    }
+}
+
+/** Perform a classical ROT13 permutation in-place */
+void rot13(char* str) {
+    int length = stringLength(str);
+
+    for (int charId = 0; charId < length; ++charId) {
+        char chrValue = str[charId];
+
+        if (chrValue >= 'a' && chrValue <= 'z') {
+            str[charId] =
+                (chrValue - 'a' // Translate chrValue from 'a'-'z' to 0-25
+                 + 13) // Add 13
+                % 26 // Rotate in 0-25
+                + 'a'; // Translate the value from 0-25 to 'a'-'z'
+        } else if (chrValue >= 'A' && chrValue <= 'Z') {
+            str[charId] = (chrValue - 'A' + 13) % 26 + 'A';
+        }
+    }
+}
+
+int main() {
+    char msg[] = "Votre message";
+    printf("Initial value: \"%s\"\n", msg);
+    reverseString(msg);
+    printf("Reversed     : \"%s\"\n", msg);
+    reverseString(msg); // Restore the original message
+    rot13(msg);
+    printf("ROT13        : \"%s\"\n", msg);
+}
diff --git a/TP_8/exo1/Makefile b/TP_8/exo1/Makefile
new file mode 100644 (file)
index 0000000..4db03fb
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo1
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall -Wextra
+LDFLAGS = -g -Wall -Wextra
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_8/exo1/exo1.c b/TP_8/exo1/exo1.c
new file mode 100644 (file)
index 0000000..c810c05
--- /dev/null
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int promptValue() {
+    int value;
+    scanf("%d", &value);
+    return value;
+}
+
+int main() {
+    int* arr;
+    printf("Longeur?\n");
+    int size = promptValue();
+    //arr[size];
+    //arr = malloc(sizeof(arr));
+    arr = malloc(sizeof(int)*size);
+    
+    for (int i = 0; i < size; i++) {
+        printf("Valeur?\n");
+        arr[i] = promptValue();            
+    }
+
+    printf("Sortie:\n");
+    int sum = 0;
+    for (int i = 0; i < size; i++) {
+         printf("%d (%d)\n", arr[i], sum += arr[i]); 
+    }
+
+    free(arr);
+
+    return 0;
+}
diff --git a/TP_8/exo2/Makefile b/TP_8/exo2/Makefile
new file mode 100644 (file)
index 0000000..20b3d81
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo2
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall -Wextra
+LDFLAGS = -g -Wall -Wextra
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_8/exo2/exo2.c b/TP_8/exo2/exo2.c
new file mode 100644 (file)
index 0000000..ba0dfd2
--- /dev/null
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Display a prompt to the user then wait for an integer input. */
+int promptValue(const char* prompt) {
+    printf("%s:\n", prompt);
+    int result;
+    scanf("%d", &result);
+    return result;
+}
+
+/** Linked list of int */
+typedef struct link_s {
+    int value;
+    struct link_s* next;
+} link_t;
+
+link_t* list_new(int value) {
+    link_t* link_t_new;        
+    link_t_new = malloc(sizeof(link_t));
+    link_t_new->value = value;
+    link_t_new->next = NULL;
+    return link_t_new;
+}
+
+void list_clear(link_t* link) {
+    free(link);
+}
+
+int main() {
+    link_t* head;
+    int value = promptValue("Entrer l'entier a mettre dans un maillon");
+    head = list_new(value);
+    printf("Valeur entiere dans le maillon: %d\n", head->value);
+    list_clear(head);
+
+    return 0;
+}
diff --git a/TP_8/exo3/Makefile b/TP_8/exo3/Makefile
new file mode 100644 (file)
index 0000000..fc320df
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo3
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall -Wextra
+LDFLAGS = -g -Wall -Wextra
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_8/exo3/exo3.c b/TP_8/exo3/exo3.c
new file mode 100644 (file)
index 0000000..6f9cb34
--- /dev/null
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Display a prompt to the user then wait for an integer input. */
+int promptValue(const char* prompt) {
+    printf("%s:\n", prompt);
+    int result;
+    scanf("%d", &result);
+    return result;
+}
+
+/** Linked list of int */
+typedef struct link_s {
+    int value;
+    struct link_s* next;
+} link_t;
+
+link_t* list_new(int value) {
+    link_t* link_t_new;        
+    link_t_new = malloc(sizeof(link_t));
+    link_t_new->value = value;
+    link_t_new->next = NULL;
+    return link_t_new;
+}
+
+void list_append(link_t* head, int value) {
+       
+    while (head->next != NULL) {
+       head = head->next; 
+    }
+    head->next = list_new(value);
+}
+
+unsigned list_count(link_t* head) {
+    // And if head is not defined? 
+    int count = 1;
+
+    while (head->next != NULL) {
+        ++count;
+        head = head->next;
+    } 
+    return count;
+}
+
+int list_get(link_t* head, unsigned index) {
+    
+    if (index < list_count(head)) {
+        for (unsigned i = 0; i < index; i++) {
+            head = head->next; 
+        }
+        return head->value;
+    } else { 
+        return -1;
+    }
+}
+
+void list_clear(link_t* link) {
+
+    while (link != NULL) {
+        link_t* next_link = link->next;
+        free(link);
+        link = next_link;
+    }
+}
+
+int main() {
+    link_t* head = list_new(1);
+    printf("Longueur de la liste: %d\n", list_count(head));
+    list_append(head, 2);
+    list_append(head, 3);
+    list_append(head, 4);
+    printf("Longueur de la liste: %d\n", list_count(head));
+    printf("Valeur a index %d: %d\n", 2, list_get(head, 2));
+    printf("Valeur a index %d: %d\n", 3, list_get(head, 3));
+    printf("Valeur a index %d: %d\n", 4, list_get(head, 4));
+    list_clear(head);
+
+    return 0;
+}
diff --git a/TP_9/exo1/Makefile b/TP_9/exo1/Makefile
new file mode 100644 (file)
index 0000000..4db03fb
--- /dev/null
@@ -0,0 +1,31 @@
+TARGET = exo1
+LIBS =
+CC = gcc
+# Enforce C11 ISO standard for now
+CFLAGS = -std=c11 -g -Wall -Wextra
+LDFLAGS = -g -Wall -Wextra
+
+.PHONY: default all clean
+
+default: $(TARGET)
+all: default
+
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
+HEADERS = $(wildcard *.h)
+
+%.o: %.c $(HEADERS)
+       $(CC) $(CFLAGS) -c $< -o $@
+
+.PRECIOUS: $(TARGET) $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+       $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+       -rm -f $(TARGET) $(OBJECTS) 
+
+disassemble: $(TARGET)
+       objdump -d $< | less
+
+symbols: $(TARGET)
+       objdump -t $< | sort | less
diff --git a/TP_9/exo1/clist.c b/TP_9/exo1/clist.c
new file mode 100644 (file)
index 0000000..87f97a7
--- /dev/null
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+
+#include "clist.h"
+
+link_t* list_new(int value) {
+    link_t* link_t_new;        
+    link_t_new = malloc(sizeof(link_t));
+    link_t_new->value = value;
+    link_t_new->next = NULL;
+    return link_t_new;
+}
+
+void list_append(link_t* head, int value) {
+       
+    while (head->next != NULL) {
+       head = head->next; 
+    }
+    head->next = list_new(value);
+}
+
+unsigned list_count(link_t* head) {
+    // And if head is not defined? 
+    int count = 1;
+
+    while (head->next != NULL) {
+        ++count;
+        head = head->next;
+    } 
+    return count;
+}
+
+int list_get(link_t* head, unsigned index) {
+    
+    if (index < list_count(head)) {
+        for (unsigned i = 0; i < index; i++) {
+            head = head->next; 
+        }
+        return head->value;
+    } else { 
+        return -1;
+    }
+}
+
+void list_clear(link_t* link) {
+
+    while (link != NULL) {
+        link_t* next_link = link->next;
+        free(link);
+        link = next_link;
+    }
+}
diff --git a/TP_9/exo1/clist.h b/TP_9/exo1/clist.h
new file mode 100644 (file)
index 0000000..02a59be
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef CLIST_H
+#define CLIST_H
+
+/** Linked list of int */
+typedef struct link_s {
+    int value;
+    struct link_s* next;
+} link_t;
+
+link_t* list_new(int value); 
+void list_append(link_t* head, int value); 
+unsigned list_count(link_t* head);
+int list_get(link_t* head, unsigned index);
+void list_clear(link_t* link);
+
+#endif /* CLIST_H */
diff --git a/TP_9/exo1/exo1.c b/TP_9/exo1/exo1.c
new file mode 100644 (file)
index 0000000..e70d29b
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+#include "clist.h"
+
+int main() {
+    link_t* head = list_new(1);
+    printf("Longueur de la liste: %d\n", list_count(head));
+    list_append(head, 2);
+    list_append(head, 3);
+    list_append(head, 4);
+    printf("Longueur de la liste: %d\n", list_count(head));
+    printf("Valeur a index %d: %d\n", 2, list_get(head, 2));
+    printf("Valeur a index %d: %d\n", 3, list_get(head, 3));
+    printf("Valeur a index %d: %d\n", 4, list_get(head, 4));
+    list_clear(head);
+
+    return 0;
+}
diff --git a/TP_9/exo2/Makefile b/TP_9/exo2/Makefile
new file mode 100644 (file)
index 0000000..d4b8fdb
--- /dev/null
@@ -0,0 +1,79 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo2
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME)
+
+CC=gcc
+LD=gcc
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c99
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/TP_9/exo2/clist.c b/TP_9/exo2/clist.c
new file mode 100644 (file)
index 0000000..2fd3dfd
--- /dev/null
@@ -0,0 +1,216 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "clist.h"
+
+link_t* list_new(int value) {
+    link_t* link_new;
+    link_new = malloc(sizeof(link_t));
+    link_new->value = value;
+    link_new->next = NULL;
+    return link_new;
+}
+
+link_t* list_append(link_t* head, int value) {
+
+    if (head == NULL) {
+        return head = list_new(value);
+    } else {
+        link_t* head_first = head;
+        while (head->next != NULL) {
+            head = head->next;
+        }
+        head->next = list_new(value);
+        return head_first;
+    }
+}
+
+link_t* list_prepend(link_t* head, int value) {
+    link_t* first_link = list_new(value);
+
+    first_link->next = head;
+    return first_link;
+}
+
+link_t* list_insert(link_t* head, unsigned index, int value) {
+
+    if (index == 0) {
+        return list_prepend(head, value);
+    } else if (index == list_count(head)) {
+        return list_append(head, value);
+    } else {
+        link_t* link_insrt = list_new(value);
+        link_t* head_first = head;
+        link_t* head_next = NULL;
+        for (unsigned i = 0; i < index-1; i++) {
+            head = head->next;
+        }
+        head_next = head->next;
+        head->next = link_insrt;
+        head = link_insrt;
+        head->next = head_next;
+        return head_first;
+    }
+}
+
+link_t* list_delete(link_t* head, unsigned index) {
+    link_t* head_prev = NULL;
+    link_t* head_next = NULL;
+    link_t* head_ret = NULL;
+
+    if (head == NULL) {
+        return NULL;
+    } else if (index == 0) {
+        head_next = head->next;
+        free(head);
+        head = head_next;
+        head_ret = head;
+    } else {
+        link_t* head_first = head;
+        for (unsigned i = 0; i < index-1; i++) {
+            head = head->next;
+        }
+        head_prev = head;
+        head = head->next;
+        head_next = head->next;
+        free(head);
+        head = head_prev;
+        head->next = head_next;
+        head_ret = head_first;
+    }
+    if (head_ret != NULL) {
+        return head_ret;
+    } else {
+        return NULL;
+    }
+}
+
+link_t* list_concat(link_t* first, link_t* second) {
+    link_t* head_first = first;
+
+    while (first->next != NULL) {
+        first = first->next;
+    }
+    first->next = second;
+    return head_first;
+}
+
+link_t* list_sort(link_t* head) {
+    int tmp;
+    bool isswaped;
+    link_t* head_first = head;
+
+    do {
+        isswaped = false;
+        while (head->next != NULL) {
+            if (head->value > head->next->value) {
+                tmp = head->value;
+                head->value = head->next->value;
+                head->next->value = tmp;
+                isswaped = true;
+            }
+            head = head->next;
+        }
+        /* Reloop at the beginning of the list until there's values swaped */
+        head = head_first;
+    } while (isswaped);
+    return head_first;
+}
+
+static link_t* _list_merge_sort(link_t* head1, link_t* head2) {
+    link_t* head_result = NULL;
+
+    if (head1 == NULL) {
+        return head2;
+    }
+    if (head2 == NULL) {
+        return head1;
+    }
+    if (head1->value < head2->value) {
+        head_result = head1;
+        head_result->next = _list_merge_sort(head1->next, head2);
+    } else {
+        head_result = head2;
+        head_result->next = _list_merge_sort(head1, head2->next);
+    }
+    return head_result;
+}
+
+link_t* list_merge_sort(link_t* head) {
+    link_t* head1;
+    link_t* head2;
+
+    if (head == NULL || head->next == NULL) {
+        return head;
+    }
+
+    head1 = head;
+    head2 = head->next;
+    while (head2 != NULL && head2->next != NULL) {
+        head = head->next;
+        head2 = head->next->next;
+    }
+    head2 = head->next;
+    head->next = NULL;
+
+    head1 = list_merge_sort(head1);
+    head2 = list_merge_sort(head2);
+    return _list_merge_sort(head1, head2);
+}
+
+unsigned list_count(link_t* head) {
+    unsigned count = 0;
+
+    while (head != NULL) {
+        ++count;
+        head = head->next;
+    }
+    return count;
+}
+
+void list_set(link_t* head, unsigned index, int value) {
+    unsigned count = 0;
+
+    while (head != NULL && count < index) {
+        ++count;
+        head = head->next;
+    }
+    if (head != NULL) { head->value = value; }
+}
+
+int list_get(link_t* head, unsigned index) {
+    unsigned count = 0;
+
+    while (head != NULL && count < index) {
+        ++count;
+        head = head->next;
+    }
+    if (head != NULL) {
+        return head->value;
+    } else {
+        return -1;
+    }
+}
+
+void list_clear(link_t* head) {
+    link_t* next_link = NULL;
+
+    while (head != NULL) {
+        next_link = head->next;
+        free(head);
+        head = next_link;
+    }
+}
+
+void list_display_values(link_t* head) {
+    unsigned i = 0;
+
+    printf("------Begin------\n");
+    while (head != NULL) {
+        printf("value at [%d]=%d\n", i, head->value);
+        head = head->next;
+        i++;
+    }
+    printf("------End------\n");
+}
diff --git a/TP_9/exo2/clist.h b/TP_9/exo2/clist.h
new file mode 100644 (file)
index 0000000..2ca5752
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef CLIST_H
+#define CLIST_H
+
+/** Linked list of int */
+typedef struct link_s {
+    int value;
+    struct link_s* next;
+} link_t;
+
+link_t* list_new(int value); 
+link_t* list_append(link_t* head, int value); 
+link_t* list_prepend(link_t* head, int value); 
+link_t* list_insert(link_t* head, unsigned index, int value);
+link_t* list_delete(link_t* head, unsigned index);
+link_t* list_concat(link_t* first, link_t* second);
+link_t* list_sort(link_t* head);
+link_t* list_merge_sort(link_t* head);
+unsigned list_count(link_t* head);
+void list_set(link_t* head, unsigned index, int value);
+int list_get(link_t* head, unsigned index);
+void list_clear(link_t* head);
+void list_display_values(link_t* head);
+
+#endif /* CLIST_H */
diff --git a/TP_9/exo2/exo2.c b/TP_9/exo2/exo2.c
new file mode 100644 (file)
index 0000000..810bd9e
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+#include "clist.h"
+
+int main() {
+    link_t* head1 = NULL;
+    link_t* head2 = NULL;
+    link_t* head = NULL;
+
+    printf("Longueur de la liste: %d\n", list_count(head1));
+    head1 = list_append(head1, 1);
+    head1 = list_append(head1, 2);
+    head1 = list_append(head1, 3);
+    head1 = list_append(head1, 4);
+    printf("Longueur de la liste: %d\n", list_count(head1));
+    list_display_values(head1);
+    head1 = list_prepend(head1, 5);
+    printf("Longueur de la liste: %d\n", list_count(head1));
+    list_display_values(head1);
+    list_set(head1, 0, 78);
+    list_display_values(head1);
+    head1 = list_insert(head1, 2, 7);
+    list_display_values(head1);
+    head1 = list_delete(head1, 3);
+    list_display_values(head1);
+    head1 = list_append(head1, 5);
+    head1 = list_append(head1, 12);
+    head1 = list_append(head1, 65);
+    head1 = list_append(head1, 21);
+    head1 = list_sort(head1);
+    list_display_values(head1);
+    head2 = list_insert(head2, 0, 8);
+    head2 = list_append(head2, 6);
+    head2 = list_prepend(head2, 5);
+    list_display_values(head2);
+    head = list_concat(head1, head2);
+    list_display_values(head);
+    head = list_merge_sort(head);
+    //head = list_sort(head);
+    list_display_values(head);
+    //list_clear(head1);
+    //list_clear(head2);
+    list_clear(head);
+
+    return 0;
+}
diff --git a/exo_skel/Makefile b/exo_skel/Makefile
new file mode 100644 (file)
index 0000000..8adb5d0
--- /dev/null
@@ -0,0 +1,79 @@
+# Sample Makefile to build simple project.
+#
+# This Makefile expect all source files (.c) to be at the same level, in the
+# current working directory.
+#
+# It will automatically generate dependencies, compile all files, and produce a
+# binary using the provided name.
+#
+# Set BINARY_NAME to the name of the binary file to build.
+# Set BUILD_TYPE to either debug or release
+#
+# Automatic dependencies code from:
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr
+BINARY_NAME=exo_skel
+BUILD_TYPE=debug
+
+# ====================================
+# DO NOT CHANGE STUFF BEYOND THIS LINE
+# ====================================
+
+all: $(BINARY_NAME)
+
+CC=gcc
+LD=gcc
+
+WARN_FLAGS = -Wall -Wextra
+STD_FLAG = -std=c11
+
+ifeq ($(BUILD_TYPE),debug)
+BUILDDIR := .build/debug
+DEBUG_FLAG = -g
+STRIP_FLAG =
+OPTI_FLAG = -O0
+else
+BUILDDIR := .build/release
+DEBUG_FLAG =
+STRIP_FLAG = -s
+OPTI_FLAG = -O3
+endif
+
+CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG)
+LDFLAGS := $(LDFLAGS) $(STRIP_FLAG)
+
+OBJDIR := $(BUILDDIR)/objs
+$(shell mkdir -p $(OBJDIR))
+
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
+
+DEPDIR := $(BUILDDIR)/deps
+$(shell mkdir -p $(DEPDIR))
+DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
+POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
+
+$(BINARY_NAME): $(OBJS)
+       @echo "[LD ] $@"
+       @$(LD) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
+       @echo "[C  ] $*"
+       @$(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+       @$(POSTCOMPILE)
+
+$(DEPDIR)/%.d: ;
+
+.PRECIOUS: $(DEPDIR)/%.d
+
+include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
+
+clean:
+       @echo "[CLN]"
+       -@rm -r $(BUILDDIR)
+       -@rm $(BINARY_NAME)
+
+disassemble: $(BINARY_NAME)
+       objdump -d $< | less
+
+symbols: $(BINARY_NAME)
+       objdump -t $< | sort | less
diff --git a/exo_skel/exo_skel.c b/exo_skel/exo_skel.c
new file mode 100644 (file)
index 0000000..32d1af6
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main() {
+
+    return 0;
+}