Mercurial > molko
annotate libcore/core/sys.c @ 121:789b23e01f52
misc: reorganize hierarchy, closes #2490
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 05 Oct 2020 13:25:06 +0200 |
parents | src/core/sys.c@68ce8e02061a |
children | eb0a7ab71023 |
rev | line source |
---|---|
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * sys.c -- system routines |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
19 #include <assert.h> |
56
43d1102a367e
core: disable buffering on MinGW
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
20 #include <stdio.h> |
43d1102a367e
core: disable buffering on MinGW
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
21 #include <stdlib.h> |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
22 #include <limits.h> |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
23 |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 #include <SDL.h> |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 #include <SDL_image.h> |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 #include <SDL_mixer.h> |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 #include <SDL_ttf.h> |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 |
36
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
29 #if !defined(_WIN32) /* Assuming POSIX */ |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
30 # include <sys/types.h> |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
31 # include <dirent.h> |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
32 #endif |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
33 |
39
9d1421c09dfb
core: add more utilities to improve code simplicity
David Demelier <markand@malikania.fr>
parents:
36
diff
changeset
|
34 #include "error.h" |
9d1421c09dfb
core: add more utilities to improve code simplicity
David Demelier <markand@malikania.fr>
parents:
36
diff
changeset
|
35 #include "error_p.h" |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 #include "sys.h" |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
38 #if defined(_WIN32) |
36
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
39 |
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
40 static void |
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
41 determine(char path[], size_t pathlen) |
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
42 { |
40 | 43 char *base = SDL_GetBasePath(); |
36
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
44 |
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
45 /* On Windows, the data hierarchy is the same as the project. */ |
40 | 46 snprintf(path, pathlen, "%sassets", base); |
36
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
47 SDL_free(base); |
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
48 } |
798baf7f3ec0
core: implement sys_data* functions for Windows
David Demelier <markand@malikania.fr>
parents:
32
diff
changeset
|
49 |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
50 #else /* Assuming POSIX */ |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
51 |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
52 static bool |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
53 is_absolute(const char *path) |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
54 { |
40 | 55 assert(path); |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
56 |
40 | 57 return path[0] == '/'; |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
58 } |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
59 |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
60 static void |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
61 determine(char path[], size_t pathlen) |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
62 { |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
63 char localassets[PATH_MAX]; |
40 | 64 char *base = SDL_GetBasePath(); |
65 DIR *dp; | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
66 |
40 | 67 /* Try assets directory where executable lives. */ |
68 snprintf(localassets, sizeof (localassets), "%sassets", base); | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
69 |
40 | 70 if ((dp = opendir(localassets))) { |
71 snprintf(path, pathlen, "%sassets", base); | |
72 closedir(dp); | |
73 } else { | |
74 /* We are not in the project source directory. */ | |
75 if (is_absolute(SHAREDIR)) { | |
76 /* SHAREDIR is absolute */ | |
77 snprintf(path, pathlen, "%s/molko", SHAREDIR); | |
78 } else if (is_absolute(BINDIR)) { | |
79 /* SHAREDIR is relative but BINDIR is absolute */ | |
80 snprintf(path, pathlen, "%s/%s/molko", PREFIX, SHAREDIR); | |
81 } else { | |
82 /* SHAREDIR, BINDIR are both relative */ | |
83 char *ptr = strstr(base, BINDIR); | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
84 |
40 | 85 if (ptr) { |
86 *ptr = '\0'; | |
87 snprintf(path, pathlen, "%s%s/molko", base, SHAREDIR); | |
88 } else { | |
89 /* Unable to determine. */ | |
90 snprintf(path, pathlen, "."); | |
91 } | |
92 } | |
93 } | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
94 |
40 | 95 SDL_free(base); |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
96 } |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
97 |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
98 #endif |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
99 |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 bool |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 sys_init(void) |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 { |
56
43d1102a367e
core: disable buffering on MinGW
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
103 #if defined(__MINGW64__) |
43d1102a367e
core: disable buffering on MinGW
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
104 /* On MinGW buffering leads to painful debugging. */ |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
105 setbuf(stderr, NULL); |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
106 setbuf(stdout, NULL); |
56
43d1102a367e
core: disable buffering on MinGW
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
107 #endif |
43d1102a367e
core: disable buffering on MinGW
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
108 |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) |
39
9d1421c09dfb
core: add more utilities to improve code simplicity
David Demelier <markand@malikania.fr>
parents:
36
diff
changeset
|
110 return error_sdl(); |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) |
39
9d1421c09dfb
core: add more utilities to improve code simplicity
David Demelier <markand@malikania.fr>
parents:
36
diff
changeset
|
112 return error_sdl(); |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 if (TTF_Init() < 0) |
39
9d1421c09dfb
core: add more utilities to improve code simplicity
David Demelier <markand@malikania.fr>
parents:
36
diff
changeset
|
114 return error_sdl(); |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 if (Mix_Init(MIX_INIT_OGG) != MIX_INIT_OGG) |
39
9d1421c09dfb
core: add more utilities to improve code simplicity
David Demelier <markand@malikania.fr>
parents:
36
diff
changeset
|
116 return error_sdl(); |
103
68ce8e02061a
sound: add basic sound API
David Demelier <markand@malikania.fr>
parents:
97
diff
changeset
|
117 if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0) |
68ce8e02061a
sound: add basic sound API
David Demelier <markand@malikania.fr>
parents:
97
diff
changeset
|
118 return error_sdl(); |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 return true; |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 } |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 |
31 | 123 const char * |
124 sys_datadir(void) | |
125 { | |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
126 static char path[PATH_MAX]; |
31 | 127 |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
128 if (path[0] == '\0') |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
129 determine(path, sizeof (path)); |
31 | 130 |
131 return path; | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
132 } |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
133 |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
134 const char * |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
135 sys_datapath(const char *fmt, ...) |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
136 { |
40 | 137 const char *ret; |
138 va_list ap; | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
139 |
40 | 140 va_start(ap, fmt); |
141 ret = sys_datapathv(fmt, ap); | |
142 va_end(ap); | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
143 |
40 | 144 return ret; |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
145 } |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
146 |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
147 const char * |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
148 sys_datapathv(const char *fmt, va_list ap) |
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
149 { |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
150 static char path[PATH_MAX]; |
40 | 151 char filename[FILENAME_MAX]; |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
152 |
40 | 153 vsnprintf(filename, sizeof (filename), fmt, ap); |
154 snprintf(path, sizeof (path), "%s/%s", sys_datadir(), filename); | |
32
91bc2329ab0c
core: implement data directory access, closes #2454 @1h
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
155 |
40 | 156 return path; |
31 | 157 } |
158 | |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
159 const char * |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
160 sys_savepath(unsigned int idx) |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
161 { |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
162 static char path[PATH_MAX]; |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
163 char *pref; |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
164 |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
165 if ((pref = SDL_GetPrefPath("malikania", "molko"))) { |
87
ebbf35d90088
misc: fix several portability issues
David Demelier <markand@malikania.fr>
parents:
84
diff
changeset
|
166 snprintf(path, sizeof (path), "%ssave-%u", pref, idx); |
84
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
167 SDL_free(pref); |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
168 } else |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
169 snprintf(path, sizeof (path), "save-%u", idx); |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
170 |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
171 return path; |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
172 } |
a6c2067709ce
core: implement basic save routines, closes #2476 @2h
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
173 |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 void |
97
58133933ea17
window: expose some data to avoid functions
David Demelier <markand@malikania.fr>
parents:
87
diff
changeset
|
175 sys_finish(void) |
23
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
176 { |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 Mix_Quit(); |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
178 TTF_Quit(); |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 IMG_Quit(); |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
180 SDL_Quit(); |
bc9637a2601b
core: add basic system routines
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 } |