Octopus
recipes.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 <gsl/gsl_rng.h>
24#include <locale.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#if __has_include(<unistd.h>)
30#include <unistd.h>
31#endif
32
33#ifdef _POSIX_VERSION
34#include <dirent.h>
35#include <sys/time.h>
36#endif
37
38#include "string_f.h"
39
40unsigned long int random_seed() {
41 unsigned long int seed;
42 FILE *devrandom;
43
44 if ((devrandom = fopen("/dev/urandom", "r")) == NULL) {
45#ifdef _POSIX_VERSION
46 struct timeval tv;
47 gettimeofday(&tv, 0);
48 seed = tv.tv_sec + tv.tv_usec;
49#else
50 seed = 0;
51#endif
52 } else {
53 fread(&seed, sizeof(seed), 1, devrandom);
54 fclose(devrandom);
55 }
56
57 return seed;
58}
59
60void FC_FUNC_(oct_printrecipe, OCT_PRINTRECIPE)(STR_F_TYPE _dir,
61 STR_F_TYPE filename STR_ARG2) {
62
63#ifdef _POSIX_VERSION
64 char *lang, *tmp, dir[512];
65 struct dirent **namelist;
66 int ii, nn;
67 gsl_rng *rng;
68
69 /* get language */
70 lang = getenv("LANG");
71 if (lang == NULL)
72 lang = "en";
73
74 /* convert directory from Fortran to C string */
75 TO_C_STR1(_dir, tmp);
76 strcpy(dir, tmp);
77 free(tmp);
78
79 strcat(dir, "/recipes");
80
81 /* check out if lang dir exists */
82 nn = scandir(dir, &namelist, 0, alphasort);
83 if (nn < 0) {
84 printf("Directory does not exist: %s", dir);
85 return;
86 }
87
88 for (ii = 0; ii < nn; ii++)
89 if (strncmp(lang, namelist[ii]->d_name, 2) == 0) {
90 strcat(dir, "/");
91 strcat(dir, namelist[ii]->d_name);
92 break;
93 }
94
95 if (ii == nn)
96 strcat(dir, "/en"); /* default */
97
98 /* clean up */
99 for (ii = 0; ii < nn; ii++)
100 free(namelist[ii]);
101 free(namelist);
102
103 /* now we read the recipes */
104 nn = scandir(dir, &namelist, 0, alphasort);
105
106 /* initialize random numbers */
107 gsl_rng_env_setup();
108 rng = gsl_rng_alloc(gsl_rng_default);
109 gsl_rng_set(rng, random_seed());
110 ii = gsl_rng_uniform_int(rng, nn - 2);
111 gsl_rng_free(rng);
112
113 strcat(dir, "/");
114 strcat(dir, namelist[ii + 2]->d_name); /* skip ./ and ../ */
115
116 /* clean up again */
117 for (ii = 0; ii < nn; ii++)
118 free(namelist[ii]);
119 free(namelist);
120
121 TO_F_STR2(dir, filename);
122
123#else
124 printf("Sorry, recipes cannot be printed unless scandir and alphasort are "
125 "available with your C compiler.\n");
126#endif
127}
int fclose(FILE *__stream)
int scandir(const char *__restrict __dir, struct dirent ***__restrict __namelist, int(*__selector)(const struct dirent *), int(*__cmp)(const struct dirent **, const struct dirent **)) __attribute__((__nonnull__(1
int gettimeofday(struct timeval *__restrict __tv, void *__restrict __tz) __attribute__((__nothrow__
int int alphasort(const struct dirent **__e1, const struct dirent **__e2) __attribute__((__nothrow__