Nuit Du Hack
Creative Commons License
.

Aller au contenu | Aller au menu | Aller à la recherche | Voir les modalités d'utilisation des travaux de l'auteur

Page d'accueil rss Sélection Geekstories.fr La Boite à Vomi

jeudi 28 novembre 2013

[ShellScript] Détecter les occurences d'une chaine dans les fichier d'un répertoire, récursivement. PARTII

[ Partager : Partager sur Digg ]
Salutations!

Un second petit article concernant la recherche récursive d’occurrences dans une arborescence de fichiers.

En effet, l'ami @zmf_Tim m'a fait remarqué, à raison, que dans pas mal de cas, la commande "grep -in 'occurrence' 'chemin'" pouvait faire l'affaire. Du coups, c'est vrai qu'au lieu d'utiliser l'usine à gaz que j'avais codé, j’utilisais plutôt sa commande.

Ça marche pas trop mal... Mais il y a un petit problème quand même: Pas moyen de faire cette commande de manière récursive!

Alors après une bonne heure à tenter l'impossible en étudiant minutieusement le MAN de grep, j'ai décidé de bidouiller un peu celle ci en l'intégrant dans un "find". Le résultat est pas trop mal. Bien entendu, ce doit sûrement être du déjà vu, et je pense que pas mal de gens l'utilisent déjà. Quoi qu'il en soit, j'ai décidé de vous la mettre là, au cas ou certains recherchent ce genre de fonctionnalité:

find ./ -iname "FICHIER[s]" -type f -exec grep -in --color "OCCURRENCE" {} \;

Amusez vous bien!

vendredi 27 septembre 2013

[ShellScript] Détecter les occurences d'une chaine dans les fichier d'un répertoire, récursivement.

[ Partager : Partager sur Digg ]
Salutations!

Aujourd'hui, un petit utilitaire codé à la va-vite pour détecter toutes les occurences d'une chaine de caractères à l'intérieur de tous les fichiers d'un dossier, et ce de manière récursive.

Pour l’anecdote, il se trouve qu'on m'as demandé, au boulot, de faire une petite modification sur le code de l'ancien développeur de la boite. Comme ce dernier codait comme une vieille toupie manchote, et en dépit du bon-sens, il se trouve que l’essentiel du boulot consiste à patcher son code à tous les endroits ou une référence X apparaît, en essayant de voir ce qu'il voulait faire à ce moment précis. (venant d'un mec qui a passé sa vie à faire du .NET, je ne m'étonne plus de rien)

Fin du troll

Heureusement, là, il s'agissait d'une appli PHP sur un serveur Debian (<3), et j'ai donc pu BASHER le boulot! Au cas ou certain puissent en avoir besoin, voici le code:

Le code:

L'utilitaire ci-dessous, qui n'est autre qu'un script bash peu optimisé, a pour but d'afficher le nom, l'emplacement, et le contenu de tous les fichiers contenant une occurrence de la chaine passée en paramètre, tout en surlignant la ligne exacte ou celle-ci apparaît:

    1 #!/bin/bash
    2 HR="\n"$(printf "%$(tput cols)s\n" | tr ' ' "*")"\n"
    3 for i in `find $1 -iname $2`;do 
    1         # echo $i;
    5         if grep $3 "$i"
    6         then
    7                 nline=0
    8                 echo -e "$HR\n( $i )"
    9                 while IFS=: read -r line; do
   10                         nline=$(($nline+1))
   11                         if echo $line | grep $3
   12                         then 
   13                                 echo -e "\033[1;32m$nline\t$line\033[0m" 
   14                         else
   15                                 echo -e "$nline \t$line"
   16                         fi
   17                 done < "$i" 
   18         fi
   19 done

Et il s'utilise comme ceci:

tixlegeek@malcolm:~/Scripts$ ./occurs /dossier/de/recherche "*.php" "Occurence"
Et pour une lecture plus aisée, on peut aussi réinjecter ça dans un less, en précisant bien l'option -R pour que la coloration ne soit pas zappée.

Et il s'utilise comme ceci:

tixlegeek@malcolm:~/Scripts$ ./occurs /dossier/de/recherche "*.php" "Occurence" | less -R

lundi 5 août 2013

[ShellScript] La dernière "Bonjour madame" Dans conky.

[ Partager : Partager sur Digg ]
Salutations!

Suite au vol de mon PC (et de quasiment tous mes Goodies NDH dans le TER en revenant de la NDH2k13 :( ), j'ai été contraint et obligé d'investir dans un nouveau laptop. Un bien beau laptop qu'est l'Asus N56Vz, aussi beau à l'intérieur qu'a l'extérieur. Bref! Une nouvelle machine, c'est toujours cool, et c'est encore plus cool de la configurer!

Après 10min (le temps de voir de quoi il retournait niveau fonctionnement) J'ai bien évidemment commencé par virer cette saloperie de W7 (d’ailleurs si quelqu'un veut une licence Winwin OEM, je la donne), pour y installer une Wheezy toute belle et toute neuve. Sorti de là, une fois installé deux ou trois utilitaires de survie, j'ai enfin pu commencer à faire joujou, et à personnaliser l'engin. (Par exemple en le tapissant avec les stickerz que l'ami @nyx__o (blog) m'avait envoyé fût un temps, merci à lui!)

Conky

Conky, pour ceux qui ne connaissent pas, c'est un super petit soft qui permet d'afficher les stats d'une machine, et bien plus que ça. Il est entièrement scriptable et peut être couplé à pas mal de trucs sympa comme un interpréteur Lua, et peut aussi exécuter des actions externes (Scripts bash, programmes...) et afficher la sortie.

Conky is a free, light-weight system monitor for X, that displays any information on your desktop. Conky is licensed under the GPL and runs on Linux and BSD. Source

En somme c'est un "must-have" du gros geek qui veut se la jouer Tony Stark quand il prend possession de sa session

Le point fort de conky, comme je l'ai déjà précisé plus haut, c'est qu'il est entièrement scriptable. C'est d'ailleurs ULTRA moche, et pas du tout sympa à faire, mais, ça fait partie du plaisir, et, quand on veut faire le kéké, faut assumer :)

On trouve sur le net un nombre indécent de configs, partagées par leur auteur, accompagné parfois de fichiers additionnels (scripts, images, fonts...) permettant de tweaker son propre conky comme on veut. En général, à chaque configuration de Conky, je prend une config qui me plait "à la base" sur le net, je la bidouille, et à la fin, ça me donne un truc entièrement différent... C'est la magie du partage!

L'objet de l'aticle

Avoir les stats de son PC sur son bureau, c'est plutôt cool. Et en ce qui me concerne, je commence souvent ma journée en allant voir la dernière demoiselle postée sur Bonjourmadame.fr. La question qui vient logiquement après ces deux affirmations et la suivante: Pourquoi pas faire les deux?

L'idée n'est pas nouvelle, et comme beaucoup, ce n'est pas la première fois que je code un truc pour aller pécho la dernière madame de ce site. Seulement voilà, le script que j'avais fait à l'époque, et ceux que j'ai tenté de récupérer sur le net ne marchent plus! Alors il m'a fallut agir, et coder un nouveau petit utilitaire.

Le plan d'action

L'idée est là. Reste à la mettre en pratique. Les scripts présentés sur le net se basent sur le même principe: On récupère le contenu de la page d'accueil, on y applique une expression régulière pour repérer l'URL de l'image de la madame, et on la télécharge. Tout ça se fait à base de wget/sed/curl/grep.... On ne dérogera pas à la règle.

Pour ma part, j'ai décidé de partir du flux Rss xml du site. Question de goût, mais, je trouvais ça plus logique, bien que dans les faits, le détail importe peu.

Une fois l'URL de la photo repérée, il faut la télécharger. Pour ça, un petit wget qui ne mange pas de pain et ne fait pas de miettes.

Après avoir rapatrié la jolie fille en sous-vêtements, j'ai décidé de traiter un peu l'image, pour générer une miniature parfaitement carrée, et de dimensions calibrées. Un petit coup de convert fera l'affaire. C'est quand même méga-bien les systèmes GNU/Linux!

Pour le fun, j'ai décidé de copier le fichier téléchargé sous un nom statique, de manière à pouvoir aller le chercher simplement depuis un raccourci dans ma barre de menu, et l'afficher à grand coup de display

Le code:

Au final, mon script ressemble à ça:

#!/bin/bash 
################################################################################
#             SCRIPT DE RÉCUPÉRATION AUTOMATIQUE DE LA DERNIERE
#                       DEMOISELLE DE BONJOURMADAME
################################################################################
#                                       
# Par Tixlegeek, http://www.tixlegeek.com - tixlegeek[aT]whoarehackers[dot]com
#                          Aucune revendication particulière
#
# Lignes à insérer dans le conkyrc:
#  ${texeci 200 ~/.conkybonjourmadame > /dev/null}     # Exécution periodique
#  ${image ~/.bonjour_madame/LATEST.png -p 40,730 -f 20}  # Affichage
#
#   LATEST.png     : Miniature carrée de la photo
#
FEEDURL="http://feeds.feedburner.com/BonjourMadame?format=xml"
# Teste la connexion à internet
if ping google.com -q -w 2 -c 1 > /dev/null 2>/dev/null; then
	# Dossier de destination.
	BMPATH="/home/tixlegeek/.bonjour_madame"
	THSIZE=250
	# Récupère l'URL de la dernière photo publiée à partir du flux Rss (xml)
	URL=`wget $FEEDURL -q -O -  | grep -o 'src="http[^"]*"'| cut -d\" -f2 | head -n1`
	# Récupère le nom du fichier
	NAME=$(basename $URL)
	# Extrait l'extension
	EXT=${NAME#*.}
	# Si le fichier existe déjà, pas besoin de le re-télécharger
	if [ -f "$BMPATH/$NAME" ]
	then
		exit
	else
		wget $URL -q -O "$BMPATH/$NAME"
		# Copie le fichier en résolution normale pour une utilisation
		# future... Comme l'affichage en grand.
		cp "$BMPATH/$NAME" "$BMPATH/LATEST_Big.${NAME#*.}"
	#	echo	"$BMPATH/LATEST_Big.$EXT"
	fi 
	# Télécharge la dernière madame
	wget $URL -q -O "$BMPATH/$NAME"
	# Recadre la demoiselle en un joli carré bien propre
	convert "$BMPATH/$NAME" -thumbnail $THSIZEx$THSIZE^ -gravity center -extent $THSIZEx$THSIZE "$BMPATH/LATEST.png"
fi

Pour l'utiliser, rien de plus simple. Il faut l'enregistrer dans un fichier, le chmodPlusXer, et le lancer périodiquement depuis conky. Pour se faire, on va utiliser ${texeci x cmd }, qui permet d'exécuter une commande externe cmd tout les x secondes dans un thread séparé, et éventuellement d'afficher la sortie (chose dont on se passera dans le cas présent). Pour pouvoir afficher la miniature dans conky, on va utiliser la balise ${image img -p x,y -f t }. Ici, img est le chemin vers la miniature, x,y sont les coordonnées où placer l'image, et t, le timeout permettant de recharger l'image.

Et comme un screenshot vaut toujours mieux qu'un long discours, voilà ce que ça donne chez moi:

De toute beauté n'est-ce pas? :)

Plusplus et bon surf, Tixlegeek.

dimanche 2 septembre 2012

[Tixlegeek's Workshop] Servo-motor controller GUI sous GNU/Linux

[ Partager : Partager sur Digg ]
Salutations!

Hier, a midi, j'ai reçu ça:

C'est une petite carte permettant de controler 24 servo-moteurs via une liaison série. Seulement voilà, comme tout bon appareil chinois qui se respecte, il est livré avec un petit paquet d'utilitaires, et bien entendu, tous dispo sous Windaube exclusivement.

*

J'ai donc cherché un peu sur le net pour trouver des outils équivalents sous GNU/Linux, mais n'ait rien trouvé... Alors j'ai codé un petit utilitaire graphique pour commander cette petite carte sur mes machines, vierges de toute salissure microsoftienne. (Sous linux en somme).

Le petit utilitaire en question le voici:

Download

Le programme est écrit en python, et utilise les librairies pySerial et wxPython. Chaque canal est généré suivant le nombre d'I/O désirées. Pour le moment, il n'est possible que de controler les servos, mais, d'ici quelque versions, tout sera utilisable!

Tixlegeek's ServoToolBox v0.1

jeudi 24 mars 2011

[ShellScript] Utilitaire de MacSpoofing

[ Partager : Partager sur Digg ]
Salutations!

Voilà un petit utilitaire qui permet de modifier l'adresse MAC d'une interface réseaux sur systemes GNU/Linux. J'avais déjà posté un truc du genre, mais, bien moins ergonomique. Ce matin, en cours, j'ai donc codé un truc plus joli.

Ce petit script doit etre lancé en root (gksudo ./.MacSpoof) et nécessite le programme zenity. Il permet de configurer une adresse MAC aléatoire sur une interface. Un petit menu vous permet de choisir simplement l'interface, parmi celles disponibles sur votre machine.

Pour l'installer (récupérer les sources, la dépendance, et le rendre exécutable) tapez simplement, dans un terminal root:

sudo apt-get install zenity
wget http://tixlegeek.com/Scriptz/.MacSpoof -O ~/.MacSpoof
chmod 775 ~/.MacSpoof

Et voilà le script en lui même:

#!/bin/bash 
#         SCRIPT DE CONFIGURATION D'ADRESSE MAC ALEATOIRE
###################################################################
# Par Tixlegeek (cc by-nc-sa) - Aucune revendication particulière
#  http://www.tixlegeek.com - tixlegeek[aT]gmail[dot]com
#
echo -e "Calcul d'une nouvelle adresse MAC alétoire..."
RANDOMMAC=`openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//'`
SPOOFINTERFACE=$(zenity --list --column=Interfaces `ifconfig | grep -Eo "^[A-Za-z]{2,6}[0-9]"` --text="Choisissez l'interface à configurer" )
ifconfig $SPOOFINTERFACE down hw ether $RANDOMMAC up
echo "Interface $SPOOFINTERFACE configurée avec l'adresse MAC $RANDOMMAC"
sleep 4

J’espère qu'il sera utile à quelque personnes! :)

mercredi 9 février 2011

[Code] Animation Matrix en C.

[ Partager : Partager sur Digg ]
Salutations!

Je viens juste de terminer la réécriture d'un de mes anciens programmes; "Matrix operator". Pas mal dépoussiéré! On vois bien le changement de style. C'est une animation de type "cryptogramme matrix", entierement écrite en C, avec la librairie SDL, et entierement réalisée avec des logiciels libres.

Vous pouvez télécharger l'archive, la modifier, ou la redistribuer, suivant les termes de la license GPLv3 (incluse).

Code source:

/*
      ___  ___    _____ _      _                      _   __
      |  \/  |   |_   _(_)    | |                    | | / /
      | .  . | __ _| |  ___  _| | ___  __ _  ___  ___| |/ / 
      | |\/| |/ _` | | | \ \/ / |/ _ \/ _` |/ _ \/ _ \    \ 
      | |  | | (_| | | | |>  <| |  __/ (_| |  __/  __/ |\  \
      \_|  |_/\__,_\_/ |_/_/\_\_|\___|\__, |\___|\___\_| \_/
                                    __/ |                
                                   |___/                 

==================================== CREDITS ===================================
  - "Matixlegeek" Par Tixlegeek (Graphismes, Code, Algo) est soumis à la 
  license GPLV3
  
  Version: 1.0
  Release: 09/02/11
  
 http://www.tixlegeek.com                         tixlegeek@gmail.com
==================================== GPLv3 =====================================
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 3
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  http://www.gnu.org/licenses/gpl.html
================================== COMPILATION =================================
Compilation: gcc matixlegeek.c `sdl-config --cflags` `sdl-config --libs` -lSDL_image -o matixlegeek
===================================== NOTE =====================================

/!\ --> Addaptez le programme à votre résolution pour un meilleur résultat!

*/
#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
#include <SDL_image.h>

#define SCREEN_W 1024        // Résolution
#define SCREEN_H 768

#define GLYPH_W 20          // Dimention d'un glyphe

#define MAP_W (SCREEN_W/GLYPH_W)  // W de la carte
#define MAP_H (SCREEN_H/GLYPH_W)  // H de la carte

#define MAP_S (MAP_W*MAP_H)    // Taille de la carte

#define CHAINLEN 15          // Longueur des chaines

#define CL_DRKR CHAINLEN/3      // Style tres sombre
#define CL_DRK (CHAINLEN/3)*2    // Style sombre
#define CL_LGH CHAINLEN        // Style claire
 
void GlyBlit(int x, int y, int index, int style, SDL_Surface *dst, SDL_Surface *artwork);
void ShowMatrix(unsigned char *MatrixedMap, SDL_Surface *screen, SDL_Surface *artwork);
void NewBeacon(char zone, unsigned char *MatrixedMap, char type);
void Iteration(unsigned char *MatrixedMap);

int main(int argc, char *argv[])
{
  int looping = 0, count=0;
  unsigned char MatrixedMap[MAP_S]={0};
  SDL_Surface   *screen = NULL,
            *buffer = NULL, 
            *artwork = NULL;
  //SDL_Rect glyph={0,0,0,0};
  
  SDL_Rect CreditClip = {0,80,200,100};
  SDL_Rect CreditPos = {10,10,0,0};
  
  SDL_Event event;
  
  SDL_Init(SDL_INIT_VIDEO);
  SDL_EnableKeyRepeat(10, 10);
  screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);//SDL_FULLSCREEN | 
  SDL_WM_SetCaption("MatixLeGeek - http://www.tixlegeek.com", NULL);
  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,0,0));
  
  artwork = IMG_Load("artwork2.png");
  
  while (!looping)
  {
    //    Arret du programme
    SDL_PollEvent(&event);
    switch(event.type)
    {
      case SDL_QUIT:
        looping++;
      break;
      case SDL_KEYDOWN:
        switch(event.key.keysym.sym)
        {
          case SDLK_ESCAPE:
            looping++;
           break;
         }
       break;
       default:
       break;
    }
    /*
          Créé des constructeurs    
    */
    for(count=0; count<=5; count++)
      {
        NewBeacon(1, MatrixedMap,CHAINLEN);
      }
      for(count=0; count<=5; count++)
      {
        NewBeacon(0, MatrixedMap,(CHAINLEN/3)*2);
      }
    /*
          Détruit des constructeurs    
    */
        for(count=0; count<=50; count++)
      {
        NewBeacon(1, MatrixedMap,0);
      }
      // Une itération à chaque passage
    Iteration(MatrixedMap);
    // Affichage de la carte
    ShowMatrix(MatrixedMap, screen, artwork);
    SDL_BlitSurface(artwork, &CreditClip, screen, &CreditPos );
    // Affichage du buffer
    SDL_Flip(screen);
    
    SDL_Delay(50);
  }

  SDL_FreeSurface(artwork);
  SDL_FreeSurface(screen);
  SDL_Quit();
 
  return EXIT_SUCCESS;
}
/*

      Créé l'image dans le buffer à partir de la carte

*/
void ShowMatrix(unsigned char *MatrixedMap, SDL_Surface *screen, SDL_Surface *artwork)
{
  int i=0, x=0, y=0, index=0, style=0;
  char *ptr;

  // Raz du buffer
  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,0,0));
  while(i<MAP_S)
  {
    ptr = MatrixedMap + i;
    if(*ptr>2)
    {
      x=i%MAP_W * GLYPH_W;
      y=i/MAP_W * GLYPH_W;
      style = (*ptr<CL_DRKR)?3:((*ptr<CL_DRK)?2:((*ptr<CL_LGH)?1:0));
      index = rand() % 10;
      GlyBlit(x, y, index, style, screen, artwork);
    }
    i++;
  }

}

/*

      Fait évoluer la carte

*/
void Iteration(unsigned char *MatrixedMap)
{
  int i=MAP_S;
  char *ptr;
  while(i>0)
  {
    ptr = MatrixedMap + i;
    if(*ptr)
    {
      if((i + MAP_W ) < MAP_S )
      {    
        if(*ptr)
        {
          *(ptr + MAP_W)=*ptr;
        }
      }
      *ptr = *ptr-1;
    }
    i--;
  }
}

/*

      Créé un "BEACON" (coordonnée alléatoire)

*/
void NewBeacon(char zone, unsigned char *MatrixedMap, char type)
{
  int ptr = rand() % ((zone>0)?MAP_S:MAP_W);
   *(MatrixedMap+ptr)= type;
}

void GlyBlit(int x, int y, int index, int style, SDL_Surface *artwork, SDL_Surface *dst)
{
  SDL_Rect GlyClip = {index*GLYPH_W,style*GLYPH_W,GLYPH_W,GLYPH_W};
  SDL_Rect GlyPos = {x ,y ,0 ,0 };
  SDL_BlitSurface(dst, &GlyClip, artwork, &GlyPos);
}

voilà!

dimanche 1 août 2010

[INFO] Interpréteur

[ Partager : Partager sur Digg ]
Information de parcour J'ai trouvé un nom et une charte graphique pour mon langage de programmation. Je suis entrain de faire un site de présentation/téléchargement. Plus de nouvelles d'ici peu!

mercredi 28 juillet 2010

Mon interpréteur BrainFuck perso

[ Partager : Partager sur Digg ]
Salutations!

Pour ceux qui ne connaissent pas ce merveilleux langage de programmation, il y a dans la note précédente, quelques exemples de code brainfuck. Le brainfuck, conceptuellement, c'est trop cool. Un seul registre, un jeu d'instruction tres réduite, et une utilisation tres proche des systèmes logiques. Et bien, en attendant d'avoir le courage de bidouiller un ordinateur brainfuck, j'ai décidé de coder ma propre version de ce langage!

Voilà, donc j'ai commencé par programmer un interpréteur simple, qui supportait toutes les instructions du brainfuck, pour ensuite le modifier. J'ai déjà implémenté deux ou trois fonctionnalités tres pratiques qui rendent bien service, comme le support des boucles imbriquées, et un incrément numérique des valeur du registres. Prochain étape, l'adressage "direct" du registre. Finalement, ça va s'apparenter à ce que je voulais faire (voir le billet sur mes projets en cours). Le brainfuck est vraiment tout indiqué, et est bien plus facile à interpréter que le BASIC (la conversion "langage->code" c'est trop la merde, et ca dépends trop de la finalité.).

Là, je pense être sur la bonne voie pour créer un langage pratique, rétro-compatible (il peut interpréter un code brainfuck), et léger (moins de répétitions, interpréteur simple=bug--). Je vais poster le code source de l'interpréteur, sous licence GPL (of course) et le langage lui même aussi j'espère.

Et bon surf!

lundi 26 juillet 2010

It's BrainFucking time !

[ Partager : Partager sur Digg ]
Salutations!

Grace à TimGau, qui a posté une de ses sources BrainFuck sur le réseau social totalitaire et bleu, j'ai eu le plaisir de re-goûter à ce merveilleux langage qu'est le BrainFuck. J'ai alors demandé à mon entité cérébrale nerd de me remettre en RAM les vicissitudes de ce dernier. Quel miracle, un langage si simple, et si poétique à la fois! Il regorge de concepts tout à fait intéressants d'ailleurs.

Pour rappel, le brainfuck permet de manipuler UN registre, d'afficher la valeur d'une cellule de ce registre, et de demander la saisie d'une valeur de cellule. Il dispose aussi de la formidable "[]" qui est une boucle conditionnelle.

Quelque petits codes BrainFuck

Signature Brainfuck
+++++ +++++ +++++ ++++
[>+++++<-]
+++[>----<-]>+.
<+++[>+++++++<-]>.     
<+++[>+++++<-]>.
<+++[>----<-]>.
<++[>---<-]>-.
++.
--..
<++[>+++<-]>.
Un petit compte à rebours avec retour-chariot
>+++++ +++
[<+++++ ++>-]<+
>>+++
[<+++>-]<+
>++++++++++.<
[<.->->.<]
Et son homologue, le compteur
>+++++ +++
[<+++++ +>-]<
>>+++
[<+++>-]<+
>++++++++++.<
[<.+>->.<]
Un petit programme mignon tout plein pour les sensibleries geekesques:
>++++++++++
[>+++++++<-]>+++.
<++[>-----<-]>---.
<++[>-----<-]>+.
<++++[>++++++++<-]>++.

Hm... Et c'est tout pour le moment. Je vais avoir le temps de brainfucker, je vous tiens au courant!

Coder les fonctions usuelles des librairies standard du C

[ Partager : Partager sur Digg ]
Salutations.

Souvent, quand on est amené à manipuler de la mémoire en C, par exemple, lors que l'on a des chaines de caractères, ou que l'on doit analyser une structure "complexe" de données (images, etc...), on aimerait pouvoir résoudre de petits problèmes simples avec élégance... Si les librairies standard offrent de bons moyens de ne pas avoir à savoir coder, il est en revanche un constat accablant à faire: apprendre à bien coder éviteraient parfois de belles bourdes.

Je n'ai pas la prétention d'avoir des leçons a donner. Mais finalement, pourquoi ne pas diffuser un peut ce qui me semble utile?

Je propose donc de donner quelques exemples commentés de fonctions usuelles codées dans un style élégant, qui pourraient vous permettre d'enfin apprécier de faire un code découlant d'une logique implacable. Et le code logique et pur, c'est beau.

Strlen

strlen (string lenght) est une fonction définie dans le header de la librairie standard string.h, et ayant pour prototype "size_t strlen(const char *s);". Son role est de renvoyer la taille d'une chaine de caractères (nombres de caractères contenus dans la chaine). Une chaine correspond en réalité à un pointeur, donnant accès à une plage de caractères, et dont la fin est déterminée par un \0 (valeur à 0). Le pointeur donne l'emplacement mémoire du premier caractère de la chaine.

Comme je le disait plus haut, le C permet une manipulation de la mémoire très propre, et bien intégrée. On pourra donc coder notre fonction de strlen en utilisant les pointeurs et leur syntaxe:


/* (c)Tixlegeek 2010 - GPLv3  */
int strlen(char *str)
{
   int i=0;
   while(*(str+i)){i++;}
   return i;
}

Malgré qu'il puisse etre un peut intimidant pour les débutants (et c'est normal, ya des pointeurs :) ) on peut aisément l'expliquer et le comprendre:


int strlen(char *str)
{
   int i=0;   Déclaration de la variable i et initialisation à 0
   while(*(str+i)){i++}  Tant que la valeur *(str+i) (=valeur à l'adresse str+i) est supérieure à 0, on incrémente i.
   return i;   On est arrivé à un 0, on retourne donc la valeur de i, qui correspond au nombre de caracteres parcouru dans la boucle précédente.
}

ltrim

OOPS! L'ami Mathedit m'a fait remarqué à juste titre que ma fonction ne marchait pas! (je flagellerai ma chaire impure avec une courge molle ce soir, c'est promis) Et m'en a fait la démonstration. Je ne suis pas encore certain des circonstances du bug, mais à l'évidence, ca plante. Ce n'est que partie remise! Et merci à mathedit

Voilà. Ces deux fonctions permettent de comprendre un peut mieux l'utilité des pointeurs, et en quoi ils peuvent nous changer la vie. Ce ne sont que des exemples, mais le haut niveau n'empêche pas d'avoir à savoir programmer un minimum!

mardi 23 février 2010

Wiimote et OpenGL en C sous GNU/Linux

[ Partager : Partager sur Digg ]
Salutations !
wiimote en C wiimote en C wiimote en C

Il ya quelques temps, j'aivais réalisé en une matinée, un petit programme qui utilisait la wiimote et OpenGL pour faire bouger des mobiles en 3D avec l'accéléromètre de la wiimote. J'avais fait ça juste avant mon exposé sur "la contre culture du détournement logiciel et matériel" (Les Hackers en réalité)

J'ai enfin pris le temps de réaliser une petite vidéo pour vous montrer mon petit bricolage !

Voilà! J'utilise donc les librairies OpenGL, SDL, Et LibcWiid, et compile mon code sous GCC. Je le posterai bientot je pense.

mercredi 13 mai 2009

La citation du jour : Le code source

[ Partager : Partager sur Digg ]
Salutations

Suite au commentaire de Gaspard sur l'article dédié précédent, voilà l'archive contenant le code source et le projet CodeBlocks. Il est distribué sous licence GPL, ne contient qu'un seul fichier source, et, je le rappel, utilise les librairies GTK+ et Libcurl.

Récupérer l'archive en tar.gz

++ Tix.

mercredi 29 avril 2009

La citation du jour

[ Partager : Partager sur Digg ]
Salutation !

Voilà mon dernier programme : "La citation du jour". Il s'agit d'une application, pour le momment uniquement disponible pour GNU/linux, qui, à chaque lancement, se connecte à mon serveur de citations aléatoires (écrit en PHP dans la foulée) et l'affiche.

J'ai utilisé la librairie Libcurl, une librairie réseau tres sympathique, et un interfacage graphique GTK+. Le code, lui, à été compilé avec GCC, sous Code::blocks IDE, et sera bientot publié. Je n'ai aucune envie de faire une version Windows, mais, qui sait !

++ Tix. !

jeudi 11 décembre 2008

Developpement -> LowBrainBasicInterpreter [0.0.2]

[ Partager : Partager sur Digg ]

Voilà le dernier sample de mon interpréteur basic. Ajout d'une fonction Ltrim, et d'une fonction d'analyse plus poussée du code. Optimisation des fonctions précédentes. J'ai aussi revu un peu ma syntaxe, et j'ai décidé de m'orienter un peu plus vers un basic qui tourne un peu comme celui des TI. En effet, il permet de bien gérer les imbrications de boucles, et de ne pas s'embêter avec de drôles de choses qui consomment de la mémoire ! Vous constaterez aussi que par le fait, le codage est bien plus libre espaces superflus gérés etc...)
TODO: le reste u___u

/*****************************************************************************************


                                  BASIC interpreter
                                (PIC2PC - simulateur)
                                        0.0.2


          By Gery DUBIEF, www.tixlegeek.com, tixlegee AT gmail DOT com

          Code à compiler exclusivement avec GCC. Non compatible WINDOWS

*****************************************************************************************

            -> L'intégralité de ce code est sous license GPL. Rapportez vous au
            site ci dessous pour connaître les conditions exactes de la license.

                            http://www.gnu.org/copyleft/

*****************************************************************************************/
#include <stdio.h>
#include <stdlib.h>

/*****************************************************************************************
                            Reperes de lignes
*****************************************************************************************/
#define LBB_RCCHAR 59
#define LBB_STOPCHAR 0

//Domaine de définition ASCII des variables
#define LBB_SVDEF 65
#define LBB_EVDEF 90

/*****************************************************************************************
                            Index d'instruction
*****************************************************************************************/
#define LBBI_IF 100
#define LBBI_FOR 101

#define LBBI_ELSE 110
#define LBBI_GOTO 111
/*****************************************************************************************
                            Macros du simulateur
*****************************************************************************************/

// Affiche un retour chariot
#define LBB_NRC()   printf("\033[30m"); \

                    printf("\033[43m"); \
                    printf("[RC]"); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un début de conditionnelle IF
#define LBB_NCIS(stackind)   printf("\033[34m"); \

                    printf("\033[40m"); \
                    printf("{%d\t[Debut de conditionelle IF]", stackind); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un début de conditionnelle FOR
#define LBB_NCFS(stackind)   printf("\033[31m"); \

                    printf("\033[40m"); \
                    printf("{%d\t[Debut de conditionelle FOR]", stackind); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche une fin de conditionelle
#define LBB_NCE(stackind)   printf("\033[35m"); \

                    printf("\033[40m"); \
                    printf("}%d\t[Fin de conditionelle END]", stackind); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un goto
#define LBB_NCG()   printf("\033[36m"); \

                    printf("\033[40m"); \
                    printf("--> \t<GO TO>"); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un titre
#define LBB_NTI(titre)   printf("\033[30m"); \

                    printf("\033[47m"); \
                    printf("-------------------- [ %s ] --------------------", titre); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");

// Affiche un texte
#define LBB_CTS(txt,b,f)   printf("\033[3%dm",f); \

                    printf("\033[4%dm",b); \
                    printf("%s", txt); \

                    printf("\033[37m"); \
                    printf("\033[40m");

// Affiche un caractere
#define LBB_CTC(txt,b,f)   printf("\033[3%dm",f); \

                    printf("\033[4%dm",b); \
                    printf("%c", txt); \

                    printf("\033[37m"); \
                    printf("\033[40m");

// Affiche une erreur
#define LBB_NERR(errtxt)   printf("\033[31m"); \

                    printf("\033[40m"); \
                    printf("[ERROR] : %s ", errtxt); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");

/*****************************************************************************************
                            Typedefs
*****************************************************************************************/
typedef struct

{
	int index;  // Adresse ligne
	int argstart;

	int ctype;  // Type
	int branch; // Accord de goto

} LBB_CodeLine;

/*****************************************************************************************
                    Contenu de l'eeprom, normalement externe au programme.

                    Toutes les instructions de lectures de cette varibale devront
                    interragir avec le périphérique de support dirrectement.
*****************************************************************************************/
char ProgBuffer[] = "A=0 ; for B, 1, 10;A=A+1 ;if A<=10 ;  goto 3;end ; A=A - 1; if A>=1;goto 7; end ;end ;B=78; C=D ;";

int             LBB_LineCursor = 0;             // Curseur de lecture
int             LBB_LineUltimate = 0;           // Nombre de lignes

LBB_CodeLine    LBB_LineIndex[1024];            // Index des Lignes
int             LBB_ConditionalStack[10];       // Pile de repérage des branchements

/*****************************************************************************************
                            Déclaration des fonctions
*****************************************************************************************/
int LBB_strlen(char *str);
int LBB_strstr(char *str1, char *str2);

int LBB_InitConditionnal();
int LBB_Init();
int LBB_Execut(int LBB_LineToEx);

int LBB_Ltrim(char *str, int offset);
/*****************************************************************************************
                            Fonctions
*****************************************************************************************/

/*****************************************************************************************
                        Découpe et cartographie les lignes de script

                        les ";" actuels seront transcrit comme caracteres
                        spéciaux (habituellement \n, codé 15) dans l'eeprom.
*****************************************************************************************/
int LBB_Init()
{
    LBB_NTI("Initialisation de la trame de code");

    int i=0, j=1;
    while(ProgBuffer[i] != LBB_STOPCHAR)

    {
        if(ProgBuffer[i] == LBB_RCCHAR)

        {
            j++;
            LBB_Ltrim(ProgBuffer, i+1);

            LBB_LineIndex[j].index = i+1;
            LBB_NRC();

        }
        else
        {
            printf("%c", ProgBuffer[i]);

        }
        i++;
    }
    LBB_LineUltimate = j;

    printf("\nNombre de lignes : %d \n", LBB_LineUltimate);
    return(0);

}

/*****************************************************************************************
                            Cartographie de l'arbre conditionel
*****************************************************************************************/
int LBB_InitConditionnal()
{
    LBB_NTI("Analyse des conditionelles");

    int i=0, j=1, charindex = 1, LBB_ConditionalStackIndex = 0;

    char LBB_InstructionBuffer[30];
    for(i = 1 ; i <= LBB_LineUltimate-1 ; i++)

    {
        charindex = 0;
        printf("Ligne n° %d : instruction ", i);

        for(j=LBB_LineIndex[i].index; j<=LBB_LineIndex[i+1].index; j++)

        {

            if(ProgBuffer[j] == 32 || ProgBuffer[j] == 59 || ProgBuffer[j] == 61)

            {
                LBB_InstructionBuffer[charindex] = 0;
                LBB_LineIndex[i].argstart = LBB_strlen(LBB_InstructionBuffer);                // Inscription de l'offset de lecture pour

                break;
            }
            else
            {
            LBB_InstructionBuffer[charindex] = ProgBuffer[j];

            charindex++;
            }
        }



                                                 // les arguments

        printf("%s \t\t(offset de lecture : %d) \n",LBB_InstructionBuffer, LBB_LineIndex[i].argstart);

        if(LBB_strstr(LBB_InstructionBuffer, "if")==1)

        {
            LBB_ConditionalStackIndex ++;                                               // Ajout d'une adresse au STACK conditionel
            LBB_ConditionalStack[LBB_ConditionalStackIndex] = i;                        // pour les retours

            LBB_LineIndex[i].ctype = LBBI_IF;
            LBB_NCIS(LBB_ConditionalStackIndex);

        }
        if(LBB_strstr(LBB_InstructionBuffer, "end")==1)

        {
            LBB_LineIndex[LBB_ConditionalStack[LBB_ConditionalStackIndex]].branch = i;  // Attribution de l'index actuel

            LBB_NCE(LBB_ConditionalStackIndex);                                         // au STACK précedent
            LBB_ConditionalStackIndex --;                                               //

            LBB_LineIndex[i].ctype = LBBI_ELSE;

        }

        if(LBB_strstr(LBB_InstructionBuffer, "for")==1)

        {
            LBB_ConditionalStackIndex ++;                           // Ajout d'une adresse au STACK conditionel
            LBB_ConditionalStack[LBB_ConditionalStackIndex] = i;    // pour les retours

            LBB_LineIndex[i].ctype = LBBI_FOR;
            LBB_NCFS(LBB_ConditionalStackIndex);

        }
/*
        if(LBB_strstr(LBB_InstructionBuffer, "next")==1)
        {
            LBB_LineIndex[LBB_ConditionalStack[LBB_ConditionalStackIndex]].branch = i;  // Attribution de l'index actuel
            LBB_NCE(LBB_ConditionalStackIndex);                                         // au STACK précedent
            LBB_ConditionalStackIndex --;                                               //
            LBB_LineIndex[i].ctype = LBBI_ELSE;

        }
*/

        if(LBB_strstr(LBB_InstructionBuffer, "goto")==1)

        {
            LBB_LineIndex[i].ctype = LBBI_GOTO;
            LBB_NCG();

        }

    }
    if(LBB_ConditionalStackIndex > 0)
    {

        LBB_NERR("Arbre de branchement déséquilibré");
    }
    return(0);

}

/*****************************************************************************************
                                Analyse d'une ligne en vue de l'exécuter
*****************************************************************************************/
int LBB_Execut(int LBB_LineToEx)
{

    // 101 132
    int j=1, charindex;
    char LBB_InstructionBuffer[5],LBB_ArgumentBuffer[30];

        //printf(" >> ligne %d --> argstart: %d, index: %d \n",LBB_LineToEx, LBB_LineIndex[LBB_LineToEx].argstart, LBB_LineIndex[LBB_LineToEx].index);
        /////////////////////////////////////////////////////////////////////////////////////////////
        charindex = 0;

        for(j=LBB_LineIndex[LBB_LineToEx].index; j<= LBB_LineIndex[LBB_LineToEx].index + LBB_LineIndex[LBB_LineToEx].argstart-1; j++)    // Parcour de l'instruction

        {

            LBB_InstructionBuffer[charindex] = ProgBuffer[j];               // Copie dans le Buffer

            charindex++;
        }
        LBB_InstructionBuffer[charindex] = 0;

        /////////////////////////////////////////////////////////////////////////////////////////////
        charindex = 0;
        for(j=LBB_LineIndex[LBB_LineToEx].index + LBB_LineIndex[LBB_LineToEx].argstart; j<= LBB_LineIndex[LBB_LineToEx+1].index-2; j++)    // Parcour des arguments

        {

            LBB_ArgumentBuffer[charindex] = ProgBuffer[j];               // Copie dans le Buffer

            charindex++;
        }
        LBB_ArgumentBuffer[charindex] = 0;

        /////////////////////////////////////////////////////////////////////////////////////////////
        printf("%d#\t",LBB_LineToEx);
        LBB_Ltrim(LBB_ArgumentBuffer, 0);

        //printf("[");
        LBB_CTS(LBB_InstructionBuffer,0,4);
        //printf("][");

        LBB_CTS(LBB_ArgumentBuffer,0,5);

        if(LBB_InstructionBuffer[0] >= LBB_SVDEF && LBB_InstructionBuffer[0] <= LBB_EVDEF)

        {
           printf ("\t\t[Modification du registre ");
           LBB_CTC(LBB_InstructionBuffer[0],0,3);

           printf ("]");
        }
        printf(" \n");

       /* if(LBB_strstr(LBB_InstructionBuffer, "goto")==1)
        {
            LBB_LineIndex[i].ctype = LBBI_GOTO;
            LBB_NCG();
        }*/
    return(0);
}

/*****************************************************************************************
                            Renvoie la taille d'un tableau
*****************************************************************************************/
int LBB_strlen(char *str)
{
    int i=0,  strlen_buffer = 0;

    while(str[i] != 0)
    {

        strlen_buffer++;
        i++;
    }
    return strlen_buffer;

}

/*****************************************************************************************
                            Supprimme les espaces à gauche
                         d'une chaine et renvoie leur nombre
*****************************************************************************************/
int LBB_Ltrim(char *str, int offset)

{
    int i=0, decreased = 0, b;

    while(str[offset] == 32)
    {

        for(i=offset; i<=LBB_strlen(str); i++)

        {
        b = str[i+1];
        str[i] = b;

        }
        decreased++;
    }
    return(decreased);

}

/*****************************************************************************************
                            Compare deux chaines
*****************************************************************************************/
int LBB_strstr(char *str1, char *str2)

{
    int i = 0, strlen_str = LBB_strlen(str1), returned = 1;

    if(strlen_str==LBB_strlen(str2))
    {
        while(i < strlen_str)

        {

            if(str1[i]!=str2[i])

            {
                returned = 0;
            }
            i++;

        }

    }
    else
    {
        returned = 0;

    }
    return returned;

}
/*****************************************************************************************
                            Fonction principale
*****************************************************************************************/
int main()

{
    int i;
    LBB_Init();
    LBB_InitConditionnal();

        LBB_NTI("Exécution");
    for(i=1; i<=LBB_LineUltimate; i++)

    {
        LBB_Execut(i);
    }
    return 0;

}

Et, une fois compilé, ce gros tas de bug donne ca :

++ Tix.

mercredi 10 décembre 2008

Developpement -> LowBrainBasicInterpreter

[ Partager : Partager sur Digg ]
Salutations

Cette semaine, j'ai entrepris le développement d'un petit interpréteur BASIC simple. Le but à terme est de pouvoir l'utiliser dans des systemes embarqués, genre PIC, AVR... pour traiter de petits scripts "clairs", et ce, sans avoir à gérer l'EMI, qui permet d'étendre la mémoire RAM du micro, sur des systèmes amovibles par exemple.

Le la syntaxe du BASIC que j'entreprends de décoder est un genre d'hybride entre le BASIC des micro d'antan, et un assembleur émulé. J'ai choisi cette voie pour des raisons pratique. En effet, si cette solution est plus stricte au niveau du script, elle est bien plus simple à décoder tout en permettant l'interprétation d'instructions très "bas niveau" (gestion de la mémoire plus poussée, registres, pile, etc...)

voilà un exemple de script :

va =0
vb=0
va = va + 1
if va <= 10
goto 3
else
va= va - 1
if va >= 1
goto 7
else
vb = vb + 1
if vb <= 10
goto 4
else

Ce petit morceau de code fait varier la valeur de va une dizaine de fois, de 1 à 10, puis de 10 à 1.

Actuellement, l'interpréteur n'en est qu'à ses balbutiement. Il découpe d'ors et déjà le script en lignes puis dresse une carte du programme et des branchements conditionnels. En effet, tout l'intéret de cet interpréteur est que le code n'est pas copié dans la RAM dans son intégralité, mais uniquement par ligne. Ensuite, en fonction de la carte dressée au préalable, il pourra exécuter telle ou telle ligne. Pour le développement, j'utilise un code qui n'ets pas le code définitif, mais une émulation de ce qui se passerait dans le PIC. Par exemple, le script ne sera pas stocké dans une variable (ca serait en contradiction avec les principes cités plus haut) mais dans un périphérique externe (genre mémoire EEPROM ou FLASH). Deplus, aucun dispositif de monitoring, tout ce qui est en rapport avec l'affichage sera viré au moment opportun.

Voilà le code actuel :

/*****************************************************************************************


                                  BASIC interpreter
                                (PIC2PC - simulateur)
                                        0.0.1


          By Gery DUBIEF, www.tixlegeek.com, tixlegee AT gmail DOT com

          Code à compiler exclusivement avec GCC. Non compatible WINDOWS

*****************************************************************************************

            -> L'intégralité de ce code est sous license GPL. Rapportez vous au
            site ci dessous pour connaître les conditions exactes de la license.

                            http://www.gnu.org/copyleft/

*****************************************************************************************/
#include <stdio.h>
#include <stdlib.h>

/*****************************************************************************************
                            Reperes de lignes
*****************************************************************************************/
#define LBB_RCCHAR 59
#define LBB_STOPCHAR 0

/*****************************************************************************************
                            Index d'instruction
*****************************************************************************************/
#define LBBI_IF 100
#define LBBI_ELSE 101

#define LBBI_GOTO 102
/*****************************************************************************************
                            Macros du simulateur
*****************************************************************************************/
// Affiche un retour chariot
#define LBB_NRC()   printf("\033[30m"); \

                    printf("\033[43m"); \
                    printf("[RC]"); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un début de conditionnelle
#define LBB_NCS(stackind)   printf("\033[33m"); \

                    printf("\033[40m"); \
                    printf("{%d\t[Debut de conditionelle IF]", stackind); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche une fin de conditionelle
#define LBB_NCE(stackind)   printf("\033[33m"); \

                    printf("\033[40m"); \
                    printf("}%d\t[Fin de conditionelle IF]", stackind); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un goto
#define LBB_NCG()   printf("\033[36m"); \

                    printf("\033[40m"); \
                    printf("--> \t<GO TO>"); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche un titre
#define LBB_NTI(titre)   printf("\033[30m"); \

                    printf("\033[47m"); \
                    printf("-------------------- [ %s ] --------------------", titre); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");
// Affiche une erreur
#define LBB_NERR(errtxt)   printf("\033[31m"); \

                    printf("\033[40m"); \
                    printf("[ERROR] : %s ", errtxt); \

                    printf("\033[37m"); \
                    printf("\033[40m"); \

                    printf("\n");

/*****************************************************************************************
                            Typedefs
*****************************************************************************************/
typedef struct

{
	int index;  // Adresse ligne
	int argstart;

	int ctype;  // Type
	int branch; // Accord de goto

} LBB_CodeLine;

/*****************************************************************************************
                    Contenu de l'eeprom, normalement externe au programme.

                    Toutes les instructions de lectures de cette varibale devront
                    interragir avec le périphérique de support dirrectement.
*****************************************************************************************/
unsigned char ProgBuffer[] = "va =0;vb = 0;va = va + 1;if va <= 10;goto 3;else ;va = va - 1;if va >= 1;goto 7;else ;vb = vb + 1;if vb <= 10;goto 4;else ; ;";

int             LBB_LineCursor = 0;             // Curseur de lecture
int             LBB_LineUltimate = 0;           // Nombre de lignes

LBB_CodeLine    LBB_LineIndex[1024];            // Index des Lignes
int             LBB_ConditionalStack[10];       // Pile de repérage des branchements

/*****************************************************************************************
                            Déclaration des fonctions
*****************************************************************************************/
int LBB_strlen(char *str);
int LBB_strstr(char *str1, char *str2);

int LBB_InitConditionnal();
int LBB_Init();
/*****************************************************************************************
                            Fonctions
*****************************************************************************************/

/*****************************************************************************************
                        Découpe et cartographie les lignes de script

                        les ";" actuels seront transcrit comme caracteres
                        spéciaux (habituellement \n, codé 15) dans l'eeprom.
*****************************************************************************************/
int LBB_Init()
{
    LBB_NTI("Initialisation de la trame de code");

    int i=0, j=1;
    while(ProgBuffer[i] != LBB_STOPCHAR)

    {
        if(ProgBuffer[i] == LBB_RCCHAR)

        {
            j++;
            LBB_LineIndex[j].index = i+1;

            LBB_NRC();
        }
        else
        {
            printf("%c", ProgBuffer[i]);

        }
        i++;
    }
    LBB_LineUltimate = j;

    printf("\nNombre de lignes : %d \n", LBB_LineUltimate);
    return(0);

}

/*****************************************************************************************
                            Cartographie de l'arbre conditionel
*****************************************************************************************/
int LBB_InitConditionnal()
{
    LBB_NTI("Analyse des conditionelles");

    int i=0, j=1, charindex = 1, LBB_ConditionalStackIndex = 0;

    char LBB_InstructionBuffer[30];
    for(i = 1 ; i <= LBB_LineUltimate-1 ; i++)

    {
        charindex = 0;
        printf("Ligne n° %d : instruction ", i);

        for(j=LBB_LineIndex[i].index; j<=LBB_LineIndex[i+1].index; j++)

        {
            if(ProgBuffer[j] == 32)

            {
                LBB_InstructionBuffer[charindex] = 0;
                break;

            }
            LBB_InstructionBuffer[charindex] = ProgBuffer[j];

            charindex++;

        }

        LBB_LineIndex[i].argstart = LBB_strlen(LBB_InstructionBuffer)+1;  // Inscription de l'offset de lecture poue

                                                                        // les arguments
        printf("%s \t\t(offset de lecture : %d) \n",LBB_InstructionBuffer, LBB_LineIndex[i].argstart);

        if(LBB_strstr(LBB_InstructionBuffer, "if")==1)

        {
            LBB_ConditionalStackIndex ++;                           // Ajout d'une adresse au STACK conditionel
            LBB_ConditionalStack[LBB_ConditionalStackIndex] = i;    // pour les retours

            LBB_LineIndex[i].ctype = LBBI_IF;
            LBB_NCS(LBB_ConditionalStackIndex);

        }
        if(LBB_strstr(LBB_InstructionBuffer, "else")==1)

        {
            LBB_LineIndex[LBB_ConditionalStack[LBB_ConditionalStackIndex]].branch = i;  // Attribution de l'index actuel

            LBB_NCE(LBB_ConditionalStackIndex);                                         // au STACK précedent
            LBB_ConditionalStackIndex --;                                               //

            LBB_LineIndex[i].ctype = LBBI_ELSE;

        }

        if(LBB_strstr(LBB_InstructionBuffer, "goto")==1)

        {
            LBB_LineIndex[i].ctype = LBBI_GOTO;
            LBB_NCG();

        }

    }
    if(LBB_ConditionalStackIndex > 0)
    {

        LBB_NERR("Arbre de branchement déséquilibré");
    }
    return(0);

}
/*****************************************************************************************
                            Renvoie la taille d'un tableau
*****************************************************************************************/
int LBB_strlen(char *str)
{

    int i=0,  strlen_buffer = 0;
    while(str[i] != 0)

    {
        strlen_buffer++;
        i++;
    }

    return strlen_buffer;
}
/*****************************************************************************************
                            Compare deux chaines
*****************************************************************************************/
int LBB_strstr(char *str1, char *str2)

{
    int i = 0, strlen_str = LBB_strlen(str1), returned = 1;

    if(strlen_str==LBB_strlen(str2))
    {
        while(i < strlen_str)

        {

            if(str1[i]!=str2[i])

            {
                returned = 0;
            }
            i++;

        }

    }
    else
    {
        returned = 0;

    }
    return returned;

}
/*****************************************************************************************
                            Fonction principale
*****************************************************************************************/
int main()

{
    LBB_Init();
    LBB_InitConditionnal();
    return 0;

}

Et, une fois compilé, ce gros sac de noeud donne ca :

Plus d'infos dans les semaines à venir.

Creative Commons License
Les travaux signés "Tixlegeek" by DUBIEF Gery sont mis à disposition selon les termes de la licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique 2.0 France.

Pour toute modifications apportées, ou diffusion, merci de mentionner l'auteur d'origine, et l'adresse de ce blog.