From f0f758803cc2b142853579586c5cebc12e223a97 Mon Sep 17 00:00:00 2001 From: ache Date: Sat, 29 Dec 2018 02:10:04 +0100 Subject: =?UTF-8?q?Add=20stark=E2=9D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .babelrc | 6 + 403.html | 4 - 404.html | 4 - article/_liste | 1 - article/article.m4 | 18 - article/article.txt | 12 - article/bizarrerie-du-langage-c.md | 750 --------------------------------- article/des.txt | 11 - article/duckduckgo-google-en-mieux.md | 141 ------- article/intro.m4 | 5 - article/leC.txt | 87 ---- article/res/DuckDuckGo_Logo.png | Bin 14784 -> 0 bytes article/res/DuckDuckGo_Logo.svg | 70 --- article/res/c_language.svg | 3 - article/res/digraphe_c.png | Bin 10068 -> 0 bytes article/res/trigraphe_c.png | Bin 5052 -> 0 bytes article/res/zeroClickBox1.png | Bin 33536 -> 0 bytes articles/article.m4 | 18 + articles/bizarrerie-du-langage-c.md | 750 +++++++++++++++++++++++++++++++++ articles/des.txt | 11 + articles/duckduckgo-google-en-mieux.md | 141 +++++++ articles/intro.m4 | 5 + articles/res/DuckDuckGo_Logo.png | Bin 0 -> 14784 bytes articles/res/DuckDuckGo_Logo.svg | 70 +++ articles/res/c_language.svg | 3 + articles/res/digraphe_c.png | Bin 0 -> 10068 bytes articles/res/trigraphe_c.png | Bin 0 -> 5052 bytes articles/res/zeroClickBox1.png | Bin 0 -> 33536 bytes design/.design.css.swp | Bin 12288 -> 0 bytes design/.sommaire.css.swp | Bin 12288 -> 0 bytes design/cloud.svg | 17 - design/commentaire.css | 47 --- design/confirmation.css | 96 ----- design/contenu.css | 97 ----- design/design.css | 43 -- design/rainbow.css | 85 ---- design/sommaire.css | 105 ----- design/style.css | 164 ------- headers.m4 | 6 +- img/favicon.ico | Bin 1094 -> 0 bytes img/ic_bad_black_48px.svg | 4 - img/ic_comment_black_48px.svg | 5 - img/ic_error_black_48px.svg | 5 - img/ic_good_black_48px.svg | 5 - img/ic_help_black_48px.svg | 5 - img/ic_info_black_48px.svg | 5 - index.m4 | 9 +- left.m4 | 9 +- makefile | 160 ++++--- package.json | 29 +- res/ache.ico | Bin 1094 -> 0 bytes res/acheLogo.svg | 27 -- res/gitLogo.svg | 1 - res/mastoLogo.svg | 1 - res/rss.svg | 8 - res/twitterLogo.svg | 19 - res/zen.js | 28 -- s/err/403.html | 4 + s/err/404.html | 4 + s/img/ache.ico | Bin 0 -> 1094 bytes s/img/acheLogo.svg | 27 ++ s/img/favicon.ico | Bin 0 -> 1094 bytes s/img/gitLogo.svg | 1 + s/img/ic_bad_black_48px.svg | 4 + s/img/ic_comment_black_48px.svg | 5 + s/img/ic_error_black_48px.svg | 5 + s/img/ic_good_black_48px.svg | 5 + s/img/ic_help_black_48px.svg | 5 + s/img/ic_info_black_48px.svg | 5 + s/img/mastoLogo.svg | 1 + s/img/rss.svg | 8 + s/img/twitterLogo.svg | 5 + src/css/.design.css.swp | Bin 0 -> 12288 bytes src/css/.sommaire.css.swp | Bin 0 -> 12288 bytes src/css/_contenu.scss | 94 +++++ src/css/_rainbow.scss | 85 ++++ src/css/_sommaire.scss | 97 +++++ src/css/_style.scss | 124 ++++++ src/css/design.scss | 52 +++ src/js/zen.js | 27 ++ 80 files changed, 1709 insertions(+), 1939 deletions(-) create mode 100644 .babelrc delete mode 100644 403.html delete mode 100644 404.html delete mode 100755 article/_liste delete mode 100644 article/article.m4 delete mode 100755 article/article.txt delete mode 100644 article/bizarrerie-du-langage-c.md delete mode 100755 article/des.txt delete mode 100644 article/duckduckgo-google-en-mieux.md delete mode 100644 article/intro.m4 delete mode 100755 article/leC.txt delete mode 100644 article/res/DuckDuckGo_Logo.png delete mode 100644 article/res/DuckDuckGo_Logo.svg delete mode 100644 article/res/c_language.svg delete mode 100644 article/res/digraphe_c.png delete mode 100644 article/res/trigraphe_c.png delete mode 100755 article/res/zeroClickBox1.png create mode 100644 articles/article.m4 create mode 100644 articles/bizarrerie-du-langage-c.md create mode 100755 articles/des.txt create mode 100644 articles/duckduckgo-google-en-mieux.md create mode 100644 articles/intro.m4 create mode 100644 articles/res/DuckDuckGo_Logo.png create mode 100644 articles/res/DuckDuckGo_Logo.svg create mode 100644 articles/res/c_language.svg create mode 100644 articles/res/digraphe_c.png create mode 100644 articles/res/trigraphe_c.png create mode 100755 articles/res/zeroClickBox1.png delete mode 100755 design/.design.css.swp delete mode 100755 design/.sommaire.css.swp delete mode 100755 design/cloud.svg delete mode 100755 design/commentaire.css delete mode 100755 design/confirmation.css delete mode 100755 design/contenu.css delete mode 100755 design/design.css delete mode 100644 design/rainbow.css delete mode 100755 design/sommaire.css delete mode 100644 design/style.css delete mode 100644 img/favicon.ico delete mode 100644 img/ic_bad_black_48px.svg delete mode 100644 img/ic_comment_black_48px.svg delete mode 100644 img/ic_error_black_48px.svg delete mode 100644 img/ic_good_black_48px.svg delete mode 100644 img/ic_help_black_48px.svg delete mode 100644 img/ic_info_black_48px.svg delete mode 100644 res/ache.ico delete mode 100644 res/acheLogo.svg delete mode 100644 res/gitLogo.svg delete mode 100644 res/mastoLogo.svg delete mode 100755 res/rss.svg delete mode 100644 res/twitterLogo.svg delete mode 100644 res/zen.js create mode 100644 s/err/403.html create mode 100644 s/err/404.html create mode 100644 s/img/ache.ico create mode 100644 s/img/acheLogo.svg create mode 100644 s/img/favicon.ico create mode 100644 s/img/gitLogo.svg create mode 100644 s/img/ic_bad_black_48px.svg create mode 100644 s/img/ic_comment_black_48px.svg create mode 100644 s/img/ic_error_black_48px.svg create mode 100644 s/img/ic_good_black_48px.svg create mode 100644 s/img/ic_help_black_48px.svg create mode 100644 s/img/ic_info_black_48px.svg create mode 100644 s/img/mastoLogo.svg create mode 100755 s/img/rss.svg create mode 100644 s/img/twitterLogo.svg create mode 100755 src/css/.design.css.swp create mode 100755 src/css/.sommaire.css.swp create mode 100755 src/css/_contenu.scss create mode 100644 src/css/_rainbow.scss create mode 100755 src/css/_sommaire.scss create mode 100644 src/css/_style.scss create mode 100755 src/css/design.scss create mode 100644 src/js/zen.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..cf18521 --- /dev/null +++ b/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": ["@babel/env"], + "plugins": [ + ["@babel/plugin-proposal-object-rest-spread"] + ] +} diff --git a/403.html b/403.html deleted file mode 100644 index cd218bd..0000000 --- a/403.html +++ /dev/null @@ -1,4 +0,0 @@ - - - You can't touch this🦊 - diff --git a/404.html b/404.html deleted file mode 100644 index 21abcf1..0000000 --- a/404.html +++ /dev/null @@ -1,4 +0,0 @@ - - - cat not found - diff --git a/article/_liste b/article/_liste deleted file mode 100755 index f2a81a1..0000000 --- a/article/_liste +++ /dev/null @@ -1 +0,0 @@ -article/duckduckgo.txt diff --git a/article/article.m4 b/article/article.m4 deleted file mode 100644 index 72c1965..0000000 --- a/article/article.m4 +++ /dev/null @@ -1,18 +0,0 @@ - - - -include(HEADER_HEADER) - - - - - - -
-include(tmpFileNameArticle) -
-
- -include(left.htm) - - diff --git a/article/article.txt b/article/article.txt deleted file mode 100755 index 16b6829..0000000 --- a/article/article.txt +++ /dev/null @@ -1,12 +0,0 @@ -Premier billet|06/09/11|svg|http://ache.nyan.at/perso/ache[200*200].svg -
Voilà ! C'est fait quelques temps que je souhaitais remetre à jour ce site/blog/portofolio ... Désormais ça c'est fait.
- -

-Je suis @che, un lycéen de 15 ans. Depuis quelques temps, l'informatique me passionne et notamment la programmation. J'ai débuté en apprenant le langage C et possède quelques connaissances en d'autres langages comme le C++ ou le Python. Ce site a pour but de présenter mes divers projets ainsi que mon activité sur le Web. Pour plus d'informations je vous invite à visiter l'article "Qui suis-je" ou encore mes réalisations. -

- -

À propos de ce site

- -

Voila, j'ai remis à jour tout le site. Pour ceux qui se souviennent de l'ancien site statique en HTML, vous pouvez oublier. Le site est désormais en C. Oui, oui en langage C grâce au CGI. Le C me permet de manipuler le code de la page (un peu comme le PHP). Sinon, ce site utilise l'HTML5 et CSS3 et le JavaScript en Client-side. Tout le design est réalisé sans image. Le logo de cet article est en SVG.

- - diff --git a/article/bizarrerie-du-langage-c.md b/article/bizarrerie-du-langage-c.md deleted file mode 100644 index db5c2f5..0000000 --- a/article/bizarrerie-du-langage-c.md +++ /dev/null @@ -1,750 +0,0 @@ -Les bizarreries du langage C -============================ - -![The C Programming Language logo](res/c_language.svg) -Le C est un langage à la syntaxe simple. Les seules complexités de ce langage viennent du fait qu'il agit de manière proche de la machine. -Pourtant, une partie des syntaxes autorisées par le C n'est pratiquement jamais enseignée. Attaquons-nous à ces cas mystérieux ! 🧞 - ->!attention -> Pour comprendre ce billet, il est nécessaire d'avoir des bases dans un langage ayant une syntaxe et un fonctionnement proche du C. - - -Les opérateurs inusités ----------------------- - -Il existe deux opérateurs dans le langage C qui ne sont pratiquement jamais utilisés. Le premier est l'opérateur virgule. -En C la virgule sert à séparer factoriser les éléments d'une définition ou séparer les éléments d'une fonction. En bref, c'est un élément de ponctuation. -Mais pas seulement ! C'est également un opérateur. - - -### L'opérateur virgule - -L'instruction suivante, bien qu'inutile est tout à fait valide : - -~~~c -printf("%d", (5,3) ); -~~~ - -Elle affiche 3. L'opérateur `,` sert à juxtaposer des expressions. -La valeur de l'expression complète est égale à la valeur de la dernière expression. - -Cet opérateur se révèle très utile dans une boucle `for` pour multiplier les itérations. -Par exemple pour incrémenter `i` et décrémenter `j` dans la même itération d'une boucle `for` on peut faire : -~~~c -for( ; i < j ; i++, j-- ) { - // [...] -} -~~~ - -Ou encore, dans de petits `if` pour les simplifier : - -~~~c -if( argc > 2 && argv[2][0] == '0' ) - action = 4, color = false; -~~~ - -Ici, on assigne `action` et `color`. Normalement pour faire 2 assignations, on aurait dû mettre des accolades au `if`. - -On peut également s'en servir pour retirer des parenthèses. - -~~~c -while( c = getchar(), c != EOF && c != '\n' ) { - // [...] -} -// Est strictement équivalent à : -while( (c = getchar()) != EOF && c != '\n' ) { - // [...] -} -~~~ - -Mais surtout, ne pas abuser de cet opérateur ! On peut, de manière assez rapide, obtenir des choses illisibles. -Cette remarque est d'ailleurs également valide pour le prochain opérateur ! - -### L'opérateur ternaire - -Le ternaire pour les intimes. Le seul opérateur du langage C qui prenne 3 opérandes. -Il sert à simplifier des expressions conditionnelles. - -Par exemple pour afficher le minimum de deux nombres, sans le ternaire, on ferait : - -~~~c -if (a < b) - printf("%d", a); -else - printf("%d", b); -~~~ - -Ou avec une variable temporaire : - -~~~c -int min = a; -if( b < a) - min = b; -printf("%d", min); -~~~ - -Alors qu'avec les ternaires on fait simplement : - -~~~c -printf("%d", a!information -> Pour l'exemple, on va prendre une structure `point` que je vais utiliser plusieurs fois dans ce billet, idem pour la structure `message`. - -On peut ainsi initialiser un point en utilisant ses composantes. - -~~~c -typedef struct point { - int x,y; -} point; - - -point A = {.x = 1, .y = 2}; -~~~ - -Ici, il n'y avait pas d'ambigüité. -Mais pour une structure plus complexe, cette syntaxe est vraiment avantageuse. - -Tenez : - -~~~c -typedef struct message { - char src[20], dst[20], msg[200]; -} message; - -// [...] - -message to_send = {.src="", .dst="23:12:23", .msg="Code 10"}; - -// Est bien plus clair que : - -message to_send = {"", "23:12:23", "Code 10"}; - -// D'ailleurs, je ne l'ai pas fait mais avec cette syntaxe pas besoin de se souvenir de l'ordre -// des champs de la structure - -message to_send = { .msg="Code 10", .dst="23:12:23", .src=""}; - -// Et aussi puisque tout champ d'une structure est inialisé à sa valeur nulle s'il n'est pas initialisé explicitement. -// On peut également omettre src. - -message to_send = { .dst="23:12:23", .msg="Code 10"}; -~~~ - - -Avec ces syntaxes on peut également alourdir le code, mais généralement, on gagne en lisibilité. -Parfois, ces syntaxes sont très judicieusement utilisées ! -Comme ici, dans ce décodeur de base64 : ->~~~c ->static int b64_d[] = { -> ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, -> ['F'] = 5, ['G'] = 6, ['H'] = 7, ['I'] = 8, ['J'] = 9, -> ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, -> ['P'] = 15, ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, -> ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, ['Y'] = 24, -> ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, -> ['e'] = 30, ['f'] = 31, ['g'] = 32, ['h'] = 33, ['i'] = 34, -> ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39, -> ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, -> ['t'] = 45, ['u'] = 46, ['v'] = 47, ['w'] = 48, ['x'] = 49, -> ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, -> ['3'] = 55, ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, -> ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63, ['='] = 64 ->}; ->~~~ -Source: [Taurre](https://openclassrooms.com/forum/sujet/defis-8-tout-en-base64-19054?page=1#message-6921633) - - -[^tableau]: - `{0}` peut également être utilisé pour un nombre. Toute valeur initialisant une variable simple (pointeur, nombre, ...) peut optionnellement prendre des accolades. - - ~~~c - int a = {11}; - float pi = {3.1415926}; - char* s = {"unicorn"}; - ~~~ - - Ce qui caractérise le tableau du coup est surtout le fait d'utiliser des virgules entre les accolades. - -Les expressions littéralement composées --------------------------------------- - -Puisque nous parlons des tableaux. Il existe une syntaxe simple pour utiliser des tableaux à usage unique. - -Je voudrais utiliser ce tableau : -~~~c -int tab[5] = {5, 4, 5, 2, 1}; -printf("%d", tab[i]); // Avec i égale à quelque chose >=0 et <5 -~~~ - -Cependant, je ne l'utilise qu'une seule fois ce tableau ... -C'est un peu dérangeant d'avoir à utiliser un identificateur juste pour ça. - -*Eh* bien je peux faire ceci : -~~~c -printf("%d", ((int[]){5,4,5,2,1}) [i] ); // Avec i égale à quelque chose >=0 et <5 -~~~ - -Ce n'est pas super lisible pour le coup. Mais il existe plein de cas où cette syntaxe est très utile. Par exemple avec une structure : - -~~~c - -// Pour envoyer notre message : -send_msg( (message){ .dst="192.168.11.1", .msg="Code 11"} ); - -// Pour afficher la distance entre deux points -printf("%d", distance( (point){1, 2}, (point){2, 3} ) ); - -// Ou encore sous Linux, en programmation système -execvp( "bash" , (char*[]){"bash", "-c", "ls", NULL} ); -~~~ - -On appelle ces expressions des *compound literals* (ou littéraux agrégats si l'on s'essaye à traduire). - -Introduction aux VLAs --------- - -Les tableaux à taille variable (ou *Variable Length Arrays* en anglais, soit VLAs) sont des tableaux dont la taille n'est connue qu'à l'exécution. Si vous n'avez jamais entendu parler des VLAs, ceci devrait vous choquer : - -~~~c -int n = 11; - -int tab[n]; - -for(int i = 0 ; i < n ; i++) - tab[i] = 0; -~~~ - -Ce code, bien que valide, a dû être réprimandé par de nombreux professeurs. En effet, on nous apprend qu'un tableau doit avoir une taille connue à la compilation. -*Eh* bien, les VLAs constituent l'exception. Apparu avec la norme C99, les VLAs jouissent d'une mauvaise réputation. À cela, il existe plusieurs raisons que je ne détaillerais pas ici[^raisons]. Je vais simplement parler des comportements non-intuitifs introduits avec les VLAs. Mais tout d'abord, voyons ce qu'est et comment se servir d'un tableau à taille variable. - -Les VLAs se définissent avec la même syntaxe qu'un tableau classique. La seule différence est que la taille du tableau est une expression entière non constante. - -~~~c -int n = 50; -int tab[n]; - -double tab2[2*n]; - -unsigned int tab[foo()]; // avec foo une fonction définie ailleurs -~~~ - -Un VLA ne peut pas être initialisé, de plus, il ne peut être déclaré `static`. C'est-à-dire que ces deux déclarations sont incorrectes : - -~~~c -int n = 30; - -int tab[n] = {0}; -static tab2[n]; -~~~ - -Dans une fonction, on pourrait utiliser : - -~~~c -void bar(int n, int tab[n]) { - -} -~~~ - -Cependant, la taille de la première dimension d'un tableau n'a pas beaucoup d'importance, un tableau étant implicitement convertit en un pointeur vers son premier élément. En revanche, pour un tableau à deux dimensions, la taille de la deuxième dimension *doit* être spécifiée : - -~~~c -void foo( int n, int m, int tab[][m]) { - -} -~~~ - -À noter qu'il est possible d'utiliser le caractère `*` (encore une utilisation de plus) en lieu et place de la taille d'une ou plusieurs dimensions d'un VLA, mais *uniquement* au sein d'un prototype. - -~~~c -void foo(int, int, int[][*]); -~~~ - -Bien, après cette courte introduction aux VLAs, passons aux cas qui nous intéressent. Pour être précis, les bizarreries et excentricités que les VLAs ont introduits. - -[^raisons]: Je peux néanmoins vous donnez deux références [“Is it safe to use variable-length arrays?”](https://stackoverflow.com/questions/7326547/is-it-safe-to-use-variable-length-arrays) de stack overflow et cet article : [“The Linux Kernel Is Now VLA-Free”](https://www.phoronix.com/scan.php?page=news_item&px=Linux-Kills-The-VLA). - -L'exception des VLAs ---------------------------- - -Le comportement déviant le plus connu des VLAs est leur rapport à `sizeof`. - -`sizeof` est un opérateur unaire qui permet de retrouver la taille d'un type à partir d'une expression ou du nom d'un type entouré de parenthèses. - -~~~c -/* Le fonctionnement de l'opérateur sizeof par des exemples */ -float a; -size_t b = 0; - -printf("%zu", sizeof(char)); // Affiche 1 -printf("%zu", sizeof(int)); // Affiche 4 -printf("%zu", sizeof a); // Affiche 4 -printf("%zu", sizeof(a*2.)); // Affiche 8 -printf("%zu", sizeof b++); // Affiche 8 -~~~ - -Le premier résultat n'est pas très surprenant, la taille d'un `char` est défini à 1 *byte* et `sizeof(char)` doit retourner 1. Le deuxième résultat est la taille d'un `int`[^machine]. Le troisième résultat est la taille d'un `float`[^machine]. Le quatrième est la taille d'un `double`[^machine] qui est le type de l'expression `a*2.`[^float]. Le dernier résultat est la taille d'un `size_t`[^machine], `size_t` étant le type de l'expression `b++`. - -Ici, je ne me suis pas intéressé à la valeur des expressions et pour cause, `sizeof` ne s'y intéresse pas non plus. Ces valeurs sont déterminées à la compilation. Les opérations que l'on retrouve dans l'expression passé à `sizeof` ne sont pas effectuées. Puisque l'expression doit être valide, son type doit être déterminé à la compilation. Le résultat de `sizeof` étant alors connu à la compilation, il n'y avait aucune raison d'exécuter l'expression. - -~~~c -int n = 5; -printf("%zu", sizeof(char[++n])); // Affiche 6 -~~~ - -*Arf* ! Les VLAs rajoutent leur grain de sel. Dans le type `int[++n]`, `++n` est une expression non constante. Donc le tableau est un tableau à taille variable. Pour connaitre la taille totale du tableau, il est nécessaire d'exécuter l'expression entre crochet. Ainsi `n` vaut désormais 6 et `sizeof` nous indique qu'un VLA de `char` déclaré avec cette expression aurait eu pour taille `6`. - -Ce n'est que peu intuitif puisque les VLAs ont ici introduit une *exception à la règle* qui est de ne pas exécuter l'expression passée à `sizeof`. - - -Un autre comportement bizarre introduit par les VLAs est l'exécution des expressions liées à la taille d'un VLA dans la définition d'une fonction. Ainsi : - -~~~c -int foo( char tab[printf("bar")] ) { - printf("%zu", sizeof tab); -} -~~~ - -En supposant que les affichages ne causent pas d'erreur, appeler cette fonction affichera `bar3`. L'instruction `printf("bar")` est évaluée et ensuite seulement le corps de la fonction est exécuté. - -Il est à noter qu'il existe d'autres exceptions induites pas la standardisation des VLAs comme l'impossibilité d'allouer les VLAs de manière statique (assez logique), ou l'impossibilité d'utiliser des VLAs dans une structure (GNU GCC le support tout de même). Et même certains branchements conditionnels sont interdits lorsque l'on utilise un VLA. - -[^machine]: Sur ma machine -[^float]: Ici, l'implémentation des nombres flottants suit la norme IEE 754, où la taille d'un nombre flottant simple est de 4 octets et double précision est de 8 octets. `2.` est de type `double`, l'expression `2.*a` est donc du même type que le plus grand des deux types de ses deux opérandes, ici `double`. - -Un tableau flexible -------------------- - -Vous n'avez peut-être jamais entendu parler des « *flexible arrays member* ». C'est normal, ceux-ci répondent à une problématique très précise et peu courante. - -L'objectif est d'allouer une structure mais dont un champ (un tableau) est de taille inconnue à la compilation et le tout sur un espace contiguë[^pourquoi]. - -Ici, pas de VLAs, car comme on l'a vu, ceux-ci sont interdits en tant que champs de structure. L'allocation dynamique s'impose. -On pourrait vouloir faire : - -~~~c -struct foo { - int* tab; -}; -~~~ - -Et l'utiliser comme ceci : - -~~~c - struct foo* contigue = malloc( sizeof(struct foo) ); - if (contigue) { - contigue->tab = malloc( N * sizeof *contigue->tab ); - if (contigue->tab) { - contigue->tab[0] = 11; - } - } -~~~ - -Mais ici, le tableau n'a aucune raison d'être contiguë à la structure. Ce qui aura pour conséquence qu'en cas de copie de la structure, la valeur du champ `tab` sera la même pour la copie et l'origine. Pour éviter cela, il faudra copier la structure, réallouer le tableau et le recopier. Voyons une autre méthode. - -~~~c -struct foo { - /* ... Au moins un autre champ car le standard l'impose. */ - int flexiTab[]; -}; -~~~ - -Ici, le champ `flexiTab` est un tableau membre flexible. Un tel tableau doit être le dernier élément de la structure et ne pas spécifier de taille[^zero]. On l'utilise comme ceci : - -~~~c - struct foo* contigue = malloc( sizeof(struct foo) + N * sizeof *flexiTab ); - if (contigue) { - flexiTab[0] = 11; - } -~~~ - -Cette syntaxe répond autant à un besoin de portabilité sur les architectures imposant un alignement particulier (le tableau est contigu à la structure) qu'au besoin de faire apparaître un lien sémantique entre le tableau et la structure (le tableau appartient à la structure). - - -[^pourquoi]: On peut vouloir que cet espace soit contiguë pour plusieurs raisons. Une de ces raisons est pour optimiser l'utilisation du cache processeur. Également, la gestion des couches réseaux se portent assez bien à l'utilisation de tableaux flexibles. -[^zero]: Avant la spécification des « flexible array member » en C99, il était courant d'utiliser des tableaux de taille un pour reproduire le concept. - - -Une histoire d'étiquettes ------------------------- - -En C, s'il y a un truc dont on ne doit pas parler, ce sont bien des *étiquettes*. -On les utilise avec la structure de contrôle `goto` ! L'interdite ! - -Pour les cacher, on remplace les `goto` par des structures de contrôles adaptées et plus claires comme `break` ou `continue`. -De manière à ne jamais avoir à utiliser `goto`. - -Du coup, on n'apprend jamais ce qu'est une étiquette... - -Voici comment on utilise `goto` et une étiquette : - -~~~c -goto end; - - -end: return 0; -} -~~~ -En gros, une étiquette est un nom que l'on donne à une instruction. - - -*Eh* bien on en utilise des étiquettes ! Dans les `switch` ! - -~~~c - -switch( action ) { - case 0: - do_action0(); - case 1: - do_action1(); - break; - case 2: - do_action2(); - break; - default: - do_action3(); -} -~~~ - -Ici, les `case` et le `default` sont en fait des étiquettes ! Comme pour les `goto`. -Sauf qu'elles sont pour les `switch`, et inutilisables par les `goto`... - - ->!question -> Pourquoi tu nous parles de ça ? - -Déjà, c'est bien de savoir que ça s'appelle une étiquette. Ensuite, parce que je vais vous parlez d'un classique. -Le dispositif de *Duff*. - -C'est une sorte de boucle déroulée optimisée. Le but est de réduire le nombre de vérifications de fin de boucle (ainsi que le nombre de décrémentations). - -Voici la version historique écrite par Tom Duff : - -~~~c -{ - register n = (count + 7) / 8; - switch (count % 8) { - case 0: do { *to = *from++; - case 7: *to = *from++; - case 6: *to = *from++; - case 5: *to = *from++; - case 4: *to = *from++; - case 3: *to = *from++; - case 2: *to = *from++; - case 1: *to = *from++; - } while (--n > 0); - } -} -~~~ - -Peu importe ce que signifie `register`. Aussi, `to` est un pointeur particulier, mais ce n'est pas vraiment important. - -Ici, ce dont je veux vous parler, c'est de cette boucle `do-while` en plein milieu d'un `switch`. - -Le test que l'on cherche à effectuer le moins possible est `--n > 0`. - -En temps normal, `n` serait en fait `count`. Et on devrait faire le test `count` fois. -De même pour sa décrémentation. - -C'est-à-dire : - -~~~c -while( count-- > 0 ) - *to = *from++; -~~~ - -En divisant par 8 (nombre arbitraire) on divise également par 8 le nombre de tests et de décrémentations. -Cependant, si `count` n'est pas divisible par 8, on a un problème, on ne fait pas toutes les instructions. -Ce serait bien de pouvoir sauter directement à la 2ème instruction, si on a seulement 6 instructions restantes. - -Et c'est là que les étiquettes peuvent nous aider ! -Grâce au `switch` on peut sauter directement à la bonne instruction. - -Il suffit d'étiqueter chaque instruction avec le nombre d'instructions qu'il reste à faire dans la boucle. -Puis de sauter dans la boucle avec la structure de contrôle `switch` sur le reste d'instructions à réaliser. - -Ensuite, on exécute nos paquets de 8 instructions normalement. - -Il est très rare d'avoir à utiliser ce type d'astuce. -D'ailleurs, c'est une optimisation d'un autre temps. -Mais comme je voulais vous parler de syntaxe, il était nécessaire de parler des étiquettes. - -Les nombres complexes --------------------- - -Encore une fois nous allons voir une syntaxe introduite en C99. Plus exactement, ce sont 3 types qui ont été introduits, ceux-ci correspondent aux nombres complexes. Le type d'un nombre complexe est `double _Complex` (les deux autres types suivent le même schéma, afin de ne pas me répéter, je vais me concentrer sur le type `double`). - -Ainsi en C, il est possible de déclarer un nombre complexe comme ceci : - -~~~c -double complex point = 2 + 3 * I; -~~~ - -Ici, on retrouve les macros spéciales `complex` et `I` (définie dans l'en-tête ``). Le premier sert à créer un type complexe alors que le second sert à définir la partie imaginaire d'un nombre complexe. - -En mémoire une variable complexe occupe autant d'espace que 2 fois le type réel sur lequel elle est basée. On se sert d'une variable complexe comme d'une variable normale. L'arithmétique y est intuitive puisque basées sur celle des réels. Il est à noter qu'il est recommandé d'utiliser le macro `CMPLX` pour initialiser un nombre complexe : - -~~~c -double complex cplx = CMPLX(2, 3); -~~~ - -Pour une meilleure gestion des cas où la partie imaginaire (celle multipliée par `I` donc) serait `NAN`, `INFINITY` ou encore plus ou moins 0. - -L'en-tête `` nous offre une manière réellement simple d'utiliser des nombres imaginaires. En effet, de nombreuses fonctions courantes de manipulations des nombres imaginaires y sont disponibles. - -Les macros génériques ---------------------- - -Il existe un moyen en C d'avoir des macros qui soient définies différemment en fonction du type de l'un de ses arguments. Cette syntaxe est cependant « nouvelle » puisqu'elle date du standard C11. - -Cette généricité s'obtient avec les sélections génériques basées sur la syntaxe ` _Generic ( /* ... */ )` - -Pour comprendre la syntaxe, voyons un exemple simpliste : - -~~~c -#include -#include - -#define MAXIMUM_OF(x) _Generic ((x), \ - char: CHAR_MAX, \ - int: INT_MAX, \ - long: LONG_MAX \ - ) - -int main(int argc, char* argv[]) { - int i = 0; - long l = 0; - char c = 0; - - printf("%i\n", MAXIMUM_OF(i)); - printf("%d\n", MAXIMUM_OF(c)); - printf("%ld\n", MAXIMUM_OF(l)); - return 0; -} -~~~ - -Ici, on affiche le maximum que peut stocker chacun des types que nous utilisons. C'est quelque chose qui n'aurait pas été possible sans l'utilisation de ce nouveau mot-clé `_Generic`. -Pour utiliser cette syntaxe, on utilise le mot clé `_Generic` auquel on passe 2 paramètres. Le premier est une expression dont le type va influencer l'expression finalement exécutée. Le deuxième est une suite d'association de type et d'expression (type : expression) dont les associations sont séparées par des virgules. Au final, seule l'expression désignée par le type de la première expression est finalement évaluée. - - -Un exemple réel d'utilisation pourrait être : -~~~c -int powInt(int,int); - -#define POW(x,y) _Generic ((y), double: pow, float: powf, long double: powl, int: powInt)((x), (y)) -~~~ - - -Il n'y a plus grand-chose à dire si ce n'est qu'il est possible d'avoir dans la liste des types le mot `default` qui correspondra alors à tous les types non-cités. Ainsi une définition plus propre de la macro `POW` de tout à l'heure pourrait être : - -~~~c -int powIntuInt(int a, unsigned int b); -double powIntInt(int a, int b); -double powFltInt(double a,int b) { return pow (a,b); } -double powfFltInt(float a,int b) { return powf(a,b); } -double powlFltInt(long double a,int b) { return powl(a,b); } - - -#define POWINT(x) _Generic((x), double: powFltInt, \ - float : powfFltInt, \ - long double: powlFltInt, \ - unsigned int: powIntuInt, \ - default: powIntInt) -#define POW(x,y) _Generic ((y), double: pow, float: powf, long double: powl, default: POWINT((x)) )((x), (y)) -~~~ - -Les caractères trop spéciaux ---------------------------- - - -On va remonter encore dans le temps. -Je vais vous citer une dernière chose. -Un temps où tous les caractères n'étaient pas aussi accessibles que de nos jours sur autant de types de claviers. - -Les claviers n'avaient pas forcément de touches de composition. Ainsi, il était impossible de taper le caractère `#`. - -On pouvait alors remplacer le caractère `#` par la séquence `??=`. -Et pour chaque caractère n'étant pas sur le clavier et utiliser en langage C, il existait une séquence à base de `??` que l'on nomme trigraphe. Une autre version à base de 2 caractères plus lisible se nomme les digraphes. - -Voici un tableau récapitulatif des séquences de trigraphes, de digraphes et de leur représentation en caractère. - -+-----------+----------+-----------+ -| Caractère | Digraphe | Trigraphe | -+===========+==========+===========+ -| `#` | `%:` | `??=` | -+-----------+----------+-----------+ -| `[` | `<:` | `??(` | -+-----------+----------+-----------+ -| `]` | `:>` | `??)` | -+-----------+----------+-----------+ -| `{` | `<%` | `??<` | -+-----------+----------+-----------+ -| `}` | `%>` | `??>` | -+-----------+----------+-----------+ -| `\` | | `??/` | -+-----------+ +-----------+ -| `^` | | `??'` | -+-----------+ +-----------+ -| `|` | | `??!` | -+-----------+ +-----------+ -| `~` | | `??-` | -+-----------+----------+-----------+ -| `##` | `%:%:` | | -+-----------+----------+-----------+ - - - -La différence **principale** entre les digraphes et les trigraphes est dans une chaîne de caractère : - -~~~c -puts("??= est un croisillon"); -puts("%:"); -~~~ - -Ces mécanismes du Moyen Âge sont encore valides de nos jours en C. -Du coup, cette ligne de code est tout à fait valide : - -~~~c -??=define FIRST tab<:0] -~~~ - -La seule utilité de cette syntaxe de nos jours est d'obfusquer un code source très facilement. -Une combinaison d'un ternaire avec un trigraphe et un digraphe et vous avez un code absolument illisible. ;) - -~~~c -printf("%d", a ?5??((tab):>:0); -~~~ - -**À ne jamais utiliser dans un code sérieux** donc. - - -## Conclusion - -Voilà, c'est fini, j'espère que vous avez appris quelque chose de ce billet. Surtout n'oubliez pas d'utiliser ces syntaxes avec parcimonie. - -Je tiens tout particulièrement à remercier [Taurre](https://zestedesavoir.com/membres/voir/Taurre/) pour avoir validé cet article, mais également pour sa pédagogie sur les forums depuis des années, ainsi que [blo yhg](https://zestedesavoir.com/membres/voir/blo%20yhg/) pour sa relecture attentive. - -À noter que vous pouvez (re)découvrir de nombreux codes abusant de la syntaxe du langage C aux [IOCCC](http://ioccc.org/winners.html). 😈 diff --git a/article/des.txt b/article/des.txt deleted file mode 100755 index 60f902b..0000000 --- a/article/des.txt +++ /dev/null @@ -1,11 +0,0 @@ -Implémenté le DES|04/01/12|svg|http://ache.nyan.at/perso/ache[200*200].svg -
Le DES, Data Encryption Standard est un algorithme de chiffrement symétrique, par bloc de 64bits. Il a été inventé par IBM, sous le nom de Lucifer, algo destiné à un usage civile mais qui fût utiliser par des entreprises également. La NSA (National Security Agency, organisme États-Uniens chargé de la sécurité des systèmes de communication entre-autres) l'a légèrement modifier afin de créer le DES en 1976, puis normalisé en 1977, il fût alors utilisé nottament comme le standard de chiffrement des organismes du gouvernement des États-Unis. Puis fût remplacer en 2001 par l'AES (Advanced Encryption Standard) car il n'était plus considérer comme suffisament sûr.
- -

Attention, cet article est technique. Et s'adresse à des personnes ayant déjà une expérience en programmation et en Algorithmique. Ici, j'utiliserais le C pour implémenté cet Algorithme, mais ici, je me consentrerais sûr la théorie et donc vous pourrez aisément l'implémenter dans un autre langage. Cet Article n'étudie pas le DES de manière Mathématique, ceci étant suffisament complexe pour constituer un autre article. -

- -

À propos de ce site

- -

Voila, j'ai remis à jour tout le site. Pour ceux qui se souviennent de l'ancien site statique en HTML, vous pouvez oublier. Le site est désormais en C. Oui, oui en langage C grâce au CGI. Le C me permet de manipuler le code de la page (un peu comme le PHP). Sinon, ce site utilise l'HTML5 et CSS3 et le JavaScript en Client-side. Tout le design est réalisé sans image. Le logo de cet article est en SVG.

- - diff --git a/article/duckduckgo-google-en-mieux.md b/article/duckduckgo-google-en-mieux.md deleted file mode 100644 index 3195467..0000000 --- a/article/duckduckgo-google-en-mieux.md +++ /dev/null @@ -1,141 +0,0 @@ -DuckDuckGo, Google en mieux ? -=============== - -![Logo DuckDuckGo](res/DuckDuckGo_Logo.svg) -Depuis un certain temps déjà, Google ne se consacre plus entièrement à -son moteur de recherche. En effet, la firme est déjà bien implentée dans -la plupart des pays occidentaux où elle est le site le plus visité. Mais -la concurrence, elle, s'est développée. Les moteurs de recherches tels -que DuckDuckGo évoluent avec le temps, jusqu'à devenir plus pratique et -ergonomique que Google. -DuckDuckGo est un moteur de recherche assez jeune mais qui a beaucoup -d'avenir. En effet, il allie rapidité et fonctionnalités innovantes, -tout en conservant la vie privée de l'utilisateur - - -### Bang ! - -Vous connaissiez le "I'm Feeling Lucky" de Google ("J'ai de la chance" -en français). DuckDuckGo lui propose une fonctionnalité similaire du nom -de "I'm Feeling Ducky". En effet, il suffit de placer un point -d'exclamation ("bang" en anglais) dans les termes de votre recherche -afin d'arriver directement sur le premier résultat. Mais ce n'est pas -tout, sinon !Bang n'aurait rien d'innovant. DuckDuckGo permet d'accéder -simplement à certains sites environs une centaine. Par exemple, "!wfr" -permet d'afficher directement la page d'accueil de Wipipédia en Français -("!w" pour la version anglaise). On peut remarquer notamment "!sdz" qui -permet d'afficher directement la page d'accueil du site du zéro. Il -existe pour tous les sites couramment utilisés comme FaceBook par -exemple ("!fb"). - -Toujours pas convaincu ? !Bang peut également prendre des arguments dans -ces !Bang afin de créer une véritable ligne de commande. On peut ainsi -directement accéder à l'article DuckDuckGo de Wikipédia en français en -tapants simplement "!wfr DuckDuckGo". Et cela fonctionne avec énormément -de mot-clé comme "!ixquick", "!sp", "!g" (Google), "!answers", ... - -DuckDuckGo devient ainsi une véritable ligne de commande dans votre -navigateur Web. De quoi satisfaire les adeptes de la console. D'ailleur -de nombreux !Bang son adapté au developpement comme "!cpp" pour la man -du C++ ou encore "!golang" pour une recherche dans la documentation de -GO (le langage de programmation) - -Vous pouvez consulter la liste des -[!Bang](https://duckduckgo.com/bang.html) en tappant "!Bang" dans -DuckDuckGo. - - -### Zero Click Infobox - -![ZéroClickBox](res/zeroClickBox1.png) - -Mais qu'est-ce dont encore ce truc-là ? La Zéro Click Infobox, est une -boite d'information apparaissant avant les premiers liens et qui essaye -de vous apporter l'information que vous recherchez sans que vous ayez -besoin de visiter un quelconque autre site. Pratique quand on est -pressé. Elle vous propose également quelques liens utiles à tout début -de recherche. - -Afin d'apporter l'information, la Zero Click Infobox va s'appuyer sur -d'autres sites comme Wikipédia. Elle permet aussi comme la [calculatrice -de Google](https://fr.wikipedia.org/wiki/Calculatrice_Google) -d'effectuer des calculs directement dans le champ de recherche. Là où -DuckDuckGo innove, c'est dans la précision. En effet, Google se plante -assez minablement dans des calculs simples pour des raisons des -précisions. On connait tous le célèbre ["399 999 999 999 999 - 399 999 -999 999 998 = -0"](http://www.google.com/search?&q=399999999999999+-+399999999999998) -de Google. Pour pallier ce problème de précision, DuckDuckGo va -directement chercher sur WorlFramAlpha afin de faire les calculs les -plus compliqués (Il traite cependant les plus simples). - -Mais quitte à utiliser WolframAlpha ... autant utiliser toutes les -fonctionnalités disponibles ... C'est ce que propose DuckDuckGo. Ainsi, -on peut retrouver certaines informations très rapidement "mass of -jupiter" par exemple ou encore "base64 Hello World" qui donne -directement "SGVsbG8gV29ybGQ=". Ce système de conversion marche -également pour le binaire, rot13, SHA, ... Plus d'info et de -fonctionnalités sur leur page d'information [tech -Goodies](http://duckduckgo.com/tech.html) . Toutes les lister seraient -trop long. - - -### Respect de la vie privée - -Contrairement à Google, DuckDuckGo respecte la vie privée de ses -utilisateurs. DuckDuckGo reproche à Google de personnaliser les -recherches et de créer une sorte de bulle qui réduit les résultats en -fonction de vos centres d'intérèts et donc ainsi réduire le nombre -d'information auxquelles vous avez accès. DuckDuckGo lui propose donc -les mèmes résultats pour tous les utilisateurs. Voir la page -[dontbubble.us](http://dontbubble.us/) pour plus d'informations. - -Par ailleurs DuckDuckGo est totalement contre le tracking. Son slogan -est d'ailleurs "Google tracks you. We don't." . D'ailleurs, DuckDuckGo -n'utilise pas de Coockies (mis à part pour les préférences, mais il -propose également une alternative aux Cookies par URL) et ne stocke -aucun historique des requètes. Leur campagne -[donttrack.us](http://donttrack.us/) essaye d'ailleurs d'ètre assez -choquante. - -Encore plus de respect de la vie privée ? DuckDuckGo propose la -recherche anonyme par l'utilisation de TOR. Ou comment arriver à -l'anonymat le plus totale. Vous pouvez également utiliser la version -HTTPS qui utilise donc une couche de chiffrement SSL pour que tout soit -chiffré du début à la fin. - - -### Un Moteur de recherche proche de ses utilisateurs - - -DuckDuckGo est le seul moteur de recherche que je connaisse aussi ouvert -et aussi à l'écoute de ses utilisateurs. DuckDuckGo vous permets -[d'ajouter vos propres !Bang](https://duckduckgo.com/newbang.html) au -site (s'il y a plusieurs demandes, ils l'ajouteront). C'est certainement -comme cela qu'on peut retrouver "!sdz" comme !Bang. - -Pour les utilisateurs trouvant le moteur trop gourmand, DuckDuckGo -propose également une version lite de son moteur de recherche. Celui-ci -est cependant basique mais l'initiative est preuve de la bonne volonté -de DuckDuckGo de vouloir bien faire. - -DuckDuckGo est aussi une petite communauté. En effet, en plus d'ètre -totalement transparent sur leurs informations (code source, [info -trafique](http://duckduckgo.com/traffic.html) , ...), ils vous proposent -mème de participer à l'amélioration du Wiki, de la traduction de -DuckDuckGo, au développement du site, ou tout simplement de discuter sur -des améliorations à apporter sur \#duckduckgo sur Freenode. [Voir la -plateforme de développement](https://dukgo.com/base/welcome) - - -DuckDuckGo est ainsi une véritable mine d'or. Proposant de nombreuses -fonctionnalités innovantes. Il est de ce fait un des meilleurs moteurs -de recherche du moment. Personnellement, je l'adopte. Je découvre de -plus en plus de fonctionnalité en l'utilisant quotidiennement et ça fait -vraiment plaisir de gagner chaque jour en ergonomie. DuckDuckGo vient -récemment de dépasser le million de requètes par jour. - - -Consulter la page d'accueil de DuckDuckGo pour plus d'info sur -l'utilisation du moteur de recherche. - diff --git a/article/intro.m4 b/article/intro.m4 deleted file mode 100644 index 187de13..0000000 --- a/article/intro.m4 +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/article/leC.txt b/article/leC.txt deleted file mode 100755 index d66df07..0000000 --- a/article/leC.txt +++ /dev/null @@ -1,87 +0,0 @@ -Les pratiques méconnues du C|12/04/12|svg|http://ache.nyan.at/perso/ache[200*200].svg -
Le C est un langage proche de la machine, on parle de langage bas-niveau. Conçu dans les années 70, initalement pour le système d'exploitation Unix. C'est désormais l'un des langages les plus popululaire malgrès son certain âge.
- -

- Le C est très complet et a énormément de subtilités, même après des années d'apprentissage et de pratique, la maîtrise totale de C langage n'est pas assurée. De plus, c'est un langage qui évolue, tous les 10 ans environ, la norme change, la dernière à ce jour est la norme C11, sortie en décembre dernier. Chaque norme apporte son lot de pratiques nouvelles et celle-ci ne sont pas toujours suivit ou enseignées. Même les normes nouvelles ne sont pas toujours suivit par les compilateurs. Pourtant, certaines pratiques permises par le langage C sont très utiles et méconnue. -Voyons rapidement quelques'une de ces pratiques. -

- -

Le C de base

-
Depuis le C K&R, ces pratiques n'ont pas beaucoup évoluées mais sont pourtant méconues.
-

L'Opérateur virgule

- -

Très peu utilisé en pratique, mais peu s'avérer utile de temps à autre. La virgule est souvent utiliser pour constituer des listes de déclarations ou pour une liste de paramètre/argument à transmettre/récupérer à/par une fonction, mais ce n'est pas l'opérateur virgule. L'opérateur virgule lui permet d'associés 2 expressions. L'opérateur virgule s'entoure d'un couple d'expression, la première étant évalué comme de type void. Le résultat de l'opération est celui de la deuxième expression (même type donc). -Exemple d'utilisation : - a = i*=5, b+5; -Comme l'opération se lit de droite à gauche, le première expression est i*=5 et la deuxième est b+5. À la fin de l'opération, la variable b n'est pas modifiée, a prend la valeur de b + 5 et i est égale à 5 fois sa valeur initiale. L'utilité de l'opérateur virgule peu semblé limité car on aurait put décomposer cette instruction en 2 : - i *= 5; - a = b + 5; -C'est pour cela que l'opérateur virgule n'est pas souvent utilisé. On la retrouve courrament cependant dans les for ou les conditions sur 2 lignes (afin de ne pas mettre de crochets). - for(int i = 0; b >= i; --b, ++i); - if( b == i) - b = 0, - i = 0; - -Ne soyez pas surpris si vous en croisé dans un code ;) . -

- -

Les opérateurs # et ##

- -

Le croisillon et le double croisillon sont 2 opérateurs de processeurs rarement utilisés. Pourtant leurs applications sont multiples. L'opérateur # tout d'abord permet de transformer son opérande en chaine de caractère, c'est pratique pour débugger par exemple. - Exemple : - #define WTF_WITH( x ) puts( #x " %i - %s", x, __LINE__ ) -Comment ça marche ? -Avant la compilation, le préprocesseur transphorme WTF_WITH( var ) par printf( "var" " %i - " __LINE__ "\n", var). -Ici, on a 3 expressions littérales succéssives. Elles sont donc rassemblée en une "var %i - LaLigne\n". - - Maintenant, l'opérateur ## lui concatène 2 marqueurs de position. Pas très explicite voyons tout de suite en pratique : - Exemple : - #define WTF_WITH( x, y ) x ##y // equivalent à x ## y ou x##y -Ici, printf("%d", WTF_WITH( var, 2)); donnera après passage du préprocesseur, printf("%d", var2); . Là encore bien pratique pour le debuggage. - -Seulement les possibilités de ces 2 opérateurs ne se limites pas au debuggage de code .... -

- -

Les unions

-

- Vous connaissez les structures ? Et bien les unions, c'est une structure donc vous ne pouvez utiliser que un seul des champs à la fois. L'utilité ? - L'optimisation de la taille. En effet, la taille d'une union est égale à celle de son champ le plus lourd. Elle sert également à mieu organiser son code. - union ID { - char* name; - char ID; - }; -Ici, l'union ID fait sizeof(char*) bytes. On l'utilise comme une structure. -Les Unions sont utilisées par exemple par la SDL ... -

- -

Et depuis C89 et C99 ?

-

- Les normes C89 et C99 ont ajoutés beaucoup de nouveautés. Très peux sont courrament utilisées, et certaines ne sont carrément pas implémentées par les compilateurs. On peut pensée aux nombres complexes par exemple. -

-

L'initialisation des tableaux

-

-Depuis C89, on peut initialiser un tableau avec des crochets. Comme ceci : - int tab[] = { [0] = 0, [1] = 1, [5] = 4}; - Ainsi, on peut initialiser le 1000ième éléments dès sa déclaration. - On peut également utiliser cette syntaxe afin de créer un tableau de associatif (ou de correspondance). - C'est par exemple une méthode très pratique pour convertir une chaine en Base64. -

-

L'initialisation des structures

-

Personellement, j'ai du mal à voir l'utilité. Depuis C99, il est possible d'initiliser un structure champ par champ. - struct coord pointA = {.x = 10, .y = 20}; -

-

Et depuis C11 ?

- -

En matière d'obfuscation

- -

L'obsucation est le fait rendre un code illisible par un humain en complexifiant la lecture d'un code tout en ...

- -"Hj"[4]; -Les Trigraphes -La conpressions des chaines littérales -assert() -sélection générique C11 http://www.siteduzero.com/forum-83-635220-p4-la-poo-et-le-c.html#r6283122 -stdbool.h -stdint.h -Les composés litéraux - diff --git a/article/res/DuckDuckGo_Logo.png b/article/res/DuckDuckGo_Logo.png deleted file mode 100644 index 780a444..0000000 Binary files a/article/res/DuckDuckGo_Logo.png and /dev/null differ diff --git a/article/res/DuckDuckGo_Logo.svg b/article/res/DuckDuckGo_Logo.svg deleted file mode 100644 index 4b53b6e..0000000 --- a/article/res/DuckDuckGo_Logo.svg +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/article/res/c_language.svg b/article/res/c_language.svg deleted file mode 100644 index 5bf705d..0000000 --- a/article/res/c_language.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -image/svg+xml \ No newline at end of file diff --git a/article/res/digraphe_c.png b/article/res/digraphe_c.png deleted file mode 100644 index ffb7fd2..0000000 Binary files a/article/res/digraphe_c.png and /dev/null differ diff --git a/article/res/trigraphe_c.png b/article/res/trigraphe_c.png deleted file mode 100644 index 7d3dd82..0000000 Binary files a/article/res/trigraphe_c.png and /dev/null differ diff --git a/article/res/zeroClickBox1.png b/article/res/zeroClickBox1.png deleted file mode 100755 index db92266..0000000 Binary files a/article/res/zeroClickBox1.png and /dev/null differ diff --git a/articles/article.m4 b/articles/article.m4 new file mode 100644 index 0000000..e468b2c --- /dev/null +++ b/articles/article.m4 @@ -0,0 +1,18 @@ + + + +include(HEADER_HEADER) + + + + + + +
+include(tmpFileNameArticle) +
+
+ +include(tmp/left.htm) + + diff --git a/articles/bizarrerie-du-langage-c.md b/articles/bizarrerie-du-langage-c.md new file mode 100644 index 0000000..db5c2f5 --- /dev/null +++ b/articles/bizarrerie-du-langage-c.md @@ -0,0 +1,750 @@ +Les bizarreries du langage C +============================ + +![The C Programming Language logo](res/c_language.svg) +Le C est un langage à la syntaxe simple. Les seules complexités de ce langage viennent du fait qu'il agit de manière proche de la machine. +Pourtant, une partie des syntaxes autorisées par le C n'est pratiquement jamais enseignée. Attaquons-nous à ces cas mystérieux ! 🧞 + +>!attention +> Pour comprendre ce billet, il est nécessaire d'avoir des bases dans un langage ayant une syntaxe et un fonctionnement proche du C. + + +Les opérateurs inusités +---------------------- + +Il existe deux opérateurs dans le langage C qui ne sont pratiquement jamais utilisés. Le premier est l'opérateur virgule. +En C la virgule sert à séparer factoriser les éléments d'une définition ou séparer les éléments d'une fonction. En bref, c'est un élément de ponctuation. +Mais pas seulement ! C'est également un opérateur. + + +### L'opérateur virgule + +L'instruction suivante, bien qu'inutile est tout à fait valide : + +~~~c +printf("%d", (5,3) ); +~~~ + +Elle affiche 3. L'opérateur `,` sert à juxtaposer des expressions. +La valeur de l'expression complète est égale à la valeur de la dernière expression. + +Cet opérateur se révèle très utile dans une boucle `for` pour multiplier les itérations. +Par exemple pour incrémenter `i` et décrémenter `j` dans la même itération d'une boucle `for` on peut faire : +~~~c +for( ; i < j ; i++, j-- ) { + // [...] +} +~~~ + +Ou encore, dans de petits `if` pour les simplifier : + +~~~c +if( argc > 2 && argv[2][0] == '0' ) + action = 4, color = false; +~~~ + +Ici, on assigne `action` et `color`. Normalement pour faire 2 assignations, on aurait dû mettre des accolades au `if`. + +On peut également s'en servir pour retirer des parenthèses. + +~~~c +while( c = getchar(), c != EOF && c != '\n' ) { + // [...] +} +// Est strictement équivalent à : +while( (c = getchar()) != EOF && c != '\n' ) { + // [...] +} +~~~ + +Mais surtout, ne pas abuser de cet opérateur ! On peut, de manière assez rapide, obtenir des choses illisibles. +Cette remarque est d'ailleurs également valide pour le prochain opérateur ! + +### L'opérateur ternaire + +Le ternaire pour les intimes. Le seul opérateur du langage C qui prenne 3 opérandes. +Il sert à simplifier des expressions conditionnelles. + +Par exemple pour afficher le minimum de deux nombres, sans le ternaire, on ferait : + +~~~c +if (a < b) + printf("%d", a); +else + printf("%d", b); +~~~ + +Ou avec une variable temporaire : + +~~~c +int min = a; +if( b < a) + min = b; +printf("%d", min); +~~~ + +Alors qu'avec les ternaires on fait simplement : + +~~~c +printf("%d", a!information +> Pour l'exemple, on va prendre une structure `point` que je vais utiliser plusieurs fois dans ce billet, idem pour la structure `message`. + +On peut ainsi initialiser un point en utilisant ses composantes. + +~~~c +typedef struct point { + int x,y; +} point; + + +point A = {.x = 1, .y = 2}; +~~~ + +Ici, il n'y avait pas d'ambigüité. +Mais pour une structure plus complexe, cette syntaxe est vraiment avantageuse. + +Tenez : + +~~~c +typedef struct message { + char src[20], dst[20], msg[200]; +} message; + +// [...] + +message to_send = {.src="", .dst="23:12:23", .msg="Code 10"}; + +// Est bien plus clair que : + +message to_send = {"", "23:12:23", "Code 10"}; + +// D'ailleurs, je ne l'ai pas fait mais avec cette syntaxe pas besoin de se souvenir de l'ordre +// des champs de la structure + +message to_send = { .msg="Code 10", .dst="23:12:23", .src=""}; + +// Et aussi puisque tout champ d'une structure est inialisé à sa valeur nulle s'il n'est pas initialisé explicitement. +// On peut également omettre src. + +message to_send = { .dst="23:12:23", .msg="Code 10"}; +~~~ + + +Avec ces syntaxes on peut également alourdir le code, mais généralement, on gagne en lisibilité. +Parfois, ces syntaxes sont très judicieusement utilisées ! +Comme ici, dans ce décodeur de base64 : +>~~~c +>static int b64_d[] = { +> ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, +> ['F'] = 5, ['G'] = 6, ['H'] = 7, ['I'] = 8, ['J'] = 9, +> ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, +> ['P'] = 15, ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, +> ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, ['Y'] = 24, +> ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, +> ['e'] = 30, ['f'] = 31, ['g'] = 32, ['h'] = 33, ['i'] = 34, +> ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39, +> ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, +> ['t'] = 45, ['u'] = 46, ['v'] = 47, ['w'] = 48, ['x'] = 49, +> ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, +> ['3'] = 55, ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, +> ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63, ['='] = 64 +>}; +>~~~ +Source: [Taurre](https://openclassrooms.com/forum/sujet/defis-8-tout-en-base64-19054?page=1#message-6921633) + + +[^tableau]: + `{0}` peut également être utilisé pour un nombre. Toute valeur initialisant une variable simple (pointeur, nombre, ...) peut optionnellement prendre des accolades. + + ~~~c + int a = {11}; + float pi = {3.1415926}; + char* s = {"unicorn"}; + ~~~ + + Ce qui caractérise le tableau du coup est surtout le fait d'utiliser des virgules entre les accolades. + +Les expressions littéralement composées +-------------------------------------- + +Puisque nous parlons des tableaux. Il existe une syntaxe simple pour utiliser des tableaux à usage unique. + +Je voudrais utiliser ce tableau : +~~~c +int tab[5] = {5, 4, 5, 2, 1}; +printf("%d", tab[i]); // Avec i égale à quelque chose >=0 et <5 +~~~ + +Cependant, je ne l'utilise qu'une seule fois ce tableau ... +C'est un peu dérangeant d'avoir à utiliser un identificateur juste pour ça. + +*Eh* bien je peux faire ceci : +~~~c +printf("%d", ((int[]){5,4,5,2,1}) [i] ); // Avec i égale à quelque chose >=0 et <5 +~~~ + +Ce n'est pas super lisible pour le coup. Mais il existe plein de cas où cette syntaxe est très utile. Par exemple avec une structure : + +~~~c + +// Pour envoyer notre message : +send_msg( (message){ .dst="192.168.11.1", .msg="Code 11"} ); + +// Pour afficher la distance entre deux points +printf("%d", distance( (point){1, 2}, (point){2, 3} ) ); + +// Ou encore sous Linux, en programmation système +execvp( "bash" , (char*[]){"bash", "-c", "ls", NULL} ); +~~~ + +On appelle ces expressions des *compound literals* (ou littéraux agrégats si l'on s'essaye à traduire). + +Introduction aux VLAs +-------- + +Les tableaux à taille variable (ou *Variable Length Arrays* en anglais, soit VLAs) sont des tableaux dont la taille n'est connue qu'à l'exécution. Si vous n'avez jamais entendu parler des VLAs, ceci devrait vous choquer : + +~~~c +int n = 11; + +int tab[n]; + +for(int i = 0 ; i < n ; i++) + tab[i] = 0; +~~~ + +Ce code, bien que valide, a dû être réprimandé par de nombreux professeurs. En effet, on nous apprend qu'un tableau doit avoir une taille connue à la compilation. +*Eh* bien, les VLAs constituent l'exception. Apparu avec la norme C99, les VLAs jouissent d'une mauvaise réputation. À cela, il existe plusieurs raisons que je ne détaillerais pas ici[^raisons]. Je vais simplement parler des comportements non-intuitifs introduits avec les VLAs. Mais tout d'abord, voyons ce qu'est et comment se servir d'un tableau à taille variable. + +Les VLAs se définissent avec la même syntaxe qu'un tableau classique. La seule différence est que la taille du tableau est une expression entière non constante. + +~~~c +int n = 50; +int tab[n]; + +double tab2[2*n]; + +unsigned int tab[foo()]; // avec foo une fonction définie ailleurs +~~~ + +Un VLA ne peut pas être initialisé, de plus, il ne peut être déclaré `static`. C'est-à-dire que ces deux déclarations sont incorrectes : + +~~~c +int n = 30; + +int tab[n] = {0}; +static tab2[n]; +~~~ + +Dans une fonction, on pourrait utiliser : + +~~~c +void bar(int n, int tab[n]) { + +} +~~~ + +Cependant, la taille de la première dimension d'un tableau n'a pas beaucoup d'importance, un tableau étant implicitement convertit en un pointeur vers son premier élément. En revanche, pour un tableau à deux dimensions, la taille de la deuxième dimension *doit* être spécifiée : + +~~~c +void foo( int n, int m, int tab[][m]) { + +} +~~~ + +À noter qu'il est possible d'utiliser le caractère `*` (encore une utilisation de plus) en lieu et place de la taille d'une ou plusieurs dimensions d'un VLA, mais *uniquement* au sein d'un prototype. + +~~~c +void foo(int, int, int[][*]); +~~~ + +Bien, après cette courte introduction aux VLAs, passons aux cas qui nous intéressent. Pour être précis, les bizarreries et excentricités que les VLAs ont introduits. + +[^raisons]: Je peux néanmoins vous donnez deux références [“Is it safe to use variable-length arrays?”](https://stackoverflow.com/questions/7326547/is-it-safe-to-use-variable-length-arrays) de stack overflow et cet article : [“The Linux Kernel Is Now VLA-Free”](https://www.phoronix.com/scan.php?page=news_item&px=Linux-Kills-The-VLA). + +L'exception des VLAs +--------------------------- + +Le comportement déviant le plus connu des VLAs est leur rapport à `sizeof`. + +`sizeof` est un opérateur unaire qui permet de retrouver la taille d'un type à partir d'une expression ou du nom d'un type entouré de parenthèses. + +~~~c +/* Le fonctionnement de l'opérateur sizeof par des exemples */ +float a; +size_t b = 0; + +printf("%zu", sizeof(char)); // Affiche 1 +printf("%zu", sizeof(int)); // Affiche 4 +printf("%zu", sizeof a); // Affiche 4 +printf("%zu", sizeof(a*2.)); // Affiche 8 +printf("%zu", sizeof b++); // Affiche 8 +~~~ + +Le premier résultat n'est pas très surprenant, la taille d'un `char` est défini à 1 *byte* et `sizeof(char)` doit retourner 1. Le deuxième résultat est la taille d'un `int`[^machine]. Le troisième résultat est la taille d'un `float`[^machine]. Le quatrième est la taille d'un `double`[^machine] qui est le type de l'expression `a*2.`[^float]. Le dernier résultat est la taille d'un `size_t`[^machine], `size_t` étant le type de l'expression `b++`. + +Ici, je ne me suis pas intéressé à la valeur des expressions et pour cause, `sizeof` ne s'y intéresse pas non plus. Ces valeurs sont déterminées à la compilation. Les opérations que l'on retrouve dans l'expression passé à `sizeof` ne sont pas effectuées. Puisque l'expression doit être valide, son type doit être déterminé à la compilation. Le résultat de `sizeof` étant alors connu à la compilation, il n'y avait aucune raison d'exécuter l'expression. + +~~~c +int n = 5; +printf("%zu", sizeof(char[++n])); // Affiche 6 +~~~ + +*Arf* ! Les VLAs rajoutent leur grain de sel. Dans le type `int[++n]`, `++n` est une expression non constante. Donc le tableau est un tableau à taille variable. Pour connaitre la taille totale du tableau, il est nécessaire d'exécuter l'expression entre crochet. Ainsi `n` vaut désormais 6 et `sizeof` nous indique qu'un VLA de `char` déclaré avec cette expression aurait eu pour taille `6`. + +Ce n'est que peu intuitif puisque les VLAs ont ici introduit une *exception à la règle* qui est de ne pas exécuter l'expression passée à `sizeof`. + + +Un autre comportement bizarre introduit par les VLAs est l'exécution des expressions liées à la taille d'un VLA dans la définition d'une fonction. Ainsi : + +~~~c +int foo( char tab[printf("bar")] ) { + printf("%zu", sizeof tab); +} +~~~ + +En supposant que les affichages ne causent pas d'erreur, appeler cette fonction affichera `bar3`. L'instruction `printf("bar")` est évaluée et ensuite seulement le corps de la fonction est exécuté. + +Il est à noter qu'il existe d'autres exceptions induites pas la standardisation des VLAs comme l'impossibilité d'allouer les VLAs de manière statique (assez logique), ou l'impossibilité d'utiliser des VLAs dans une structure (GNU GCC le support tout de même). Et même certains branchements conditionnels sont interdits lorsque l'on utilise un VLA. + +[^machine]: Sur ma machine +[^float]: Ici, l'implémentation des nombres flottants suit la norme IEE 754, où la taille d'un nombre flottant simple est de 4 octets et double précision est de 8 octets. `2.` est de type `double`, l'expression `2.*a` est donc du même type que le plus grand des deux types de ses deux opérandes, ici `double`. + +Un tableau flexible +------------------- + +Vous n'avez peut-être jamais entendu parler des « *flexible arrays member* ». C'est normal, ceux-ci répondent à une problématique très précise et peu courante. + +L'objectif est d'allouer une structure mais dont un champ (un tableau) est de taille inconnue à la compilation et le tout sur un espace contiguë[^pourquoi]. + +Ici, pas de VLAs, car comme on l'a vu, ceux-ci sont interdits en tant que champs de structure. L'allocation dynamique s'impose. +On pourrait vouloir faire : + +~~~c +struct foo { + int* tab; +}; +~~~ + +Et l'utiliser comme ceci : + +~~~c + struct foo* contigue = malloc( sizeof(struct foo) ); + if (contigue) { + contigue->tab = malloc( N * sizeof *contigue->tab ); + if (contigue->tab) { + contigue->tab[0] = 11; + } + } +~~~ + +Mais ici, le tableau n'a aucune raison d'être contiguë à la structure. Ce qui aura pour conséquence qu'en cas de copie de la structure, la valeur du champ `tab` sera la même pour la copie et l'origine. Pour éviter cela, il faudra copier la structure, réallouer le tableau et le recopier. Voyons une autre méthode. + +~~~c +struct foo { + /* ... Au moins un autre champ car le standard l'impose. */ + int flexiTab[]; +}; +~~~ + +Ici, le champ `flexiTab` est un tableau membre flexible. Un tel tableau doit être le dernier élément de la structure et ne pas spécifier de taille[^zero]. On l'utilise comme ceci : + +~~~c + struct foo* contigue = malloc( sizeof(struct foo) + N * sizeof *flexiTab ); + if (contigue) { + flexiTab[0] = 11; + } +~~~ + +Cette syntaxe répond autant à un besoin de portabilité sur les architectures imposant un alignement particulier (le tableau est contigu à la structure) qu'au besoin de faire apparaître un lien sémantique entre le tableau et la structure (le tableau appartient à la structure). + + +[^pourquoi]: On peut vouloir que cet espace soit contiguë pour plusieurs raisons. Une de ces raisons est pour optimiser l'utilisation du cache processeur. Également, la gestion des couches réseaux se portent assez bien à l'utilisation de tableaux flexibles. +[^zero]: Avant la spécification des « flexible array member » en C99, il était courant d'utiliser des tableaux de taille un pour reproduire le concept. + + +Une histoire d'étiquettes +------------------------ + +En C, s'il y a un truc dont on ne doit pas parler, ce sont bien des *étiquettes*. +On les utilise avec la structure de contrôle `goto` ! L'interdite ! + +Pour les cacher, on remplace les `goto` par des structures de contrôles adaptées et plus claires comme `break` ou `continue`. +De manière à ne jamais avoir à utiliser `goto`. + +Du coup, on n'apprend jamais ce qu'est une étiquette... + +Voici comment on utilise `goto` et une étiquette : + +~~~c +goto end; + + +end: return 0; +} +~~~ +En gros, une étiquette est un nom que l'on donne à une instruction. + + +*Eh* bien on en utilise des étiquettes ! Dans les `switch` ! + +~~~c + +switch( action ) { + case 0: + do_action0(); + case 1: + do_action1(); + break; + case 2: + do_action2(); + break; + default: + do_action3(); +} +~~~ + +Ici, les `case` et le `default` sont en fait des étiquettes ! Comme pour les `goto`. +Sauf qu'elles sont pour les `switch`, et inutilisables par les `goto`... + + +>!question +> Pourquoi tu nous parles de ça ? + +Déjà, c'est bien de savoir que ça s'appelle une étiquette. Ensuite, parce que je vais vous parlez d'un classique. +Le dispositif de *Duff*. + +C'est une sorte de boucle déroulée optimisée. Le but est de réduire le nombre de vérifications de fin de boucle (ainsi que le nombre de décrémentations). + +Voici la version historique écrite par Tom Duff : + +~~~c +{ + register n = (count + 7) / 8; + switch (count % 8) { + case 0: do { *to = *from++; + case 7: *to = *from++; + case 6: *to = *from++; + case 5: *to = *from++; + case 4: *to = *from++; + case 3: *to = *from++; + case 2: *to = *from++; + case 1: *to = *from++; + } while (--n > 0); + } +} +~~~ + +Peu importe ce que signifie `register`. Aussi, `to` est un pointeur particulier, mais ce n'est pas vraiment important. + +Ici, ce dont je veux vous parler, c'est de cette boucle `do-while` en plein milieu d'un `switch`. + +Le test que l'on cherche à effectuer le moins possible est `--n > 0`. + +En temps normal, `n` serait en fait `count`. Et on devrait faire le test `count` fois. +De même pour sa décrémentation. + +C'est-à-dire : + +~~~c +while( count-- > 0 ) + *to = *from++; +~~~ + +En divisant par 8 (nombre arbitraire) on divise également par 8 le nombre de tests et de décrémentations. +Cependant, si `count` n'est pas divisible par 8, on a un problème, on ne fait pas toutes les instructions. +Ce serait bien de pouvoir sauter directement à la 2ème instruction, si on a seulement 6 instructions restantes. + +Et c'est là que les étiquettes peuvent nous aider ! +Grâce au `switch` on peut sauter directement à la bonne instruction. + +Il suffit d'étiqueter chaque instruction avec le nombre d'instructions qu'il reste à faire dans la boucle. +Puis de sauter dans la boucle avec la structure de contrôle `switch` sur le reste d'instructions à réaliser. + +Ensuite, on exécute nos paquets de 8 instructions normalement. + +Il est très rare d'avoir à utiliser ce type d'astuce. +D'ailleurs, c'est une optimisation d'un autre temps. +Mais comme je voulais vous parler de syntaxe, il était nécessaire de parler des étiquettes. + +Les nombres complexes +-------------------- + +Encore une fois nous allons voir une syntaxe introduite en C99. Plus exactement, ce sont 3 types qui ont été introduits, ceux-ci correspondent aux nombres complexes. Le type d'un nombre complexe est `double _Complex` (les deux autres types suivent le même schéma, afin de ne pas me répéter, je vais me concentrer sur le type `double`). + +Ainsi en C, il est possible de déclarer un nombre complexe comme ceci : + +~~~c +double complex point = 2 + 3 * I; +~~~ + +Ici, on retrouve les macros spéciales `complex` et `I` (définie dans l'en-tête ``). Le premier sert à créer un type complexe alors que le second sert à définir la partie imaginaire d'un nombre complexe. + +En mémoire une variable complexe occupe autant d'espace que 2 fois le type réel sur lequel elle est basée. On se sert d'une variable complexe comme d'une variable normale. L'arithmétique y est intuitive puisque basées sur celle des réels. Il est à noter qu'il est recommandé d'utiliser le macro `CMPLX` pour initialiser un nombre complexe : + +~~~c +double complex cplx = CMPLX(2, 3); +~~~ + +Pour une meilleure gestion des cas où la partie imaginaire (celle multipliée par `I` donc) serait `NAN`, `INFINITY` ou encore plus ou moins 0. + +L'en-tête `` nous offre une manière réellement simple d'utiliser des nombres imaginaires. En effet, de nombreuses fonctions courantes de manipulations des nombres imaginaires y sont disponibles. + +Les macros génériques +--------------------- + +Il existe un moyen en C d'avoir des macros qui soient définies différemment en fonction du type de l'un de ses arguments. Cette syntaxe est cependant « nouvelle » puisqu'elle date du standard C11. + +Cette généricité s'obtient avec les sélections génériques basées sur la syntaxe ` _Generic ( /* ... */ )` + +Pour comprendre la syntaxe, voyons un exemple simpliste : + +~~~c +#include +#include + +#define MAXIMUM_OF(x) _Generic ((x), \ + char: CHAR_MAX, \ + int: INT_MAX, \ + long: LONG_MAX \ + ) + +int main(int argc, char* argv[]) { + int i = 0; + long l = 0; + char c = 0; + + printf("%i\n", MAXIMUM_OF(i)); + printf("%d\n", MAXIMUM_OF(c)); + printf("%ld\n", MAXIMUM_OF(l)); + return 0; +} +~~~ + +Ici, on affiche le maximum que peut stocker chacun des types que nous utilisons. C'est quelque chose qui n'aurait pas été possible sans l'utilisation de ce nouveau mot-clé `_Generic`. +Pour utiliser cette syntaxe, on utilise le mot clé `_Generic` auquel on passe 2 paramètres. Le premier est une expression dont le type va influencer l'expression finalement exécutée. Le deuxième est une suite d'association de type et d'expression (type : expression) dont les associations sont séparées par des virgules. Au final, seule l'expression désignée par le type de la première expression est finalement évaluée. + + +Un exemple réel d'utilisation pourrait être : +~~~c +int powInt(int,int); + +#define POW(x,y) _Generic ((y), double: pow, float: powf, long double: powl, int: powInt)((x), (y)) +~~~ + + +Il n'y a plus grand-chose à dire si ce n'est qu'il est possible d'avoir dans la liste des types le mot `default` qui correspondra alors à tous les types non-cités. Ainsi une définition plus propre de la macro `POW` de tout à l'heure pourrait être : + +~~~c +int powIntuInt(int a, unsigned int b); +double powIntInt(int a, int b); +double powFltInt(double a,int b) { return pow (a,b); } +double powfFltInt(float a,int b) { return powf(a,b); } +double powlFltInt(long double a,int b) { return powl(a,b); } + + +#define POWINT(x) _Generic((x), double: powFltInt, \ + float : powfFltInt, \ + long double: powlFltInt, \ + unsigned int: powIntuInt, \ + default: powIntInt) +#define POW(x,y) _Generic ((y), double: pow, float: powf, long double: powl, default: POWINT((x)) )((x), (y)) +~~~ + +Les caractères trop spéciaux +--------------------------- + + +On va remonter encore dans le temps. +Je vais vous citer une dernière chose. +Un temps où tous les caractères n'étaient pas aussi accessibles que de nos jours sur autant de types de claviers. + +Les claviers n'avaient pas forcément de touches de composition. Ainsi, il était impossible de taper le caractère `#`. + +On pouvait alors remplacer le caractère `#` par la séquence `??=`. +Et pour chaque caractère n'étant pas sur le clavier et utiliser en langage C, il existait une séquence à base de `??` que l'on nomme trigraphe. Une autre version à base de 2 caractères plus lisible se nomme les digraphes. + +Voici un tableau récapitulatif des séquences de trigraphes, de digraphes et de leur représentation en caractère. + ++-----------+----------+-----------+ +| Caractère | Digraphe | Trigraphe | ++===========+==========+===========+ +| `#` | `%:` | `??=` | ++-----------+----------+-----------+ +| `[` | `<:` | `??(` | ++-----------+----------+-----------+ +| `]` | `:>` | `??)` | ++-----------+----------+-----------+ +| `{` | `<%` | `??<` | ++-----------+----------+-----------+ +| `}` | `%>` | `??>` | ++-----------+----------+-----------+ +| `\` | | `??/` | ++-----------+ +-----------+ +| `^` | | `??'` | ++-----------+ +-----------+ +| `|` | | `??!` | ++-----------+ +-----------+ +| `~` | | `??-` | ++-----------+----------+-----------+ +| `##` | `%:%:` | | ++-----------+----------+-----------+ + + + +La différence **principale** entre les digraphes et les trigraphes est dans une chaîne de caractère : + +~~~c +puts("??= est un croisillon"); +puts("%:"); +~~~ + +Ces mécanismes du Moyen Âge sont encore valides de nos jours en C. +Du coup, cette ligne de code est tout à fait valide : + +~~~c +??=define FIRST tab<:0] +~~~ + +La seule utilité de cette syntaxe de nos jours est d'obfusquer un code source très facilement. +Une combinaison d'un ternaire avec un trigraphe et un digraphe et vous avez un code absolument illisible. ;) + +~~~c +printf("%d", a ?5??((tab):>:0); +~~~ + +**À ne jamais utiliser dans un code sérieux** donc. + + +## Conclusion + +Voilà, c'est fini, j'espère que vous avez appris quelque chose de ce billet. Surtout n'oubliez pas d'utiliser ces syntaxes avec parcimonie. + +Je tiens tout particulièrement à remercier [Taurre](https://zestedesavoir.com/membres/voir/Taurre/) pour avoir validé cet article, mais également pour sa pédagogie sur les forums depuis des années, ainsi que [blo yhg](https://zestedesavoir.com/membres/voir/blo%20yhg/) pour sa relecture attentive. + +À noter que vous pouvez (re)découvrir de nombreux codes abusant de la syntaxe du langage C aux [IOCCC](http://ioccc.org/winners.html). 😈 diff --git a/articles/des.txt b/articles/des.txt new file mode 100755 index 0000000..60f902b --- /dev/null +++ b/articles/des.txt @@ -0,0 +1,11 @@ +Implémenté le DES|04/01/12|svg|http://ache.nyan.at/perso/ache[200*200].svg +
Le DES, Data Encryption Standard est un algorithme de chiffrement symétrique, par bloc de 64bits. Il a été inventé par IBM, sous le nom de Lucifer, algo destiné à un usage civile mais qui fût utiliser par des entreprises également. La NSA (National Security Agency, organisme États-Uniens chargé de la sécurité des systèmes de communication entre-autres) l'a légèrement modifier afin de créer le DES en 1976, puis normalisé en 1977, il fût alors utilisé nottament comme le standard de chiffrement des organismes du gouvernement des États-Unis. Puis fût remplacer en 2001 par l'AES (Advanced Encryption Standard) car il n'était plus considérer comme suffisament sûr.
+ +

Attention, cet article est technique. Et s'adresse à des personnes ayant déjà une expérience en programmation et en Algorithmique. Ici, j'utiliserais le C pour implémenté cet Algorithme, mais ici, je me consentrerais sûr la théorie et donc vous pourrez aisément l'implémenter dans un autre langage. Cet Article n'étudie pas le DES de manière Mathématique, ceci étant suffisament complexe pour constituer un autre article. +

+ +

À propos de ce site

+ +

Voila, j'ai remis à jour tout le site. Pour ceux qui se souviennent de l'ancien site statique en HTML, vous pouvez oublier. Le site est désormais en C. Oui, oui en langage C grâce au CGI. Le C me permet de manipuler le code de la page (un peu comme le PHP). Sinon, ce site utilise l'HTML5 et CSS3 et le JavaScript en Client-side. Tout le design est réalisé sans image. Le logo de cet article est en SVG.

+ + diff --git a/articles/duckduckgo-google-en-mieux.md b/articles/duckduckgo-google-en-mieux.md new file mode 100644 index 0000000..3195467 --- /dev/null +++ b/articles/duckduckgo-google-en-mieux.md @@ -0,0 +1,141 @@ +DuckDuckGo, Google en mieux ? +=============== + +![Logo DuckDuckGo](res/DuckDuckGo_Logo.svg) +Depuis un certain temps déjà, Google ne se consacre plus entièrement à +son moteur de recherche. En effet, la firme est déjà bien implentée dans +la plupart des pays occidentaux où elle est le site le plus visité. Mais +la concurrence, elle, s'est développée. Les moteurs de recherches tels +que DuckDuckGo évoluent avec le temps, jusqu'à devenir plus pratique et +ergonomique que Google. +DuckDuckGo est un moteur de recherche assez jeune mais qui a beaucoup +d'avenir. En effet, il allie rapidité et fonctionnalités innovantes, +tout en conservant la vie privée de l'utilisateur + + +### Bang ! + +Vous connaissiez le "I'm Feeling Lucky" de Google ("J'ai de la chance" +en français). DuckDuckGo lui propose une fonctionnalité similaire du nom +de "I'm Feeling Ducky". En effet, il suffit de placer un point +d'exclamation ("bang" en anglais) dans les termes de votre recherche +afin d'arriver directement sur le premier résultat. Mais ce n'est pas +tout, sinon !Bang n'aurait rien d'innovant. DuckDuckGo permet d'accéder +simplement à certains sites environs une centaine. Par exemple, "!wfr" +permet d'afficher directement la page d'accueil de Wipipédia en Français +("!w" pour la version anglaise). On peut remarquer notamment "!sdz" qui +permet d'afficher directement la page d'accueil du site du zéro. Il +existe pour tous les sites couramment utilisés comme FaceBook par +exemple ("!fb"). + +Toujours pas convaincu ? !Bang peut également prendre des arguments dans +ces !Bang afin de créer une véritable ligne de commande. On peut ainsi +directement accéder à l'article DuckDuckGo de Wikipédia en français en +tapants simplement "!wfr DuckDuckGo". Et cela fonctionne avec énormément +de mot-clé comme "!ixquick", "!sp", "!g" (Google), "!answers", ... + +DuckDuckGo devient ainsi une véritable ligne de commande dans votre +navigateur Web. De quoi satisfaire les adeptes de la console. D'ailleur +de nombreux !Bang son adapté au developpement comme "!cpp" pour la man +du C++ ou encore "!golang" pour une recherche dans la documentation de +GO (le langage de programmation) + +Vous pouvez consulter la liste des +[!Bang](https://duckduckgo.com/bang.html) en tappant "!Bang" dans +DuckDuckGo. + + +### Zero Click Infobox + +![ZéroClickBox](res/zeroClickBox1.png) + +Mais qu'est-ce dont encore ce truc-là ? La Zéro Click Infobox, est une +boite d'information apparaissant avant les premiers liens et qui essaye +de vous apporter l'information que vous recherchez sans que vous ayez +besoin de visiter un quelconque autre site. Pratique quand on est +pressé. Elle vous propose également quelques liens utiles à tout début +de recherche. + +Afin d'apporter l'information, la Zero Click Infobox va s'appuyer sur +d'autres sites comme Wikipédia. Elle permet aussi comme la [calculatrice +de Google](https://fr.wikipedia.org/wiki/Calculatrice_Google) +d'effectuer des calculs directement dans le champ de recherche. Là où +DuckDuckGo innove, c'est dans la précision. En effet, Google se plante +assez minablement dans des calculs simples pour des raisons des +précisions. On connait tous le célèbre ["399 999 999 999 999 - 399 999 +999 999 998 = +0"](http://www.google.com/search?&q=399999999999999+-+399999999999998) +de Google. Pour pallier ce problème de précision, DuckDuckGo va +directement chercher sur WorlFramAlpha afin de faire les calculs les +plus compliqués (Il traite cependant les plus simples). + +Mais quitte à utiliser WolframAlpha ... autant utiliser toutes les +fonctionnalités disponibles ... C'est ce que propose DuckDuckGo. Ainsi, +on peut retrouver certaines informations très rapidement "mass of +jupiter" par exemple ou encore "base64 Hello World" qui donne +directement "SGVsbG8gV29ybGQ=". Ce système de conversion marche +également pour le binaire, rot13, SHA, ... Plus d'info et de +fonctionnalités sur leur page d'information [tech +Goodies](http://duckduckgo.com/tech.html) . Toutes les lister seraient +trop long. + + +### Respect de la vie privée + +Contrairement à Google, DuckDuckGo respecte la vie privée de ses +utilisateurs. DuckDuckGo reproche à Google de personnaliser les +recherches et de créer une sorte de bulle qui réduit les résultats en +fonction de vos centres d'intérèts et donc ainsi réduire le nombre +d'information auxquelles vous avez accès. DuckDuckGo lui propose donc +les mèmes résultats pour tous les utilisateurs. Voir la page +[dontbubble.us](http://dontbubble.us/) pour plus d'informations. + +Par ailleurs DuckDuckGo est totalement contre le tracking. Son slogan +est d'ailleurs "Google tracks you. We don't." . D'ailleurs, DuckDuckGo +n'utilise pas de Coockies (mis à part pour les préférences, mais il +propose également une alternative aux Cookies par URL) et ne stocke +aucun historique des requètes. Leur campagne +[donttrack.us](http://donttrack.us/) essaye d'ailleurs d'ètre assez +choquante. + +Encore plus de respect de la vie privée ? DuckDuckGo propose la +recherche anonyme par l'utilisation de TOR. Ou comment arriver à +l'anonymat le plus totale. Vous pouvez également utiliser la version +HTTPS qui utilise donc une couche de chiffrement SSL pour que tout soit +chiffré du début à la fin. + + +### Un Moteur de recherche proche de ses utilisateurs + + +DuckDuckGo est le seul moteur de recherche que je connaisse aussi ouvert +et aussi à l'écoute de ses utilisateurs. DuckDuckGo vous permets +[d'ajouter vos propres !Bang](https://duckduckgo.com/newbang.html) au +site (s'il y a plusieurs demandes, ils l'ajouteront). C'est certainement +comme cela qu'on peut retrouver "!sdz" comme !Bang. + +Pour les utilisateurs trouvant le moteur trop gourmand, DuckDuckGo +propose également une version lite de son moteur de recherche. Celui-ci +est cependant basique mais l'initiative est preuve de la bonne volonté +de DuckDuckGo de vouloir bien faire. + +DuckDuckGo est aussi une petite communauté. En effet, en plus d'ètre +totalement transparent sur leurs informations (code source, [info +trafique](http://duckduckgo.com/traffic.html) , ...), ils vous proposent +mème de participer à l'amélioration du Wiki, de la traduction de +DuckDuckGo, au développement du site, ou tout simplement de discuter sur +des améliorations à apporter sur \#duckduckgo sur Freenode. [Voir la +plateforme de développement](https://dukgo.com/base/welcome) + + +DuckDuckGo est ainsi une véritable mine d'or. Proposant de nombreuses +fonctionnalités innovantes. Il est de ce fait un des meilleurs moteurs +de recherche du moment. Personnellement, je l'adopte. Je découvre de +plus en plus de fonctionnalité en l'utilisant quotidiennement et ça fait +vraiment plaisir de gagner chaque jour en ergonomie. DuckDuckGo vient +récemment de dépasser le million de requètes par jour. + + +Consulter la page d'accueil de DuckDuckGo pour plus d'info sur +l'utilisation du moteur de recherche. + diff --git a/articles/intro.m4 b/articles/intro.m4 new file mode 100644 index 0000000..187de13 --- /dev/null +++ b/articles/intro.m4 @@ -0,0 +1,5 @@ + diff --git a/articles/res/DuckDuckGo_Logo.png b/articles/res/DuckDuckGo_Logo.png new file mode 100644 index 0000000..780a444 Binary files /dev/null and b/articles/res/DuckDuckGo_Logo.png differ diff --git a/articles/res/DuckDuckGo_Logo.svg b/articles/res/DuckDuckGo_Logo.svg new file mode 100644 index 0000000..4b53b6e --- /dev/null +++ b/articles/res/DuckDuckGo_Logo.svg @@ -0,0 +1,70 @@ + + + + + + + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/articles/res/c_language.svg b/articles/res/c_language.svg new file mode 100644 index 0000000..5bf705d --- /dev/null +++ b/articles/res/c_language.svg @@ -0,0 +1,3 @@ + + +image/svg+xml \ No newline at end of file diff --git a/articles/res/digraphe_c.png b/articles/res/digraphe_c.png new file mode 100644 index 0000000..ffb7fd2 Binary files /dev/null and b/articles/res/digraphe_c.png differ diff --git a/articles/res/trigraphe_c.png b/articles/res/trigraphe_c.png new file mode 100644 index 0000000..7d3dd82 Binary files /dev/null and b/articles/res/trigraphe_c.png differ diff --git a/articles/res/zeroClickBox1.png b/articles/res/zeroClickBox1.png new file mode 100755 index 0000000..db92266 Binary files /dev/null and b/articles/res/zeroClickBox1.png differ diff --git a/design/.design.css.swp b/design/.design.css.swp deleted file mode 100755 index 89e9e74..0000000 Binary files a/design/.design.css.swp and /dev/null differ diff --git a/design/.sommaire.css.swp b/design/.sommaire.css.swp deleted file mode 100755 index 7a61c4d..0000000 Binary files a/design/.sommaire.css.swp and /dev/null differ diff --git a/design/cloud.svg b/design/cloud.svg deleted file mode 100755 index 5bace14..0000000 --- a/design/cloud.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - SVG Animation - A New Cloud - - - - - - - - - - diff --git a/design/commentaire.css b/design/commentaire.css deleted file mode 100755 index 5c8bdec..0000000 --- a/design/commentaire.css +++ /dev/null @@ -1,47 +0,0 @@ -#commentaires -{ - background-color: #c9cbce; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - border-radius: 10px; - width: 90%; height: auto; - margin: auto; - padding-bottom: 10px; -} -#c_intro -{ - font-style: oblique; - padding-top: 10px; - line-height: 250%; - padding-left: 25px; - text-indent: 10px; - font-size: 0.95em; - color: #944040; -} -#c_contenu -{ - text-indent: 100px; - font-size: 0.67em; - width: 70%; height: auto; - padding-left: 15px; -} -#c_contenu:after -{ - color: #FFF; - content: "_______________"; -} -#c_post -{ - width: 70%; height: auto; - padding-left: 15px; -} -#c_post p -{ - font-size: 0.7em; - padding-left: 25px; - -} -#c_titre -{ - color: #6b633e; -} diff --git a/design/confirmation.css b/design/confirmation.css deleted file mode 100755 index d7e1f97..0000000 --- a/design/confirmation.css +++ /dev/null @@ -1,96 +0,0 @@ -#boutons -{ - float: right; - margin: 2px 2px 2px 2px; -} -#bouton -{ - position: relative; - width: 20px; height: 16px; - background-color: #819fbc; - border: 1px solid #4a6a8b; - -moz-border-radius: 2px; -} -#bouton:hover -{ - -moz-box-shadow: 0px 0px 5px rgba(0,0,0,0.5); - -webkit-box-shadow: 0px 0px 5px rgba(0,0,0,0.5); - box-shadow: 0px 0px 5px rgba(0,0,0,0.5); -} -#reduire -{ - position: relative; - margin: 1px 0px 0px 1px; - width: 18px; height: 14px; - background-color: #5a81a8; -} -#reduire div -{ - position: absolute; - margin: 9px 0px 0px 2px; - width: 14px; height: 2px; - background-color: #dfe5ed; - -moz-border-radius: 1px; -} -#close -{ - position: relative; - margin: 1px 0px 0px 1px; - width: 18px; height: 14px; - background-color: #5a81a8; -} -#close div -{ - border: 1px solid #486480; - -moz-border-radius: 1px; - -webkit-border-radius: 1px; - background-color: #dfe5ed; - position: absolute; - margin: 5px 0px 0px 1px; - width: 14px; height: 2px; -} -#close div:first-child -{ - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - transform: rotate(45deg); -} -#close div:last-child -{ - -webkit-transform: rotate(-45deg); - -moz-transform: rotate(-45deg); - transform: rotate(-45deg); -} -#confirmation -{ - margin: auto; - width: 600px; height: 250px; - background-color: #517aa3; - border: 1px solid #8ba7c2; - -moz-border-radius: 10px; -} -#confirmation_mes -{ - width: 594px; height: 222px; - border: 1px solid #395572; - background-color: #e7e7e7; - margin: 23px 0px 0px 2px; - -moz-border-radius: 10px; -} -/* -
-
-
-
-
-
-
-
-
-
-
-

- Voulez confirmez l'envoye de ce commentaire ? -
-
-*/ diff --git a/design/contenu.css b/design/contenu.css deleted file mode 100755 index 8f0e10d..0000000 --- a/design/contenu.css +++ /dev/null @@ -1,97 +0,0 @@ -article h1 { - font-size:2em; - color: #A5B; -} -article h2 { - font-size:1.5em; - color: #BB8; -} -article h3 { - font-size:1.25em; - color: #AC4; -} -article h2:before { - content: "# "; - color: #ABB; - font: bold 0.95em arial, sans-serif; -} -article h3:before { - content: "## "; - color: #ABB; - font: bold 0.95em arial, sans-serif; -} -article h4:before { - content: "### "; - color: #ABB; - font: bold 1em arial, sans-serif; -} -section > p:nth-of-type(1) { -} -section > p:nth-of-type(1):after { - content: " "; - display: table; - clear: both; -} -section > p:nth-of-type(1) > img { - height:150px; - float:right; -} -article code { - color: #a00; - background: #eee; - border: 1px solid #ccc; - padding: 0 5px; -} -article -{ - margin-right: 2%; - margin-left: 3%; - float: left; - width: 83%; - background: #FFF; - margin-bottom: 2.5%; - padding-right:0%; - padding-left:0%; - padding: 1.6em 1.6em; - font-family: Merriweather, "Liberation Serif", "Segoe UI"; -} - -@media only screen and (min-width: 768px) { - article { - float: none; - margin-right: 7%; - margin-left: 300px; - width: auto; - - font-size:1em; - padding-right:5%; - padding-left:5%; - transition: margin-left 0.5s ease-out 0.25s; - - border: 1px solid #eaeaea; - border: 1px solid rgba(51, 51, 51, 0.1); - border-color: #eaeaea !important; - margin-top: 50px; - margin-bottom: 50px; - } - article.zen-mode { - margin-left: 7%; - transition: margin-left 0.5s ease-out 0.25s; - } -} - -@media only screen and (min-width: 768px) { - section > p:first-of-type { - margin-top: 2.5%; - margin-bottom: 2.5%; - padding-left: 6%; - color: #944040; - } -} - -.miniature -{ - float:left; - width:100px; - height:100px; -} diff --git a/design/design.css b/design/design.css deleted file mode 100755 index 36c29d0..0000000 --- a/design/design.css +++ /dev/null @@ -1,43 +0,0 @@ -@import url("contenu.css"); -@import url("sommaire.css"); -@import url("confirmation.css"); -@import url("commentaire.css"); -@import url("style.css"); -@import url("rainbow.css"); - -body -{ - font-family: 'Noto Serif', Verdana, sans-serif; - margin: 0px; - background: #f1f1f1; - color: #333333; - -} -#body_c -{ - background-repeat:no-repeat; - background-position:top left; -} -.fl -{ - float: left; -} -ache { - margin-left: auto; - margin-right: auto; -} -img { - display: block; - margin: 0 auto; - max-width: 100%; -} -.suite { - color: #888888; - outline: none; - text-decoration: none; - font-size: 0.6em; - font-weight: bold; - font-family: monospace, serif; - text-shadow: 0 1px 0 #DDD; -} - diff --git a/design/rainbow.css b/design/rainbow.css deleted file mode 100644 index 905eb8e..0000000 --- a/design/rainbow.css +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Style with support for rainbow parens - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #474949; - color: #d1d9e1; -} - - -.hljs-comment, -.hljs-quote { - color: #969896; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-type, -.hljs-addition { - color: #cc99cc; -} - -.hljs-number, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #f99157; -} - -.hljs-string, -.hljs-doctag, -.hljs-regexp { - color: #8abeb7; -} - -.hljs-title, -.hljs-name, -.hljs-section, -.hljs-built_in { - color: #b5bd68; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-selector-id, -.hljs-class .hljs-title { - color: #ffcc66; -} - -.hljs-section, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-subst, -.hljs-meta, -.hljs-link { - color: #f99157; -} - -.hljs-deletion { - color: #dc322f; -} - -.hljs-formula { - background: #eee8d5; -} - -.hljs-attr, -.hljs-attribute { - color: #81a2be; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/design/sommaire.css b/design/sommaire.css deleted file mode 100755 index 8fe78b7..0000000 --- a/design/sommaire.css +++ /dev/null @@ -1,105 +0,0 @@ -#sommaire -{ - height: 40px; - width: auto; - text-align: center; -} -@media only screen and (min-width: 768px) { - #sommaire { - padding-left: 290px; - } - -} -.sommaire_blien -{ - display: inline-block; - width: 33%; - text-align: left; - color: #121311; - font-size: 0.8em; - font-weight: bold; - font-family: monospace, serif; - text-shadow: 0 1px 0 #DDD; - color: #888888; -} -.sommaire_blien:before { - content: "/"; -} -.sommaire_blien a -{ - color: #888888; - outline: none; - text-decoration: none; -} -.sommaire_blien a:hover -{ - color: #BBAABB; -} - - #side-bar{ - text-align:center; - display: block; - /*background: none repeat scroll 0% 0% #F5F6F5;*/ - width:100%; - height:auto; - text-rendering: optimizelegibility; - box-sizing: border-box; - background:#F5F6F5; - padding-top: 10px; - } - -@media screen and (min-width: 768px) { - #side-bar { - position: fixed; - top: 0px; - bottom: 0px; - left: 0px; - height: 100%; - width: 290px; - transition: left 0.5s ease-in 0.25s; - text-align: center; - /*background: none repeat scroll 0% 0% #F5F6F5;*/ - background:#FFF; - border-right: 3px solid rgba(51, 51, 51, 0.1); - } - #side-bar.hidden { - left: -290px; - transition: left 0.5s ease-out 0.15s; - } -} -#side-bar h1 { - font-family: monospace, "Helvetica Neue", Arial, sans-serif; - /*font-family: "PT Sans","Helvetica Neue",Helvetica,Arial,sans-serif; -*/ -} -#desc { - font-size: 90%; - margin-top: 15px; -} -#about { - font-size: 0.8em; - color: #666; - -} -.about_bar { - display: inline-block; - width: 20%; - text-align: left; - color: #121311; - font-size: 0.8em; - font-weight: bold; - font-family: monospace, serif; - text-shadow: 0 1px 0 #DDD; - margin:auto; -} -.side-bar svg { margin: 0 auto; - display:block; -} - -/* -
-
Accueil
-
Blog
-
Liens
-
-*/ diff --git a/design/style.css b/design/style.css deleted file mode 100644 index 2b6ae40..0000000 --- a/design/style.css +++ /dev/null @@ -1,164 +0,0 @@ -body { font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; line-height: 1.6; word-wrap: break-word; padding: 30px; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); margin: 5%;} - -.directory { - cursor: pointer; - list-style-type: disc; -} -.file { - list-style: circle; -} -.file a { - padding-top: 5px; - padding-bottom: 5px; -} - -.qcm_item p { margin: 0; padding: 0; display:inline;} -.qcm_check { padding-left: 32px;} -.qcm_radio { padding-left: 32px;} - -blockquote { - color: #777; - padding: 1px 2%; - border-left: 5px solid #ccc; -} - -.special-box { - background: #eee7da; - margin: 12.5px 12.5px; - padding: 10px 0 10px 95px; - color: #424242; - min-height: 60px; -} -.special-box::before{ - content: ""; - display: block; - width: 48px; - height: 48px; - background-repeat: no-repeat; - margin: 0px 0 -48px -70px; -} -.information{ - background: #daeaee; -} -.information::before{ - background-image: url("/img/ic_info_black_48px.svg"); -} -.comment{ - background: #eea; -} -.comment::before{ - background-image: url("/img/ic_comment_black_48px.svg"); -} -.attention{ - background: #eee7da; -} -.attention::before{ - background-image: url("/img/ic_error_black_48px.svg"); -} -.question{ - background: #e2daee; -} -.question::before{ - background-image: url("/img/ic_help_black_48px.svg"); -} -.good{ - background: #aea; -} -.good::before{ - background-image: url("/img/ic_good_black_48px.svg"); -} -.bad{ - background: #eaa; -} -.bad::before{ - background-image: url("/img/ic_bad_black_48px.svg"); -} -.secret { - background: #eee; - padding: 10px 0 10px 15px; - min-height: 20px; -} -.hiden_block_quote { - display: none; -} -table { - border-collapse: collapse; - padding: 7px 13px; -} - -table, th, td { - border: 1px solid #dfe2e5; - padding: 7px 13px; -} -.special-box-content { - margin-top: 5px; -} -kbd { - background-color: #f8f6ea; - padding: 2px 6px; - border-radius: 3px; - border: 1px solid #e0dab6; - border-bottom-width: 3px; - text-shadow: 0 1px 0 #fff; - color: #5e551f; -} -.view { - position: relative; -} -.raw_button { - position: absolute; - top:10px; - right:0; - - margin : 0; - padding : 0; - border : 0; - background : transparent; - font-family : inherit; - font-size : 1em; - cursor : pointer; -} -.raw_button > div { - width : 40px; - height : 24px; - background : rgb(192,192,192) url('image.png') no-repeat center center; - line-height : 24px; - border : 1px solid rgba(27, 31, 35, 0.2); - border-radius : 3px; - font-size: 12px; - - color: #24292e; - background-color: #eff3f6; - background-image: linear-gradient(-180deg, #fafbfc 0%, #eff3f6 90%); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; -} - -.raw_button > div > div { - font-weight: bold; -} - -.no-style { - text-decoration: none; -} -.valid { - border: 2px solid #c0392b; - border-radius: 2px; - outline: none; - border-color: #9f9; - box-shadow: 0 0 5px #9f9; -} -.invalid { - - border: 2px solid #c0392b; - border-radius: 2px; - outline: none; - border-color: #f99; - box-shadow: 0 0 5px #f99; -} -.glowing { - border: 2px solid #c0392b; - border-radius: 2px; - outline: none; - border-color: #99f; - box-shadow: 0 0 5px #99f; -} diff --git a/headers.m4 b/headers.m4 index 9f0927a..52b7492 100644 --- a/headers.m4 +++ b/headers.m4 @@ -3,8 +3,8 @@ TITLE_TITLE - - - + + + diff --git a/img/favicon.ico b/img/favicon.ico deleted file mode 100644 index ba2b618..0000000 Binary files a/img/favicon.ico and /dev/null differ diff --git a/img/ic_bad_black_48px.svg b/img/ic_bad_black_48px.svg deleted file mode 100644 index 0b02d88..0000000 --- a/img/ic_bad_black_48px.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/img/ic_comment_black_48px.svg b/img/ic_comment_black_48px.svg deleted file mode 100644 index e0d89e2..0000000 --- a/img/ic_comment_black_48px.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/img/ic_error_black_48px.svg b/img/ic_error_black_48px.svg deleted file mode 100644 index d8eb238..0000000 --- a/img/ic_error_black_48px.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/img/ic_good_black_48px.svg b/img/ic_good_black_48px.svg deleted file mode 100644 index 0995688..0000000 --- a/img/ic_good_black_48px.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/img/ic_help_black_48px.svg b/img/ic_help_black_48px.svg deleted file mode 100644 index c92b2ad..0000000 --- a/img/ic_help_black_48px.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/img/ic_info_black_48px.svg b/img/ic_info_black_48px.svg deleted file mode 100644 index 266453e..0000000 --- a/img/ic_info_black_48px.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/index.m4 b/index.m4 index b429399..cf3f47e 100644 --- a/index.m4 +++ b/index.m4 @@ -1,12 +1,11 @@ - + -include(headers_index.htm) - +include(tmp/headers.htm) -include(articles.htm) +include(tmp/articles.htm) -include(left.htm) +include(tmp/left.htm) diff --git a/left.m4 b/left.m4 index 7f8ed44..1ea2e4e 100644 --- a/left.m4 +++ b/left.m4 @@ -1,18 +1,17 @@