LeeWee petit language interprété en C

Rédigé par BeHuman 1 commentaire
Classé dans : C/C++ Mots clés : c, leewee, langage, interprété, variable, cgi

Salut à tous,

Cela fait quelques semaine que je me suis lancer pleinement dans l'apprentissge du langage C. Comme pour le FreePascal, Python, Bash...etc je me suis amusé à dévelloper un petit langage interprété histoire de rentré pleinement au cours du langage en question.

LeeWee est mon petit projet de langage interprété que j'adapte suivant mes lubbies du moment. 

Actuellement orienté sur le développement web LeeWee doit pouvoir au minimum:

  1. attribuer des variables
  2. retourner des variables dans du contenue au format HTML

Bon, je dois l'avouer pour le moment cela reste très sommaire.

Attribuer une variable:

$title=salut le monde

Retour une variable dans du HTML:

<html>
    <head>
        <title>$[title]</title>
    </head>
    <body>
    </body>
</html>

ok, jusque là rien de bien compliqué.

Nous avons la possibilité d'éxécuter une commande terminal et la stocké dans une variable.

$ip=<?ifconfig | grep 'inet adr' | cut -d: -f2 | cut -d' ' -f1?>

donc en toute logique vous pourrez executer du code python,perl,php...etc de la même manière

$python= <?python -c "print(\"$[title], it is a python script !\")
a=1
b=2
if a==2:
    print(\"OK\")
else:
    print(\"NO\")"
?>

Comme vous pouvez le constater on peut aussi inclure les variables LeeWee directement dans vos commande terminal là la variable $[title].

Exemple de script LeeWee:

#! ./lw

$ii=aa
$ipa=<?ifconfig | grep 'inet adr' | cut -d: -f2 | cut -d' ' -f1?>
$ifconfig=<?/sbin/ifconfig?>
$lspci = <?lspci?>
$lsusb = <?lsusb?>
$title = Welcome

$python1= <?python -c "print(\"$[title], it is a python script !\")
a=1
b=2
if a==2:
    print(\"OK\")
else:
    print(\"NO\")"
?>

$perl = <?perl -e "print '$[title] in LeeWee'"?>
$welcome = Welcome in LeeWee script
$a=1
$b=$[a]


<html>
    <head>
        <title>$[perl]</title>
    </head>
    <body>
        <h1>$[welcome]</h1>
        <form method="POST" enctype="multipart/form-data">
            <strong>Exemple formulaire POST :</strong><br>
            Text :<input type="text" name="txt_post" value=""><br>
            Fichier :<input type="file" name="file_post" value=""><br>
            <input type="submit" value="Valider">
        </form><br>
        
        <form method="GET">
            <strong>Exemple formulaire GET :</strong><br>
            Text :<input type="text" name="txt_get" value=""><br>
            Text2 :<input type="text" name="txt2_get" value=""><br>
            <input type="submit" value="Valider">
        </form><br>
        
        <strong>IP :</strong><br>
        $[ipa]
        <br><br>
        
        <strong>IFCONFIG :</strong><br>
        $[ifconfig]<br><br>
        
        <strong>LSPCI :</strong><br>
        $[lspci]<br><br>
        
        <strong>LSUSB :</strong><br>$[lsusb]<br><br>
        
        $[ls]
        
        <br><br>
        <strong>Variable d'environnement 'LS_COLORS' :</strong><br>
        $[LS_COLORS]
        <br><br>
        <strong>Variable d'environnement 'QUERY_STRING' :</strong><br>
        $[QUERY_STRING]
        <br><br>
        
        #modification de la variable $ls
        $ls=<?echo "modification de la variable \$ls<br><br>"?>
        $[ls]
        if($[a]=$[b]){
            <br><strong>condition 1 True Line 1</strong><br><br>
            if($[a]!=$[b]){
                <br><strong>condition 2 True Line 1</strong>
                <br><strong>condition 2 True Line 2</strong><br><br>
            }else{
                <br><strong>condition 2 False Line 1</strong><br>
                if($[a]=$[b]){
                    <br><strong>condition 3 True Line 1</strong>
                    <br><strong>condition 3 True Line 2</strong><br>
                    $ls=RE-modification de la variable $ls<br><br>
                    $[ls]
                }else{
                    <br><strong>condition 3 False Line 1</strong>
                    <br><strong>condition 3 False Line 2</strong><br><br>
                }
                <br><strong>condition 2 False Line 2</strong><br><br>
            }
        }else{
            <br><strong>condition 1 False Line 1</strong><br><br>
        }

        <br><br>
        $[python1]
    </body>
</html>

CODE SOURCE

main.c

#define _GNU_SOURCE
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <regex.h>

#define LG_MAX 40960

static char *ENV[LG_MAX];

#include "regex.c"
#include "regex_const.c"
#include "str.c"
#include "console.c"
#include "variables.c"

#include "tokens.h"



int main(int argc, char *argv[], char *envp[]) {
    char c;
    int i;
    char *tmp = (char *)malloc(sizeof(char) * LG_MAX);

    char *ligne_courante = (char *)malloc (sizeof(char) * LG_MAX);
     
    int ctmp=0;
    int multiline=0;
    int pstr=-1;
    char *tmp_tmp = (char *)malloc(sizeof(char) * LG_MAX);
    char *tmp_tmp_tmp = (char *)malloc(sizeof(char) * LG_MAX);
    int display_var=0;
    char *var_name=(char *)malloc (sizeof (char) * LG_MAX);
    char *var_value;
    
    int pos_html=0;
    int condition=0;
    int condition_count=-1;
    int condition_etat=-1;
    char **tableau_value = NULL;
    int CONDITION[LG_MAX];

    
   
    FILE *SCRIPT = fopen (argv[1], "r");
    if (SCRIPT) { 
        while(fgets(ligne_courante, LG_MAX, SCRIPT) != NULL) {
            for(i=0;i<=strlen(ligne_courante);i++) {
                c= ligne_courante[i];
                switch(c) {
                    case '\n': 
                        if (display_var<2) display_var=0;
                        //si ça ne commence pas par # (commentaire) alors...
                        if ( ((tmp[0] != '#' && multiline==0) || (multiline==1)) && (tmp[0] != 0) ) {
                            /*si la ligne vaut $var=<? cmd ?>*/
                            if ((regex_match_const(tmp,TOKEN_VAR_1)==0 || regex_match_const(tmp,TOKEN_VAR_2)==0) && (multiline==0) && (condition_etat!=1)){
                                var_name=regex_const(regex_const(tmp,TOKEN_VAR_NAME_1),TOKEN_VAR_NAME_2);
                                tmp_tmp=regex(tmp,"(<\\?.*\\?>$)");
                                tmp_tmp=str_replace(tmp_tmp,0,2,"");
                                pstr=str_istr(tmp_tmp,"?>");
                                tmp_tmp=str_replace(tmp_tmp,pstr,2,"");
                                var_value=shell(tmp_tmp);
                                libererVariable(mes_variables, var_name);
                                mes_variables=ajouterVariable(mes_variables, var_name, var_value);

                            /*si la ligne vaut $var=<? cmd*/
                            } else if ((regex_match_const(tmp,TOKEN_VAR_START_1)==0 || regex_match_const(tmp,TOKEN_VAR_START_2)==0) && (multiline==0) && (condition_etat!=1)){
                                tmp_tmp=regex(tmp,"(<\\?.*$)");
                                tmp_tmp=str_replace(tmp_tmp,0,2,"");
                                //printf("%s\033[0m\n",tmp_tmp);
                                strncat(tmp, "\n", 1);
                                multiline=1;

                            /*si la ligne vaut cmd ?>*/
                            } else if (regex_match_const(tmp,TOKEN_VAR_END_1_2)==0 && (condition_etat!=1)){
                                if (regex_match(tmp,"^.*\\?>$")==0 ) {
                                    var_name=regex_const(regex_const(tmp,TOKEN_VAR_NAME_1),TOKEN_VAR_NAME_2);
                                    tmp_tmp=regex(tmp,"(.*\\?>$)");
                                    pstr=str_istr(tmp_tmp,"?>");
                                    tmp_tmp=str_replace(tmp_tmp,pstr,2,"");
                                    pstr=str_istr(tmp_tmp,"<?");
                                    tmp_tmp=str_replace(tmp_tmp,pstr,2,"");
                                    strcpy(tmp_tmp_tmp,tmp_tmp);
                                    tableau_value=str_split(tmp_tmp_tmp, "=");
                                    pstr=str_istr(tmp_tmp, tableau_value[0]);
                                    tmp_tmp=str_replace(tmp_tmp,pstr,strlen(tableau_value[0])+1,"");
                                    var_value=shell(tmp_tmp);
                                    libererVariable(mes_variables, var_name);
                                    mes_variables=ajouterVariable(mes_variables, var_name, var_value);
                                }
                                multiline=0;
                            } else if (multiline==1 && (condition_etat!=1)){
                                strncat(tmp, "\n", 1);

                            /*si la ligne vaut $var=str*/
                            } else if ((regex_match_const(tmp,TOKEN_VAR_3)==0) && (multiline==0) && (condition_etat!=1)){
                                var_name=regex_const(regex_const(tmp,TOKEN_VAR_NAME_1),TOKEN_VAR_NAME_2);
                                tmp_tmp=regex(tmp,"(=.*$)");
                                tmp_tmp=str_replace(tmp_tmp,0,1,"");
                                var_value=tmp_tmp;
                               //printf("##%s == %s\n",var_name,var_value);
                                libererVariable(mes_variables, var_name);
                                mes_variables=ajouterVariable(mes_variables, var_name, var_value);

/*                            } else if ((regex_match(tmp,"^if\\(.*\\)\\{.*\\}else\\{.*\\}$")==0 || regex_match(tmp,"^if\\(.*\\)\\{.*\\}else\\{\\}$")==0) && (condition_etat!=1)){*/
/*                                condition=1;*/
/*                                condition_count++;*/
/*                                printf("\033[31m%d) Si et Sinon et Fin\033[0m\n",condition_count);*/
/*                                condition_count--;*/

                            /*si la ligne vaut if(.*){ */
                            } else if (regex_match_const(tmp,TOKEN_IF_1)==0) {
                                condition=1;
                                if (regex_match(tmp,"\\(.*!=.*\\)")==0){
                                    var_name=str_replace(str_replace(regex(tmp,"(\\(.*!=)"),strlen(regex(tmp,"(\\(.*!=)"))-2,2,""),0,1,"");
                                    var_value=str_replace(str_replace(regex(tmp,"(!=.*\\))"),strlen(regex(tmp,"(!=.*\\))"))-1,1,""),0,2,"");
                                    if (strcmp(var_name, var_value)==0) {
                                        condition_etat=1;
                                        CONDITION[++condition_count]=1;
                                    } else {
                                        condition_etat=0;
                                        CONDITION[++condition_count]=0;
                                    }
                                    
                                } else if (regex_match(tmp,"\\(.*=.*\\)")==0){
                                    var_name=str_replace(str_replace(regex(tmp,"(\\(.*=)"),strlen(regex(tmp,"(\\(.*=)"))-1,1,""),0,1,"");
                                    var_value=str_replace(str_replace(regex(tmp,"(=.*\\))"),strlen(regex(tmp,"(=.*\\))"))-1,1,""),0,1,"");
                                    if (strcmp(var_name, var_value)==0) {
                                        condition_etat=0;
                                        CONDITION[++condition_count]=0;
                                    } else {
                                        condition_etat=1;
                                        CONDITION[++condition_count]=1;
                                    }
/*                                } else if (regex_match(tmp,"\\(.*<.*\\)")==0){*/
/*                                    printf("\033[31m%d) Si <\033[0m\n", condition_count);*/
/*                                } else if (regex_match(tmp,"\\(.*>.*\\)")==0){*/
/*                                    printf("\033[31m%d) Si >\033[0m\n", condition_count);*/
/*                                } else {*/
/*                                    printf("\033[31m%d) Si boolean\033[0m\n", condition_count);*/
                                }
                                
                                
/*                            } else if (regex_match(tmp,"^\\}else\\{\\}")==0 || regex_match(tmp,"^}else\\{.*\\}")==0){*/
/*                                printf("\033[31m%d) Sinon et Fin\033[0m\n", condition_count);*/
/*                                condition_count--;*/
                            } else if (regex_match_const(tmp,TOKEN_ELSE_1)==0 && ((CONDITION[condition_count-1]==0 && condition_count>=0) || condition_count==0) ){
                                //printf("%d\n", condition);
                                if (condition==1 && CONDITION[condition_count]==0 ) {
                                    CONDITION[condition_count]=1;
                                    condition_etat=1;
                                } else {
                                    CONDITION[condition_count]=0;
                                    condition_etat=0;
                                }
                            } else if (regex_match_const(tmp,TOKEN_IF_ELSE_END_1)==0){
                                condition_count--;
                                if (condition_count>=0) {
                                    condition_etat=CONDITION[condition_count];
                                    condition=1;
                                } else {
                                    condition_etat=-1;
                                    condition=0;
                                }
                            } else {
                                if (pos_html<=0) {
                                     printf("Content-type: text/html\n\n");
                                     pos_html=1;
                                }
                                if (condition_etat!=1) printf("%s\n",tmp);
                            }
                        }
                        
                        if (multiline==0) bzero(tmp, LG_MAX);
                        break;
                    case '$':
                        display_var=1;
                        break;
                    case '[':
                        if (display_var==1) {
                            display_var=2;
                            if (strlen(tmp_tmp)>=0) strcpy(tmp_tmp,"");
                        } else {
                            strncat(tmp, &c, 1);
                        }
                        break;
                    case ']':
                        if (display_var==2) {
                            display_var=0;

                            
                            strcat(tmp, afficherVariable(mes_variables, tmp_tmp));
                            //strcat(tmp, getVar(tmp_tmp,VARIABLES, ENV));
                        } else {
                            strncat(tmp, &c, 1);
                        }
                        break;
                    default:
                        if (display_var==1) {
                            display_var=0;
                            strncat(tmp, "$", 1);
                        }

                        if (display_var==2) {
                            strncat(tmp_tmp, &c, 1);
                            continue;
                        } else if (i==0) {
                            if (c==' ' && multiline==0) { ctmp=1; continue; }
                        } else {
                            if (c==' ' && ctmp==1 && multiline==0) continue;
                            ctmp=0;
                        }
                        strncat(tmp, &c, 1);
                        break;
                }
            }
        }
        
        //for(i = 0; envp[i] != NULL; i++) printf("%s<br>\n", envp[i]); 
        
       // afficherListeVariables(mes_variables);
        libererListeVariables(mes_variables);
        free(tmp);
        free(tmp_tmp);
        for(i=0;ENV[i]!=NULL;i++)
            free(ENV[i]);
        printf("\n");
        return 0;
    
    } else {
        printf("LeeWee by David Lhoumaud\nGnu/GPL\n\nUsage : lw <FILENAME>\nExemple : lw index.cgi\n");
        return 0;
    }

}

console.c

void fill_argv(char *tmp_argv);
char * shell(const char * str);

static char *my_argv[LG_MAX];

void fill_argv(char *tmp_argv)
{
    char *foo = tmp_argv;
    int index = 0;
    char ret[LG_MAX];
    bzero(ret, LG_MAX);
    while(*foo != '\0') {
        if(index == 10)
            break;

        if(*foo == ' ') {
            if(my_argv[index] == NULL)
                my_argv[index] = (char *)malloc(sizeof(char) * strlen(ret) + 1);
            else {
                bzero(my_argv[index], strlen(my_argv[index]));
            }
            strncpy(my_argv[index], ret, strlen(ret));
            strncat(my_argv[index], "\0", 1);
            bzero(ret, LG_MAX);
            index++;
        } else {
            strncat(ret, foo, 1);
        }
        foo++;
        /*printf("foo is %c\n", *foo);*/
    }
    my_argv[index] = (char *)malloc(sizeof(char) * strlen(ret) + 1);
    strncpy(my_argv[index], ret, strlen(ret));
    strncat(my_argv[index], "\0", 1);
}

char * shell(const char * str) {
    FILE *in;
    extern FILE *popen();
    char buff[LG_MAX*100];
    char *output=malloc (sizeof (*output) * LG_MAX);
    
    if (strlen(output)>0) strcpy(output,"");
    if (strlen(buff)>0) strcpy(buff,"");
    
    
    if(!(in = popen(str_strip(str), "r"))){
        exit(1);
    }
    strcpy(output,buff);
    int a=0;
    int npos=-1;
    while(fgets(buff, sizeof(buff), in)!=NULL){
        if (a>0) {
            if (a==1 && npos > -1 ) strcat(output,"<br>");
            str_replace_first(buff,"\n", "<br>");
        } else {
            npos=str_istr(buff,"\n");
        }
        str_replace_first(buff,"   ", "&nbsp;");
        strcat(output,buff);
        a++;
    }
    pclose(in);
    return output;
}

str.c

#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef H_STRING
#define H_STRING

#include <string.h>

/* Redefinition des fonctions standards pour un usage futur, par exemple verifier
   la validite des arguments. */
#define str_cpy  strcpy
#define str_ncpy strncpy
#define str_cat  strcat
#define str_ncat strncat
#define str_cmp  strcmp
#define str_ncmp strncmp
#define str_len  strlen
#define str_chr  strchr
#define str_rchr strrchr
#define str_str  strstr
#define str_spn  strspn
#define str_pbrk strpbrk
#define str_tok  strtok

#define LG_MAX 40960

char *str_tolower (const char *);
char *str_toupper (const char *);
int str_istr (const char *, const char *);
char *str_sub (const char *, unsigned int, unsigned int);
char **str_split (char *, const char *);
char *str_join (char *, ...);
char *str_replace (const char *, unsigned int, unsigned int, const char *);
void str_replace_first(char * buffer, char * s, char * by);
char *str_strip (const char *);


#endif /* not H_STRING */


char *str_tolower (const char *ct)
{
  char *s = NULL;

  if (ct != NULL)
  {
    int i;

    s = malloc (sizeof (*s) * (strlen (ct) + 1));
    if (s != NULL)
    {
      for (i = 0; ct[i]; i++)
      {
        s[i] = tolower (ct[i]);
      }
      s[i] = '\0';
    }
  }
  return s;
}

char *str_toupper (const char *ct)
{
  char *s = NULL;

  if (ct != NULL)
  {
    int i;

    s = malloc (sizeof (*s) * (strlen (ct) + 1));
    if (s != NULL)
    {
      for (i = 0; ct[i]; i++)
      {
        s[i] = toupper (ct[i]);
      }
      s[i] = '\0';
    }
  }
  return s;
}

int str_istr (const char *cs, const char *ct)
{
  int index = -1;

  if (cs != NULL && ct != NULL)
  {
    char *ptr_pos = NULL;

    ptr_pos = strstr (cs, ct);
    if (ptr_pos != NULL)
    {
      index = ptr_pos - cs;
    }
  }
  return index;
}

char *str_sub (const char *s, unsigned int start, unsigned int end)
{
  char *new_s = NULL;

  if (s != NULL && start < end)
  {
    new_s = malloc (sizeof (*new_s) * (end - start + 2));
    if (new_s != NULL)
    {
      int i;

      for (i = start; i <= end; i++)
      {
        new_s[i-start] = s[i];
      }
      new_s[i-start] = '\0';
    }
    else
    {
      fprintf (stderr, "Memoire insuffisante\n");
      exit (EXIT_FAILURE);
    }
  }
  return new_s;
}

char **str_split (char *s, const char *ct)
{
  char **tab = NULL;

  if (s != NULL && ct != NULL)
  {
    int i;
    char *cs = NULL;
    size_t size = 1;

    for (i = 0; (cs = strtok (s, ct)); i++)
    {
      if (size <= i + 1)
      {
        void *tmp = NULL;

        size <<= 1;
        tmp = realloc (tab, sizeof (*tab) * size);
        if (tmp != NULL)
        {
          tab = tmp;
        }
        else
        {
          fprintf (stderr, "Memoire insuffisante\n");
          free (tab);
          tab = NULL;
          exit (EXIT_FAILURE);
        }
      }
      tab[i] = cs;
      s = NULL;
    }
    tab[i] = NULL;
  }
  return tab;
}

char *str_join (char *cs, ...)
{
  va_list va;
  const char *ct;
  char *s = NULL;
  size_t size = 0;

  va_start (va, cs);
  while ((ct = va_arg (va, char *)) != NULL)
  {
    void *tmp = NULL;

    size += strlen (ct) + strlen (cs);
    tmp = realloc (s, sizeof (*s) * (size + 1));
    if (tmp != NULL)
    {
      if (s == NULL)
      {
        s = tmp;
        strcpy (s, ct);
      }
      else
      {
         s = tmp;
         strcat (s, cs);
         strcat (s, ct);
      }
    }
    else
    {
      fprintf (stderr, "Memoire insuffisante\n");
      free (s);
      s = NULL;
      exit (EXIT_FAILURE);
    }
  }
  return s;
}

char *str_replace (const char *s, unsigned int start, unsigned int lenght, const char *ct)
{
  char *new_s = NULL;

  if (s != NULL && ct != NULL && start >= 0 && lenght > 0)
  {
    size_t size = strlen (s);

    new_s = malloc (sizeof (*new_s) * (size - lenght + strlen (ct) + 1));
    if (new_s != NULL)
    {
      memcpy (new_s, s, start);
      memcpy (&new_s[start], ct, strlen (ct));
      memcpy (&new_s[start + strlen (ct)], &s[start + lenght], size - lenght - start + 1);
    }
  }
  else
  {
    fprintf (stderr, "Memoire insuffisante\n");
    exit (EXIT_FAILURE);
  }
  return new_s;
}

void str_replace_first(char * buffer, char * s, char * by)
{
    char * p = strstr(buffer, s);
    //char * ret = NULL;
 
    if (p != NULL)
    {
        size_t len_p = strlen(p), len_s = strlen(s), len_by = strlen(by);
 
        if (len_s != len_by)
        {
            /* ajuster la taille de la partie 's' pur pouvoir placer by */
            memmove(p + len_by, p + len_s, len_p);
        }
 
        /* rempacer s par by */
        strncpy(p, by, len_by);
        //ret = buffer;
    }
}

char *str_strip (const char *string)
{
  char *strip = NULL;

  if (string != NULL)
  {
    strip = malloc (sizeof (*strip) * (strlen (string) + 1));
    if (strip != NULL)
    {
      int i, j;
      int ps = 0;

      for (i = 0, j = 0; string[i]; i++)
      {
        if (string[i] == ' ')
        {
          if (ps == 0)
          {
            strip[j] = string[i];
            ps = 1;
            j++;
          }
        }
        else
        {
          strip[j] = string[i];
          ps = 0;
          j++;
        }
      }
      strip[j] = '\0';
    }
    else
    {
      fprintf (stderr, "Memoire insuffisante\n");
      exit (EXIT_FAILURE);
    }
  }
  return strip;
}

variables.c

typedef struct variable variable;
struct variable
{
    char *name;
    char *value;
    struct variable *next;
};
 
typedef variable* llist;

llist mes_variables = NULL;

llist ajouterVariable(llist liste, char *nom, char *valeur)
{
    /* On crée un nouvel élément */
    variable* nouvelElement = malloc(sizeof(variable));
   //printf("%s",valeur);
    /* On assigne la valeur au nouvel élément */
    asprintf(&nouvelElement->name,nom);
    asprintf(&nouvelElement->value,valeur);
    //nouvelElement->name = nom;
    //nouvelElement->value = valeur;
 
    /* On assigne l'adresse de l'élément suivant au nouvel élément */
    nouvelElement->next = liste;
 
    /* On retourne la nouvelle liste, i.e. le pointeur sur le premier élément */
    return nouvelElement;
}

llist libererListeVariables(llist liste)
{
    variable* tmp = liste;
    variable* tmpnxt;
 
    /* Tant que l'on n'est pas au bout de la liste */
    while(tmp != NULL)
    {
        /* On stocke l'élément suivant pour pouvoir ensuite avancer */
        tmpnxt = tmp->next;
        /* On efface l'élément courant */
        free(tmp);
        /* On avance d'une case */
        tmp = tmpnxt;
    }
    /* La liste est vide : on retourne NULL */
    return NULL;
}

llist libererVariable(llist liste, char *nom)
{
    /* Liste vide, il n'y a plus rien à supprimer */
    if(liste == NULL)
        return NULL;
 
    /* Si l'élément en cours de traitement doit être supprimé */
    if(liste->name == nom){
        variable* tmp = liste->next;
        free(liste);
        tmp = libererVariable(tmp, nom);
        return tmp;
    }else{
        liste->next = libererVariable(liste->next, nom);
        return liste;
    }
}

void afficherListeVariables(llist liste)
{
    variable *tmp = liste;
    /* Tant que l'on n'est pas au bout de la liste */
    while(tmp != NULL)
    {
        /* On affiche */
        //printf("$[%s] == %s\n", tmp->name, tmp->value);
        /* On avance d'une case */
        tmp = tmp->next;
    }
}

char * afficherVariable(llist liste,  char *nom)
{
    variable *tmp=liste;
    /* Tant que l'on n'est pas au bout de la liste */
                                
    while(tmp != NULL)
    {
        
        if(strcmp(tmp->name,nom)==0)
        {
            //printf("--%s == %s\n",tmp->name, tmp->value);
            /* Si l'élément a la valeur recherchée, on renvoie son adresse */
            return tmp->value;
        }
        tmp = tmp->next;
    }
    char *env = getenv(nom);
    if (env == NULL) {
        return "";
    } else { return env; }
}




/* Convertit un nombre hexadecimal a deux "chiffres" en un caractere usuel */
char hex2dec(char s0, char s1) {
    int sum;
    if ((s1>=48)&&(s1<=57)) /* chiffre */
        sum=s1-48;
    else /* lettre */
        sum=s1-55;
    if ((s0>=48)&&(s0<=57)) /* chiffre */
        sum+=(s0-48)*16;
    else /* lettre */
        sum+=(s0-55)*16;
    return sum;
}

/* Extrait la chaine de caracteres renvoyee par CGI */
int GetCGIString(char *pszCGIString) {
    char *pszTemp;

    pszTemp=getenv("REQUEST_METHOD");

    if(strcmp(pszTemp,"GET")==0){
        pszTemp=getenv("QUERY_STRING");
        if(strlen(pszTemp)<LG_MAX){
            strcpy(pszCGIString,pszTemp);
            return 1;
        }else{
            printf("Erreur : taille de chaine %zu superieure a la longueur max %d. \n",strlen(pszTemp),LG_MAX);
            return 0;
        }
    }else{
        if(strcmp(pszTemp,"POST")==0){
            if(atoi(getenv("CONTENT_LENGTH"))<LG_MAX){
                scanf("%s",pszCGIString);
                return 1;
            }else{
                printf("Erreur : taille de chaine %d superieure a la longueur max %d. \n",atoi(getenv("CONTENT_LENGTH")),LG_MAX);
                return 0;
            }
        }else{
            printf("Methode CGI non supportee. \n");
            return 0;
        }
    }
}


/* Remplace les "+" et les "%xx" de la chaine CGI */
void CleanCGIString(char *pszString) {
    int iSrc=0; 
    int iDest=0; 
    do {
        while ((pszString[iSrc])&&(pszString[iSrc]!='%'))
            if (pszString[iSrc]!='+')
                pszString[iDest++]=pszString[iSrc++];
            else { 
                pszString[iDest++]=' ';
                iSrc++;
            } 

        if (pszString[iSrc]){
            pszString[iDest++]=hex2dec(pszString[iSrc+1],pszString[iSrc+2]);
            iSrc+=3; 
        }
    } while (pszString[iSrc]);

    pszString[iDest]=0; 
}

/* Decoupe la chaine CGI en ses differents arguments */
int ParseCGIString(char *pszCGIString,char *pszResult) {
    char pszTemp[LG_MAX], *pszString, *pszPointer;
    int iLength;

    iLength=strlen(pszCGIString);
    if(iLength>0 && iLength<LG_MAX){
        pszString=pszCGIString;
        pszPointer=pszTemp;
        if(*pszString!=0){
            if(*pszString=='=' && *(pszString+1)==0){
                pszString++;
                *pszResult=0;
            }
            while(*pszString!='=' && *pszString!='&' && *pszString!=0) *(pszPointer++)=*(pszString++);
            if(*pszString=='=' || *pszString=='&' || (*pszString==0 && pszPointer!=pszTemp)){
                *pszPointer=0;
                pszPointer=pszTemp;
                if(*pszString && !(*pszString=='=' && *(pszString+1)==0)) pszString++;
                CleanCGIString(pszTemp);
                strcpy(pszResult,pszTemp);
            }
        }
        strcpy(pszCGIString,pszString);
        return 1;
    }else{
        if(iLength>0) printf("Erreur : taille de chaine %d superieure a la longueur max %d. \n",iLength,LG_MAX);
        return 0;
    }
}

/* Remplace les '<' et '>' de la chaine en vue de l'affichage dans un browser */
void BeforePrintingCGIString(char *pszString){
    char pszTemp[LG_MAX];
    int iSrc, iDest;

    iSrc=0;
    iDest=0;
    while(pszString[iSrc]!=0 && iDest<LG_MAX){
        while(pszString[iSrc]!='<' && pszString[iSrc]!='>' && pszString[iSrc]!=0 && iDest<LG_MAX)
            pszTemp[iDest++]=pszString[iSrc++];

        if(pszString[iSrc]=='<'){
            iSrc++;
            if(iDest<(LG_MAX-5)){
                pszTemp[iDest++]='&';
                pszTemp[iDest++]='#';
                pszTemp[iDest++]='6';
                pszTemp[iDest++]='0';
            }
        }
        if(pszString[iSrc]=='>'){
            iSrc++;
            if (iDest<(LG_MAX-5)) {
                pszTemp[iDest++]='&';
                pszTemp[iDest++]='#';
                pszTemp[iDest++]='6';
                pszTemp[iDest++]='2';
            }
        }
    }
    pszTemp[iDest]=0;
    strcpy(pszString,pszTemp);
}

regex.c

char * regex (char *str_request, char *str_regex);
int regex_match (char *str_request, char *str_regex);

char * regex (char *str_request, char *str_regex)
{
   int err;
   regex_t preg;
   //const char *str_request = "http://www.developpez.net/forums/index.php";
   //const char *str_regex = "(www\\.[-_[:alnum:]]+\\.[[:lower:]]{2,4})";

/* (1) */
   err = regcomp (&preg, str_regex, REG_EXTENDED);
   if (err == 0)
   {
      int match;
      size_t nmatch = 0;
      regmatch_t *pmatch = NULL;
      
      nmatch = preg.re_nsub;
      pmatch = malloc (sizeof (*pmatch) * nmatch);
      if (pmatch)
      {
/* (2) */
         match = regexec (&preg, str_request, nmatch, pmatch, 0);
/* (3) */
         regfree (&preg);
/* (4) */
         if (match == 0)
         {
            char *site = NULL;
            int start = pmatch[0].rm_so;
            int end = pmatch[0].rm_eo;
            size_t size = end - start;
               
            site = malloc (sizeof (*site) * (size + 1));
            if (site)
            {
               strncpy (site, &str_request[start], size);
               site[size] = '\0';
               return site;
               free (site);
            }
         }
/* (5) */
         else if (match == REG_NOMATCH)
         {
            //printf ("[REGEX] %s n\'est pas une adresse internet valide\n", str_request);
            return "";
         }
/* (6) */
         else
         {
            char *text;
            size_t size;

/* (7) */
            size = regerror (err, &preg, NULL, 0);
            text = malloc (sizeof (*text) * size);
            if (text)
            {
/* (8) */
               regerror (err, &preg, text, size);
               fprintf (stderr, "%s\n", text);
               free (text);
            }
            else
            {
               //fprintf (stderr, "Memoire insuffisante\n");
               exit (EXIT_FAILURE);
            }
         }
      }
      else
      {
         //fprintf (stderr, "Memoire insuffisante\n");
         exit (EXIT_FAILURE);
      }
   }
   //puts ("\nPress any key\n");
/* Dev-cpp */
   //getchar ();
   return (EXIT_SUCCESS);
}

int regex_match (char *str_request, char *str_regex)
{
   int err;
   regex_t preg;

/* (1) */
   err = regcomp (&preg, str_regex, REG_NOSUB | REG_EXTENDED);
   if (err == 0)
   {
      int match;

/* (2) */
      match = regexec (&preg, str_request, 0, NULL, 0);
/* (3) */
      regfree (&preg);
/* (4) */
      if (match == 0)
      {
         //printf ("%s est une adresse internet valide\n", str_request);
         return 0;
      }
/* (5) */
      else if (match == REG_NOMATCH)
      {
         //printf ("% n\'est pas une adresse internet valide\n", str_request);
         return 1;
      }
/* (6) */
      else
      {
         char *text;
         size_t size;

/* (7) */
         size = regerror (err, &preg, NULL, 0);
         text = malloc (sizeof (*text) * size);
         if (text)
         {
/* (8) */
            regerror (err, &preg, text, size);
            fprintf (stderr, "%s\n", text);
            free (text);
         }
         else
         {
            //fprintf (stderr, "Memoire insuffisante\n");
            exit (EXIT_FAILURE);
         }
      }
   }
   return (EXIT_SUCCESS);
}

regex_const.c

char * regex_const (char *str_request, const char *str_regex);
int regex_match_const (char *str_request, const char *str_regex);

char * regex_const (char *str_request, const char *str_regex)
{
   int err;
   regex_t preg;
   //const char *str_request = "http://www.developpez.net/forums/index.php";
   //const char *str_regex = "(www\\.[-_[:alnum:]]+\\.[[:lower:]]{2,4})";

/* (1) */
   err = regcomp (&preg, str_regex, REG_EXTENDED);
   if (err == 0)
   {
      int match;
      size_t nmatch = 0;
      regmatch_t *pmatch = NULL;
      
      nmatch = preg.re_nsub;
      pmatch = malloc (sizeof (*pmatch) * nmatch);
      if (pmatch)
      {
/* (2) */
         match = regexec (&preg, str_request, nmatch, pmatch, 0);
/* (3) */
         regfree (&preg);
/* (4) */
         if (match == 0)
         {
            char *site = NULL;
            int start = pmatch[0].rm_so;
            int end = pmatch[0].rm_eo;
            size_t size = end - start;
               
            site = malloc (sizeof (*site) * (size + 1));
            if (site)
            {
               strncpy (site, &str_request[start], size);
               site[size] = '\0';
               return site;
               free (site);
            }
         }
/* (5) */
         else if (match == REG_NOMATCH)
         {
            //printf ("[REGEX] %s n\'est pas une adresse internet valide\n", str_request);
            return "";
         }
/* (6) */
         else
         {
            char *text;
            size_t size;

/* (7) */
            size = regerror (err, &preg, NULL, 0);
            text = malloc (sizeof (*text) * size);
            if (text)
            {
/* (8) */
               regerror (err, &preg, text, size);
               fprintf (stderr, "%s\n", text);
               free (text);
            }
            else
            {
               //fprintf (stderr, "Memoire insuffisante\n");
               exit (EXIT_FAILURE);
            }
         }
      }
      else
      {
         //fprintf (stderr, "Memoire insuffisante\n");
         exit (EXIT_FAILURE);
      }
   }
   //puts ("\nPress any key\n");
/* Dev-cpp */
   //getchar ();
   return (EXIT_SUCCESS);
}

int regex_match_const (char *str_request, const char *str_regex)
{
   int err;
   regex_t preg;

/* (1) */
   err = regcomp (&preg, str_regex, REG_NOSUB | REG_EXTENDED);
   if (err == 0)
   {
      int match;

/* (2) */
      match = regexec (&preg, str_request, 0, NULL, 0);
/* (3) */
      regfree (&preg);
/* (4) */
      if (match == 0)
      {
         //printf ("%s est une adresse internet valide\n", str_request);
         return 0;
      }
/* (5) */
      else if (match == REG_NOMATCH)
      {
         //printf ("% n\'est pas une adresse internet valide\n", str_request);
         return 1;
      }
/* (6) */
      else
      {
         char *text;
         size_t size;

/* (7) */
         size = regerror (err, &preg, NULL, 0);
         text = malloc (sizeof (*text) * size);
         if (text)
         {
/* (8) */
            regerror (err, &preg, text, size);
            fprintf (stderr, "%s\n", text);
            free (text);
         }
         else
         {
            //fprintf (stderr, "Memoire insuffisante\n");
            exit (EXIT_FAILURE);
         }
      }
   }
   return (EXIT_SUCCESS);
}

tokens.h

/*Déclaration des constante relative à l'analyse syntaxique*/
/*definitions variables*/
const char TOKEN_VAR_1[]="^\\$.*=\\ <\\?.*\\?>$";
const char TOKEN_VAR_2[]="^\\$.*=<\\?.*\\?>$";
const char TOKEN_VAR_3[]="^\\$.*=.*$";
const char TOKEN_VAR_START_1[]="^\\$.*=\\ <\\?.*$";
const char TOKEN_VAR_START_2[]="^\\$.*=<\\?.*$";
const char TOKEN_VAR_END_1_2[]="\\?>$";
/*nom variable*/
const char TOKEN_VAR_NAME_1[]="(^\\$.*=)";
const char TOKEN_VAR_NAME_2[]="([_[:alnum:]]+)";

/*definitions conditions*/
const char TOKEN_IF_1[]="^if\\(.*\\)\\{";
const char TOKEN_ELSE_1[]="^\\}else\\{";
const char TOKEN_IF_ELSE_END_1[]="^\\}";

COMPILATION ET TEST

lancer compile.sh

#! /bin/bash

#sudo service apache2 stop
kill -9 `cat httpserver.pid`
gcc=`gcc main.c -o lw -Wall`
if [[ $? -eq 0 ]] ; then
    ./httpserver.py -p 8080 -P . & 
    echo $! > httpserver.pid
    time ./lw index.cgi
fi

 

Télécharger la source complète

Voilà en espérant que celà soit utile

++

1 commentaire

#1  - Jean.N a dit :

cool, merci pour le partage.
Il est hardcore ton main. Je pense qu'il serait bon de créer des fonction pour l'alléger.

Répondre

Écrire un commentaire

Quelle est la quatrième lettre du mot elc2w6y ?

Fil RSS des commentaires de cet article