variable.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * File: variable.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 21 décembre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "str.h"
  10. #include "expreg.h"
  11. #include "variable.h"
  12. /* --- Fonctions publiques --- */
  13. char* parse_var(char* s, subdiv* sd, char* mem) {
  14. expreg er;
  15. int length, deb, fin, fin2 = 0, compteur = 0, index = 0;
  16. boolean first = true;
  17. char* str, * newstr;
  18. //Cherche le nombre de clefs dans la chaine
  19. length = strlen(s);
  20. ini_expreg(&er, s, "(\\$[[:alnum:]_]+)");
  21. while ((str = get_match_expreg(&er, &deb, &fin)) != NULL) {
  22. //1er tour
  23. if (first) {
  24. //Si il y a du texte avant
  25. if (deb != 0) {
  26. compteur++;
  27. }
  28. compteur++;
  29. //Garde en memoire la pos de fin
  30. fin2 = fin;
  31. first = false;
  32. }
  33. //Autre tours
  34. else {
  35. //Si il y a eu du texte entre les deux correspondances
  36. if (deb != fin2) {
  37. compteur++;
  38. }
  39. compteur++;
  40. //Garde en memoire la pos de fin
  41. fin2 = fin;
  42. }
  43. free(str);
  44. }
  45. //Si on n'est pas à la fin
  46. if (fin2 != length) {
  47. compteur++;
  48. }
  49. clean_expreg(&er);
  50. //Création tableau
  51. char** tab = malloc(sizeof(char*) * compteur);
  52. //Sécoupe la chaine
  53. first = true;
  54. ini_expreg(&er, s, "(\\$[[:alnum:]_]+)");
  55. while ((str = get_match_expreg(&er, &deb, &fin)) != NULL) {
  56. //1er tour
  57. if (first) {
  58. //Si il y a du texte avant
  59. if (deb != 0) {
  60. tab[index] = malloc(sizeof(char) * (deb + 1));
  61. memset(tab[index], 0, deb + 1);
  62. strncpy(tab[index], s, deb);
  63. index++;
  64. }
  65. tab[index] = malloc(sizeof(char) * (fin - deb + 1));
  66. memset(tab[index], 0, fin - deb + 1);
  67. strncpy(tab[index], s + deb, fin - deb);
  68. index++;
  69. //Garde en memoire la pos de fin
  70. fin2 = fin;
  71. first = false;
  72. }
  73. //Autre tours
  74. else {
  75. //Si il y a eu du texte entre les deux correspondances
  76. if (deb != fin2) {
  77. tab[index] = malloc(sizeof(char) * (deb - fin2 + 1));
  78. memset(tab[index], 0, deb - fin2 + 1);
  79. strncpy(tab[index], s + fin2, deb - fin2);
  80. index++;
  81. }
  82. tab[index] = malloc(sizeof(char) * (fin - deb + 1));
  83. memset(tab[index], 0, fin - deb + 1);
  84. strncpy(tab[index], s + deb, fin - deb);
  85. index++;
  86. //Garde en memoire la pos de fin
  87. fin2 = fin;
  88. }
  89. free(str);
  90. }
  91. //Si on n'est pas à la fin
  92. if (fin2 != length) {
  93. tab[index] = malloc(sizeof(char) * (length - fin2 + 1));
  94. memset(tab[index], 0, length - fin2 + 1);
  95. strncpy(tab[index], s + fin2, length - fin2);
  96. index++;
  97. }
  98. clean_expreg(&er);
  99. //Remplace les clef par leurs valeurs
  100. for(int i = 0; i < compteur; i++){
  101. if(tab[i][0] == '$'){
  102. char* val = get_data_subdiv(sd, mem, tab[i] + 1);
  103. if(val != NULL){
  104. free(tab[i]);
  105. tab[i] = val;
  106. }
  107. }
  108. }
  109. //Reconstruit la chaine
  110. length = 0;
  111. for(int i = 0; i < compteur; i++){
  112. length += strlen(tab[i]);
  113. }
  114. newstr = malloc(sizeof(char) * (length + 1));
  115. memset(newstr, 0, length + 1);
  116. index = 0;
  117. for(int i = 0; i < compteur; i++){
  118. length = strlen(tab[i]);
  119. for(int j = 0; j < length; j++){
  120. newstr[index] = tab[i][j];
  121. index++;
  122. }
  123. free(tab[i]);
  124. }
  125. free(tab);
  126. return newstr;
  127. }