KADATH
name_tools.cpp
1 /*
2  Copyright 2017 Philippe Grandclement
3 
4  This file is part of Kadath.
5 
6  Kadath is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Kadath is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Kadath. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "headcpp.hpp"
21 #include "name_tools.hpp"
22 #include "tensor.hpp"
23 namespace Kadath {
24 // Removes the spaces in excess from a string
25 void trim_spaces (char* dest, const char* name) {
26  int in_output = 0 ;
27  int in_input = 0 ;
28  bool inspace = (name[0] == ' ') ? true : false ;
29  bool isspace ;
30 
31  // Get rid of the spaces
32  char auxi[LMAX] ;
33  while (name[in_input]!='\0') {
34  isspace = (name[in_input]==' ') ? true : false ;
35  if ((isspace==false) || ((isspace==true) && (inspace==false))) {
36  auxi[in_output] = name[in_input] ;
37  in_output ++ ;
38  }
39  inspace = isspace ;
40  in_input++ ;
41  }
42 
43  if (auxi[in_output-1]!= ' ') {
44  auxi[in_output] = ' ' ;
45  in_output ++ ;
46  }
47  auxi[in_output] = '\0' ;
48 
49  //Get rid of the parenthesis not needed :
50  int first = 0 ;
51  int last = in_output-2 ;
52  bool doloop = true ;
53 
54  while (doloop) {
55 
56  bool needtodo = (auxi[first]== '(') ? true : false ;
57  if (auxi[last]!=')')
58  needtodo = false ;
59  if (needtodo) {
60  int ninside = 0 ;
61  for (int i=first ; i<last ; i++) {
62  if (auxi[i]== '(')
63  ninside ++ ;
64  if (auxi[i]== ')')
65  ninside-- ;
66  if ((auxi[i]== ')') && (ninside==0))
67  needtodo = false ;
68  }
69 
70  if ((needtodo) && (auxi[last] ==')')) {
71  first ++ ;
72  last -- ;
73  }
74  }
75  doloop = needtodo ;
76  }
77 
78  int pos = 0 ;
79  for (int i=first ; i<in_output-first-1 ; i++) {
80  dest[pos] = auxi[i] ;
81  pos ++ ;
82  }
83 
84  dest[pos] = ' ' ;
85  pos ++ ;
86  dest[pos] = '\0' ;
87 }
88 
89 void get_util (char* res, char* input) {
90 
91  char auxi[LMAX] ;
92  trim_spaces(auxi, input) ;
93 
94  int first = 0 ;
95  int conte = 0 ;
96  while ((first==0) && (auxi[conte]!='\0')) {
97  if (input[conte]=='_')
98  first = 1 ;
99  if (input[conte]=='^')
100  first = 2 ;
101  conte ++ ;
102  }
103 
104  if (first==0) {
105  strcpy(res, auxi) ;
106  }
107  else if (first==1) {
108  get_term (auxi, res, '_') ;
109  }
110  else get_term(auxi, res, '^') ;
111 }
112 
113 // Our many given char in a string ?
114 int nbr_char (const char* name, char xx) {
115 
116  const char* copie = name ;
117  int conte = 0 ;
118  while (*copie!='\0') {
119  if (*copie==xx)
120  conte ++ ;
121  copie ++ ;
122  }
123  return conte ;
124 }
125 
126 // Get some part of a string (up to the character sep)
127 void get_term (char* input, char* output, char sep) {
128 
129  char* found = strchr(input, sep) ;
130 
131  char auxi[LMAX] ;
132  for (int i=0 ; i<int(strlen(input)-strlen(found)) ; i++)
133  auxi[i] = input[i] ;
134  auxi[int(strlen(input)-strlen(found))]='\0' ;
135 
136  trim_spaces(output, auxi) ;
137 
138 
139  found++ ;
140  int i=0 ;
141  while (*found != '\0') {
142  input[i] = *found ;
143  i++ ;
144  found++ ;
145  }
146  input[i]='\0' ;
147 }
148 
149 void get_parts (const char* input, char* first, char* second, char sep, int place) {
150  // Put ourselves in the right place :
151  int length = static_cast<int>(strlen(input)) ;
152  int nfound = -1 ;
153  bool finloop = false ;
154  int pos = length - 1 ;
155  while (!finloop) {
156  if (input[pos]==sep)
157  nfound++ ;
158  pos -- ;
159  if (nfound==place)
160  finloop = true ;
161  if (pos==-1)
162  finloop = true ;
163  }
164  if (pos==-1) {
165  // Not good !
166  first[0] = '\0' ;
167  second[0] = '0' ;
168  }
169  else {
170  pos ++ ;
171  char auxi1[LMAX] ;
172  for (int i=0 ; i<pos ; i++)
173  auxi1[i] = input[i] ;
174  auxi1[pos]='\0' ;
175  trim_spaces(first, auxi1) ;
176 
177  char auxi2[LMAX] ;
178  for (int i=pos+1 ; i<length ; i++)
179  auxi2[i-pos-1] = input[i] ;
180  auxi2[length-1-pos]='\0' ;
181  trim_spaces(second, auxi2) ;
182  }
183 }
184 
185 
186 bool is_tensor (const char* input, const char* name_tensor, int& valence, char*& name_ind, Array<int>*& type_ind) {
187 
188  bool res = (nbr_char(input, ' ')==1) ? true : false ;
189  if (!res)
190  return false ;
191  else {
192  int first = 0 ;
193  int conte = 0 ;
194  while ((first==0) && (input[conte]!='\0')) {
195  if (input[conte]=='_')
196  first = 1 ;
197  if (input[conte]=='^')
198  first = 2 ;
199  conte ++ ;
200  }
201 
202  char name[LMAX] ;
203  char ind[LMAX] ;
204 
205  if (first==0) {
206  // No indices
207  valence = 0 ;
208  int same = strcmp(input, name_tensor);
209  if (same!=0)
210  return false;
211  else
212  return true ;
213  }
214 
215  // get the name :
216  int kant = 0 ;
217  while ((input[kant]!='_') && (input[kant]!='^')) {
218  name[kant] = input[kant] ;
219  kant++ ;
220  }
221  name[kant] = ' ' ;
222  name[kant+1] = '\0' ;
223 
224  int kkant = 0 ;
225  while (input[kant]!='\0') {
226  ind[kkant] = input[kant] ;
227  kkant++ ;
228  kant ++ ;
229  }
230  ind[kkant] = ' ' ;
231  ind[kkant+1] = '\0' ;
232 
233 
234  int same = strcmp(name, name_tensor);
235  if (same!=0)
236  return false ;
237  else {
238  valence = 0 ;
239  int cc = 0 ;
240  while (ind[cc]!='\0') {
241  if ((ind[cc]!=' ') && (ind[cc]!='_') && (ind[cc]!='^'))
242  valence ++ ;
243  cc ++ ;
244  }
245 
246  if (type_ind!=0x0)
247  delete type_ind ;
248  type_ind = new Array<int> (valence) ;
249  if (name_ind != 0x0)
250  delete [] name_ind ;
251  name_ind = new char [valence] ;
252 
253  // On remplit les arrays
254  cc = 0 ;
255  int nind = 0 ;
256  while (ind[cc]!='\0') {
257  if ((ind[cc]!=' ') && (ind[cc]!='_') && (ind[cc]!='^')) {
258  name_ind[nind] = ind[cc] ;
259  if (first == 1)
260  type_ind->set(nind) = COV ;
261  else
262  type_ind->set(nind) = CON ;
263  nind ++ ;
264  }
265  if (ind[cc]=='_')
266  first = 1 ;
267  if (ind[cc]=='^')
268  first = 2 ;
269  cc ++ ;
270  }
271  return true ;
272  }
273  }
274 }
275 
276 }