Changes to give correct output when running in parallel in vv. Doesen't yet work...
[gromacs/rigid-bodies.git] / src / gmxlib / string2.c
blob58e10305e342dae7ed9eb90071efc7336a694f1b
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
32 * And Hey:
33 * GROningen Mixture of Alchemy and Childrens' Stories
35 /* This file is completely threadsafe - keep it that way! */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
45 #ifdef GMX_CRAY_XT3
46 #undef HAVE_PWD_H
47 #endif
49 #include <stdio.h>
50 #include <ctype.h>
51 #include <stdlib.h>
52 #include <errno.h>
53 #include <sys/types.h>
55 #ifdef HAVE_PWD_H
56 #include <pwd.h>
57 #endif
58 #include <time.h>
60 #include "typedefs.h"
61 #include "smalloc.h"
62 #include "gmx_fatal.h"
63 #include "macros.h"
64 #include "string2.h"
66 int continuing(char *s)
67 /* strip trailing spaces and if s ends with a CONTINUE remove that too.
68 * returns TRUE if s ends with a CONTINUE, FALSE otherwise.
71 int sl;
73 rtrim(s);
74 sl = strlen(s);
75 if ((sl > 0) && (s[sl-1] == CONTINUE)) {
76 s[sl-1] = 0;
77 return TRUE;
79 else
80 return FALSE;
83 char *fgets2(char *line, int n, FILE *stream)
84 /* This routine reads a string from stream of max length n
85 * and zero terminated, without newlines
86 * line should be long enough (>= n)
89 char *c;
90 if (fgets(line,n,stream)==NULL) return NULL;
91 if ((c=strchr(line,'\n'))!=NULL) *c=0;
92 if ((c=strchr(line,'\r'))!=NULL) *c=0;
93 return line;
96 void strip_comment (char *line)
98 char *c;
100 if (!line)
101 return;
103 /* search for a comment mark and replace it by a zero */
104 if ((c = strchr(line,COMMENTSIGN)) != NULL)
105 (*c) = 0;
108 void upstring (char *str)
110 int i;
112 for (i=0; (i < (int)strlen(str)); i++)
113 str[i] = toupper(str[i]);
116 void ltrim (char *str)
118 char *tr;
119 int c;
121 if (!str)
122 return;
124 tr = strdup (str);
125 c = 0;
126 while ((tr[c] == ' ') || (tr[c] == '\t'))
127 c++;
129 strcpy (str,tr+c);
130 free (tr);
133 void rtrim (char *str)
135 int nul;
137 if (!str)
138 return;
140 nul = strlen(str)-1;
141 while ((nul > 0) && ((str[nul] == ' ') || (str[nul] == '\t')) ) {
142 str[nul] = '\0';
143 nul--;
147 void trim (char *str)
149 ltrim (str);
150 rtrim (str);
153 void nice_header (FILE *out,const char *fn)
155 const char *unk = "onbekend";
156 time_t clock;
157 char *user=NULL;
158 int gh;
159 uid_t uid;
160 char buf[256];
161 #ifdef HAVE_PWD_H
162 struct passwd *pw;
163 #endif
165 /* Print a nice header above the file */
166 clock = time (0);
167 fprintf (out,"%c\n",COMMENTSIGN);
168 fprintf (out,"%c\tFile '%s' was generated\n",COMMENTSIGN,fn ? fn : unk);
170 #ifdef HAVE_PWD_H
171 uid = getuid();
172 pw = getpwuid(uid);
173 gh = gethostname(buf,255);
174 user= pw->pw_name;
175 #else
176 uid = 0;
177 gh = -1;
178 #endif
180 fprintf (out,"%c\tBy user: %s (%d)\n",COMMENTSIGN,
181 user ? user : unk,(int) uid);
182 fprintf(out,"%c\tOn host: %s\n",COMMENTSIGN,(gh == 0) ? buf : unk);
184 fprintf (out,"%c\tAt date: %s",COMMENTSIGN,ctime(&clock));
185 fprintf (out,"%c\n",COMMENTSIGN);
188 int strcasecmp_min(const char *str1, const char *str2)
190 char ch1,ch2;
195 ch1=toupper(*(str1++));
196 while ((ch1=='-') || (ch1=='_'));
198 ch2=toupper(*(str2++));
199 while ((ch2=='-') || (ch2=='_'));
200 if (ch1!=ch2) return (ch1-ch2);
202 while (ch1);
203 return 0;
206 int strncasecmp_min(const char *str1, const char *str2, int n)
208 char ch1,ch2;
209 char *stri1, *stri2;
211 stri1=(char *)str1;
212 stri2=(char *)str2;
216 ch1=toupper(*(str1++));
217 while ((ch1=='-') || (ch1=='_'));
219 ch2=toupper(*(str2++));
220 while ((ch2=='-') || (ch2=='_'));
221 if (ch1!=ch2) return (ch1-ch2);
223 while (ch1 && (str1-stri1<n) && (str2-stri2<n));
224 return 0;
227 int gmx_strcasecmp(const char *str1, const char *str2)
229 char ch1,ch2;
233 ch1=toupper(*(str1++));
234 ch2=toupper(*(str2++));
235 if (ch1!=ch2) return (ch1-ch2);
237 while (ch1);
238 return 0;
241 int gmx_strncasecmp(const char *str1, const char *str2, int n)
243 char ch1,ch2;
245 if(n==0)
246 return 0;
250 ch1=toupper(*(str1++));
251 ch2=toupper(*(str2++));
252 if (ch1!=ch2) return (ch1-ch2);
253 n--;
255 while (ch1 && n);
256 return 0;
259 char *gmx_strdup(const char *src)
261 char *dest;
263 snew(dest,strlen(src)+1);
264 strcpy(dest,src);
266 return dest;
269 char *
270 gmx_strndup(const char *src, int n)
272 int len;
273 char *dest;
275 len = strlen(src);
276 if (len > n)
278 len = n;
280 snew(dest, len+1);
281 strncpy(dest, src, len);
282 dest[len] = 0;
283 return dest;
286 char *wrap_lines(const char *buf,int line_width, int indent,bool bIndentFirst)
288 char *b2;
289 int i,i0,i2,j,b2len,lspace=0,l2space=0;
290 bool bFirst,bFitsOnLine;
292 /* characters are copied from buf to b2 with possible spaces changed
293 * into newlines and extra space added for indentation.
294 * i indexes buf (source buffer) and i2 indexes b2 (destination buffer)
295 * i0 points to the beginning of the current line (in buf, source)
296 * lspace and l2space point to the last space on the current line
297 * bFirst is set to prevent indentation of first line
298 * bFitsOnLine says if the first space occurred before line_width, if
299 * that is not the case, we have a word longer than line_width which
300 * will also not fit on the next line, so we might as well keep it on
301 * the current line (where it also won't fit, but looks better)
304 b2=NULL;
305 b2len=strlen(buf)+1+indent;
306 snew(b2,b2len);
307 i0=i2=0;
308 if (bIndentFirst)
309 for(i2=0; (i2<indent); i2++)
310 b2[i2] = ' ';
311 bFirst=TRUE;
312 do {
313 l2space = -1;
314 /* find the last space before end of line */
315 for(i=i0; ((i-i0 < line_width) || (l2space==-1)) && (buf[i]); i++) {
316 b2[i2++] = buf[i];
317 /* remember the position of a space */
318 if (buf[i] == ' ') {
319 lspace = i;
320 l2space = i2-1;
322 /* if we have a newline before the line is full, reset counters */
323 if (buf[i]=='\n' && buf[i+1]) {
324 i0=i+1;
325 b2len+=indent;
326 srenew(b2, b2len);
327 /* add indentation after the newline */
328 for(j=0; (j<indent); j++)
329 b2[i2++]=' ';
332 /* If we are at the last newline, copy it */
333 if (buf[i]=='\n' && !buf[i+1]) {
334 b2[i2++] = buf[i++];
336 /* if we're not at the end of the string */
337 if (buf[i]) {
338 /* check if one word does not fit on the line */
339 bFitsOnLine = (i-i0 <= line_width);
340 /* reset line counters to just after the space */
341 i0 = lspace+1;
342 i2 = l2space+1;
343 /* if the words fit on the line, and we're beyond the indentation part */
344 if ( (bFitsOnLine) && (l2space >= indent) ) {
345 /* start a new line */
346 b2[l2space] = '\n';
347 /* and add indentation */
348 if (indent) {
349 if (bFirst) {
350 line_width-=indent;
351 bFirst=FALSE;
353 b2len+=indent;
354 srenew(b2, b2len);
355 for(j=0; (j<indent); j++)
356 b2[i2++]=' ';
357 /* no extra spaces after indent; */
358 while(buf[i0]==' ')
359 i0++;
363 } while (buf[i]);
364 b2[i2] = '\0';
366 return b2;
369 char **split(char sep,char *str)
371 char **ptr = NULL;
372 int n,nn,nptr = 0;
374 if (str == NULL)
375 return NULL;
376 nn = strlen(str);
377 for(n=0; (n<nn); n++)
378 if (str[n] == sep)
379 nptr++;
380 snew(ptr,nptr+2);
381 nptr = 0;
382 while (*str != '\0') {
383 while ((*str != '\0') && (*str == sep))
384 str++;
385 if (*str != '\0') {
386 snew(ptr[nptr],1+strlen(str));
387 n = 0;
388 while ((*str != '\0') && (*str != sep)) {
389 ptr[nptr][n] = *str;
390 str++;
391 n++;
393 ptr[nptr][n] = '\0';
394 nptr++;
397 ptr[nptr] = NULL;
399 return ptr;
403 gmx_large_int_t
404 str_to_large_int_t(const char *str, char **endptr)
406 int sign = 1;
407 gmx_large_int_t val = 0;
408 char ch;
409 const char *p;
411 p = str;
412 if(p==NULL)
414 *endptr=NULL;
415 return 0;
418 /* Strip off initial white space */
419 while(isspace(*p))
421 p++;
423 /* Conform to ISO C99 - return original pointer if string does not contain a number */
424 if(*str=='\0')
426 *endptr=(char *)str;
429 if(*p=='-')
431 p++;
432 sign *= -1;
435 while( ((ch=*p) != '\0') && isdigit(ch) )
437 /* Important to add sign here, so we dont overflow in final multiplication */
438 ch = (ch-'0')*sign;
439 val = val*10 + ch;
440 if(ch != val%10)
442 /* Some sort of overflow has occured, set endptr to original string */
443 *endptr=(char *)str;
444 errno = ERANGE;
445 return(0);
447 p++;
450 *endptr=(char *)p;
452 return val;
455 char *gmx_strsep(char **stringp, const char *delim)
457 char *ret;
458 int len=strlen(delim);
459 int i,j=0;
460 int found=0;
462 if (! *stringp)
463 return NULL;
464 ret=*stringp;
467 if ( (*stringp)[j] == '\0')
469 found=1;
470 *stringp=NULL;
471 break;
473 for (i=0;i<len;i++)
475 if ( (*stringp)[j]==delim[i])
477 (*stringp)[j]='\0';
478 *stringp=*stringp+j+1;
479 found=1;
480 break;
483 j++;
484 } while (!found);
486 return ret;