Octopus
oct_f.c
Go to the documentation of this file.
1/*
2 Copyright (C) 2002 M. Marques, A. Castro, A. Rubio, G. Bertsch
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18
19*/
20
21#include <config.h>
22
23#include <ctype.h>
24#include <libgen.h>
25#include <math.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <time.h>
30#if __has_include(<unistd.h>)
31#include <unistd.h>
32#endif
33
34#include <fortran_types.h>
35
36#ifdef _POSIX_VERSION
37#include <dirent.h>
38#include <sys/stat.h>
39#include <sys/time.h>
40#include <sys/types.h>
41#endif
42
43#include "string_f.h" /* Fortran <-> c string compatibility issues */
44
45/* *********************** interface functions ********************** */
46
47void FC_FUNC_(oct_mkdir, OCT_MKDIR)(STR_F_TYPE name STR_ARG1) {
48 struct stat buf;
49 char *name_c;
50
51 TO_C_STR1(name, name_c);
52 if (!*name_c)
53 return;
55 if (stat(name_c, &buf) == 0) {
56 free(name_c);
57 return;
58 }
60#ifndef _WIN32
61 mkdir(name_c, 0775);
62#else
63 mkdir(name_c);
64#endif
65
66 free(name_c);
68
69void FC_FUNC_(oct_stat, OCT_STAT)(fint *ierr, STR_F_TYPE name,
70 STR_F_TYPE mod_time STR_ARG2) {
71 char *name_c, *mod_time_c;
72 struct stat statbuf;
73 time_t mtime;
74 struct tm *timeinfo;
76 TO_C_STR1(name, name_c);
77 *ierr = stat(name_c, &statbuf);
79 if (*ierr == 0) {
80 mtime = statbuf.st_mtime; /* last modification time */
81 timeinfo = localtime(&mtime);
82 mod_time_c = asctime(timeinfo);
83 } else {
84 perror(name_c); /* what is the problem? */
85 mod_time_c = malloc(sizeof(char));
86 mod_time_c[0] = '\0';
87 }
88 free(name_c);
89
90 TO_F_STR2(mod_time_c, mod_time);
91 if (*ierr != 0) {
92 printf("ierr = %i\n", *ierr);
93 free(mod_time_c);
94 }
95 /* otherwise, do not do this since 'mod_time_c' points at static data of
96 * asctime */
97}
98
99int FC_FUNC_(oct_dir_exists, OCT_DIR_EXISTS)(STR_F_TYPE name STR_ARG1) {
100 int ierr;
101 char *name_c;
102 struct stat statbuf;
104 TO_C_STR1(name, name_c);
105 ierr = stat(name_c, &statbuf);
106 free(name_c);
108 if (ierr == 0) {
109 return S_ISDIR(statbuf.st_mode);
110 } else {
111 return 0;
113}
115void FC_FUNC_(oct_rm, OCT_RM)(STR_F_TYPE name STR_ARG1) {
116 char *name_c;
118 TO_C_STR1(name, name_c);
119 unlink(name_c);
120 free(name_c);
122
123void FC_FUNC_(oct_getcwd, OCT_GETCWD)(STR_F_TYPE name STR_ARG1) {
124 char s[256];
125 getcwd(s, 256);
126 TO_F_STR1(s, name);
128
129void FC_FUNC_(oct_realpath, OCT_REALPATH)(STR_F_TYPE fnam,
130 STR_F_TYPE rnam STR_ARG2) {
131 char *fn = NULL, *rn = NULL;
132 TO_C_STR1(fnam, fn);
133 rn = realpath(fn, NULL);
134 free(fn);
135 if (rn != NULL) {
136 TO_F_STR2(rn, rnam);
137 } else {
138 TO_F_STR2("", rnam);
140 free(rn);
141 return;
144void FC_FUNC_(oct_dirname, OCT_DIRNAME)(STR_F_TYPE fnam,
145 STR_F_TYPE dnam STR_ARG2) {
146 char *fn = NULL, *dn = NULL;
147 TO_C_STR1(fnam, fn);
148 dn = dirname(fn);
149 if (dn != NULL) {
150 TO_F_STR2(dn, dnam);
151 } else {
152 TO_F_STR2("", dnam);
153 }
154 free(fn);
155 return;
156}
158void FC_FUNC_(oct_basename, OCT_BASENAME)(STR_F_TYPE fnam,
159 STR_F_TYPE bnam STR_ARG2) {
160 char *fn = NULL, *bn = NULL;
161 TO_C_STR1(fnam, fn);
162 bn = basename(fn);
163 free(fn);
164 if (bn != NULL) {
165 TO_F_STR2(bn, bnam);
166 } else {
167 TO_F_STR2("", bnam);
169 return;
170}
171
172void FC_FUNC_(oct_getenv, OCT_GETENV)(STR_F_TYPE var,
173 STR_F_TYPE value STR_ARG2) {
174 char *name_c, *var_c;
175
176 TO_C_STR1(var, name_c);
177 var_c = getenv(name_c);
178 free(name_c);
179
180 if (var_c != NULL) {
181 TO_F_STR2(var_c, value);
182 } else {
183 TO_F_STR2("", value);
184 }
185}
186
187/* this function gets a string of the form '1-12, 34' and fills
188 array l with the 1 if the number is in the list, or 0 otherwise */
189void FC_FUNC_(oct_wfs_list, OCT_WFS_LIST)(STR_F_TYPE str,
190 fint l[16384] STR_ARG1) {
191 int i, i1, i2;
192 char c[20], *c1, *str_c, *s;
194 TO_C_STR1(str, str_c);
195 s = str_c;
197 /* clear list */
198 for (i = 0; i < 16384; i++)
199 l[i] = 0;
201 while (*s) {
202 /* get integer */
203 for (c1 = c; isdigit(*s) || isspace(*s); s++)
204 if (isdigit(*s))
205 *c1++ = *s;
206 *c1 = '\0';
207 i1 = atoi(c) - 1;
208
209 if (*s == '-') { /* range */
210 s++;
211 for (c1 = c; isdigit(*s) || isspace(*s); s++)
212 if (isdigit(*s))
213 *c1++ = *s;
214 *c1 = '\0';
215 i2 = atoi(c) - 1;
216 } else /* single value */
217 i2 = i1;
218
219 for (i = i1; i <= i2; i++)
220 if (i >= 0 && i < 16384)
221 l[i] = 1;
222
223 if (*s)
224 s++;
225 }
226
227 free(str_c);
228}
229
230/* ------------------------------ from varia.c -------------------------------
231 */
232#include "varia.h"
233
234void FC_FUNC_(oct_progress_bar, OCT_PROGRESS_BAR)(fint *a, fint *max) {
235 if (*max == 0)
236 return; /* Skip the bar if the length is 0 */
237 progress_bar(*a, *max);
238}
239
240/* ------------------------------ some stuff --------------------------------
241 */
242void FC_FUNC_(oct_gettimeofday, OCT_GETTIMEOFDAY)(fint *sec, fint *usec) {
243#ifdef _POSIX_VERSION
244 struct timeval tv;
245
246 gettimeofday(&tv, NULL);
247
248 /* The typecast below should use long. However, this causes incompatibilities
249 with Fortran integers.
250 Using int will cause wrong results when tv.tv_sec exceeds
251 INT_MAX=2147483647 */
252 *sec = (int)tv.tv_sec;
253 *usec = (int)tv.tv_usec;
254/*
255 char str[sizeof("HH:MM:SS")];
256 time_t local;
257 local = tv.tv_sec;
258 strftime(str, sizeof(str), "%T", localtime(&local));
259 printf("%s.%06ld \n", str, (long) tv.tv_usec);
260 printf("%ld.%06ld \n", (long) tv.tv_sec, (long) tv.tv_usec);
261*/
262#else
263 *sec = 0;
264 *usec = 0;
265#endif
266}
267
268double FC_FUNC_(oct_clock, OCT_CLOCK)() {
269#ifdef _POSIX_VERSION
270 int sec, usec;
271 FC_FUNC_(oct_gettimeofday, OCT_GETTIMEOFDAY)(&sec, &usec);
272 return sec + 1.0e-6 * usec;
273#else
274 return (double)clock() / CLOCKS_PER_SEC;
275#endif
276}
277
278void FC_FUNC_(oct_nanosleep, OCT_NANOSLEEP)(fint *sec, fint *nsec) {
279#ifdef _POSIX_VERSION
280 /* Datatypes should be long instead of int (see comment in gettimeofday) */
281 struct timespec req;
282 req.tv_sec = (time_t)*sec;
283 req.tv_nsec = (long)*nsec;
284 nanosleep(&req, NULL);
285#endif
286}
287
288void FC_FUNC_(oct_sysname, OCT_SYSNAME)(STR_F_TYPE name STR_ARG1) {
289 char *name_c;
290
291 sysname(&name_c);
292 TO_F_STR1(name_c, name);
293 free(name_c);
294}
295
296int FC_FUNC_(oct_number_of_lines,
297 OCT_NUMBER_OF_LINES)(STR_F_TYPE name STR_ARG1) {
298
299 FILE *pf;
300 int c, i;
301 char *name_c;
302
303 TO_C_STR1(name, name_c);
304 pf = fopen(name_c, "r");
305 free(name_c);
306
307 if (pf != NULL) {
308 i = 0;
309 while ((c = getc(pf)) != EOF) {
310 if (c == '\n')
311 i++;
312 }
313 fclose(pf);
314 return i;
315 } else {
316 return -1;
317 }
318}
319
320/* Given a string in C, it breaks it line by line and returns each
321 as a Fortran string. Returns 0 if string does not have more lines.
322*/
323void FC_FUNC_(oct_break_c_string,
324 OCT_BREAK_C_STRING)(char **str, char **s,
325 STR_F_TYPE line_f STR_ARG1) {
326 char *c, line[256]; /* hopefully no line is longer than 256 characters ;) */
327
328 if (*s == NULL)
329 *s = *str;
330
331 if (*s == NULL || **s == '\0') {
332 *s = (char *)(0);
333 return;
334 }
335
336 for (c = line; **s != '\0' && **s != '\n'; (*s)++, c++)
337 *c = **s;
338 *c = '\0';
339 if (**s == '\n')
340 (*s)++;
341
342 TO_F_STR1(line, line_f);
343}
344
345/*
346
347This function searches in directory given by dirname all files that have the
348following name:
349
350*_<real_number>_<integer>*
351
352It returns the value of <real_number> found that is closest to freq (or
353abs(freq)) and for which the value of <integer> matches with the tag argument.
354
355The value found is returned in the freq argument.
356
357ierr results:
3580 : value found
3591 : no matching file found
3602 : cannot open the directory or function not available
361
362*/
363
364void FC_FUNC_(oct_search_file_lr,
365 OCT_SEARCH_FILE_LR)(double *freq, const fint *tag, fint *ierr,
366 STR_F_TYPE dirname STR_ARG1) {
367#ifdef _POSIX_VERSION
368
369 DIR *dir;
370 struct dirent *ent;
371 char *name_c;
372 char *num_start, *num_end;
373 double read_value, min;
374 int found_something, read_tag;
375
376 TO_C_STR1(dirname, name_c);
377 dir = opendir(name_c);
378
379 if (dir == NULL) {
380 *ierr = 2;
381 return;
382 }
383 free(name_c);
384
385 ent = NULL;
386 found_something = 0;
387
388 while (1) {
389 ent = readdir(dir);
390 if (ent == NULL)
391 break;
392
393 num_start = strchr(ent->d_name, '_');
394
395 if (num_start != NULL) {
396 num_start++; /* now this points to the beginning of the number */
397
398 /* take the numerical value from the string */
399 read_value = strtod(num_start, &num_end);
400
401 if (num_end == num_start)
402 continue; /* no number found */
403
404 /* check that we have the correct tag */
405 if (num_end[0] == '_') {
406
407 num_start = num_end + 1;
408 read_tag = (int)strtol(num_start, &num_end, 10);
409 if (num_end == num_start)
410 continue; /* no tag found */
411 if (read_tag != *tag)
412 continue; /* tag does not match */
413
414 } else
415 continue;
416
417 /* if this is the first number we found */
418 if (!found_something) {
419 min = read_value;
420 found_something = 1;
421 } else if (fabs(fabs(min) - fabs(*freq)) >
422 fabs(fabs(read_value) - fabs(*freq))) {
423 /* if the value is closer than previous */
424 min = read_value;
425 }
426 }
427 }
428
429 closedir(dir);
430
431 if (found_something) {
432 *ierr = 0;
433 *freq = min;
434 } else {
435 *ierr = 1;
436 }
437
438#else
439#warning directory search not compiled
440 fprintf(stderr, "Warning: Directory search not available since certain C "
441 "functions are not available.\n");
442 *ierr = 2;
443#endif
444}
445
446void *FC_FUNC_(oct_get_memory_usage, OCT_GET_MEMORY_USAGE)() {
447#ifdef _POSIX_VERSION
448 static size_t pagesize = 0;
449 FILE *f;
450 int pid;
451 unsigned long mem;
452 char s[256];
453
454 if (pagesize == 0)
455 pagesize = sysconf(_SC_PAGESIZE);
456
457 pid = getpid();
458 sprintf(s, "%s%d%s", "/proc/", pid, "/statm");
459 if ((f = fopen(s, "r")) == (FILE *)NULL)
460 return (void *)(-1);
461 fscanf(f, "%lu", &mem);
462 fclose(f);
463
464 return (void *)(mem * pagesize);
465#else
466 return 0;
467#endif
468}
469
470void FC_FUNC_(oct_exit_failure, OCT_EXIT_FAILURE)() { exit(EXIT_FAILURE); }
int fint
Definition: fortran_types.h:14
double fabs(double __x) __attribute__((__nothrow__
__time_t time_t
Definition: io_binary.c:286
real(real64) function s()
struct __dirstream DIR
Definition: oct_f.c:4654
long int sysconf(int __name) __attribute__((__nothrow__
int mkdir(const char *__path, __mode_t __mode) __attribute__((__nothrow__
__pid_t getpid(void)
Definition: oct_f.c:4226
int gettimeofday(struct timeval *__restrict __tv, void *__restrict __tz) __attribute__((__nothrow__
@ _SC_PAGESIZE
Definition: oct_f.c:3657
void sysname(char **c)
Definition: varia.c:4602
DIR DIR struct dirent * readdir(DIR *__dirp) __attribute__((__nonnull__(1)))
DIR * opendir(const char *__name) __attribute__((__nonnull__(1))) __attribute__((__malloc__)) __attribute__((__malloc__(closedir
FILE * stderr
int closedir(DIR *__dirp) __attribute__((__nonnull__(1)))
int stat(const char *__restrict __file, struct stat *__restrict __buf) __attribute__((__nothrow__
int fclose(FILE *__stream)
clock_t clock(void)
Definition: oct_f.c:3216
void progress_bar(int actual, int max)
Definition: varia.c:4664
ptrdiff_t l
Definition: operate_inc.c:12
ptrdiff_t i
Definition: operate_inc.c:12
__mode_t st_mode
Definition: io_binary.c:330
__syscall_slong_t tv_nsec
Definition: getopt_f.c:1120
__time_t tv_sec
Definition: getopt_f.c:1115