3 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version. The Blender
9 * Foundation also sells licenses for use in proprietary software under
10 * the Blender License. See http://www.blender.org/BL/ for information
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23 * All rights reserved.
25 * This is a new part of Blender.
27 * Contributor(s): Willian P. Germano
29 * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 #include <BKE_utildefines.h>
33 #include <BLI_blenlib.h>
36 #include "gen_utils.h"
39 /*****************************************************************************/
40 /* Python API function prototypes for the sys module. */
41 /*****************************************************************************/
42 static PyObject *M_sys_basename (PyObject *self, PyObject *args);
43 static PyObject *M_sys_dirname (PyObject *self, PyObject *args);
44 static PyObject *M_sys_splitext (PyObject *self, PyObject *args);
45 static PyObject *M_sys_makename (PyObject *self, PyObject *args, PyObject *kw);
46 static PyObject *M_sys_exists (PyObject *self, PyObject *args);
47 static PyObject *M_sys_time (PyObject *self);
49 /*****************************************************************************/
50 /* The following string definitions are used for documentation strings. */
51 /* In Python these will be written to the console when doing a */
52 /* Blender.sys.__doc__ */
53 /*****************************************************************************/
54 static char M_sys_doc[] =
55 "The Blender.sys submodule\n\
57 This is a minimal system module to supply simple functionality available\n\
58 in the default Python module os.";
60 static char M_sys_basename_doc[] =
61 "(path) - Split 'path' in dir and filename.\n\
62 Return the filename.";
64 static char M_sys_dirname_doc[] =
65 "(path) - Split 'path' in dir and filename.\n\
68 static char M_sys_splitext_doc[] =
69 "(path) - Split 'path' in root and extension:\n\
70 /this/that/file.ext -> ('/this/that/file','.ext').\n\
71 Return the pair (root, extension).";
73 static char M_sys_makename_doc[] =
74 "(path = Blender.Get('filename'), ext = \"\", strip = 0) -\n\
75 Strip dir and extension from path, leaving only a name, then append 'ext'\n\
76 to it (if given) and return the resulting string.\n\n\
77 (path) - string: a pathname -- Blender.Get('filename') if 'path' isn't given;\n\
78 (ext = \"\") - string: the extension to append.\n\
79 (strip = 0) - int: strip dirname from 'path' if given and non-zero.\n\
80 Ex: makename('/path/to/file/myfile.foo','-01.abc') returns 'myfile-01.abc'\n\
81 Ex: makename(ext='.txt') returns 'untitled.txt' if Blender.Get('filename')\n\
82 returns a path to the file 'untitled.blend'";
84 static char M_sys_time_doc[] =
85 "() - Return a float representing time elapsed in seconds.\n\
86 Each successive call is garanteed to return values greater than or\n\
87 equal to the previous call.";
89 static char M_sys_exists_doc[] =
90 "(path) - Return 1 if given pathname (file or dir) exists, 0 otherwise.";
92 /*****************************************************************************/
93 /* Python method structure definition for Blender.sys module: */
94 /*****************************************************************************/
95 struct PyMethodDef M_sys_methods[] = {
96 {"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
97 {"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
98 {"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
99 {"makename", (PyCFunction)M_sys_makename, METH_VARARGS|METH_KEYWORDS,
101 {"exists", M_sys_exists, METH_VARARGS, M_sys_exists_doc},
102 {"time", (PyCFunction)M_sys_time, METH_NOARGS, M_sys_time_doc},
103 {NULL, NULL, 0, NULL}
106 /* Module Functions */
108 static PyObject *g_sysmodule = NULL; /* pointer to Blender.sys module */
110 PyObject *sys_Init (void)
112 PyObject *submodule, *dict, *sep;
114 submodule = Py_InitModule3("Blender.sys", M_sys_methods, M_sys_doc);
116 g_sysmodule = submodule;
118 dict = PyModule_GetDict(submodule);
121 sep = Py_BuildValue("s", "\\");
123 sep = Py_BuildValue("s", "/");
128 PyDict_SetItemString(dict, "dirsep" , sep);
129 PyDict_SetItemString(dict, "sep" , sep);
135 static PyObject *M_sys_basename (PyObject *self, PyObject *args)
139 char *name, *p, basename[FILE_MAXFILE];
143 if (!PyArg_ParseTuple(args, "s", &name))
144 return EXPP_ReturnPyObjError (PyExc_TypeError,
145 "expected string argument");
149 c = PyObject_GetAttrString (g_sysmodule, "dirsep");
150 sep = PyString_AsString(c)[0];
153 p = strrchr(name, sep);
156 n = name + len - p - 1; /* - 1 because we don't want the sep */
158 if (n > FILE_MAXFILE)
159 return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
161 BLI_strncpy(basename, p+1, n); /* + 1 to skip the sep */
163 return Py_BuildValue("s", basename);
166 return Py_BuildValue("s", name);
169 static PyObject *M_sys_dirname (PyObject *self, PyObject *args)
173 char *name, *p, dirname[FILE_MAXDIR];
177 if (!PyArg_ParseTuple(args, "s", &name))
178 return EXPP_ReturnPyObjError (PyExc_TypeError,
179 "expected string argument");
181 c = PyObject_GetAttrString (g_sysmodule, "dirsep");
182 sep = PyString_AsString(c)[0];
185 p = strrchr(name, sep);
191 return EXPP_ReturnPyObjError (PyExc_RuntimeError, "path too long");
193 BLI_strncpy(dirname, name, n);
195 return Py_BuildValue("s", dirname);
198 return Py_BuildValue("s", ".");
201 static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
205 char *name, *dot, *p, path[FILE_MAXFILE], ext[FILE_MAXFILE];
209 if (!PyArg_ParseTuple(args, "s", &name))
210 return EXPP_ReturnPyObjError (PyExc_TypeError,
211 "expected string argument");
215 c = PyObject_GetAttrString (g_sysmodule, "dirsep");
216 sep = PyString_AsString(c)[0];
219 dot = strrchr(name, '.');
221 if (!dot) return Py_BuildValue("ss", name, "");
223 p = strrchr(name, sep);
226 if (p > dot) return Py_BuildValue("ss", name, "");
229 n = name + len - dot;
231 /* loong extensions are supported -- foolish, but Python's os.path.splitext
232 * supports them, so ... */
233 if (n > FILE_MAXFILE || (len - n ) > FILE_MAXFILE)
234 EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
236 BLI_strncpy(ext, dot, n);
238 BLI_strncpy(path, name, dot - name);
239 path[dot - name] = '\0';
241 return Py_BuildValue("ss", path, ext);
244 static PyObject *M_sys_makename(PyObject *self, PyObject *args, PyObject *kw)
246 char *path = G.sce, *ext = NULL;
248 static char *kwlist[] = {"path", "ext", "strip", NULL};
249 char *dot = NULL, *p = NULL, basename[FILE_MAXFILE];
251 int n, len, lenext = 0;
254 if (!PyArg_ParseTupleAndKeywords(args, kw, "|ssi", kwlist,
255 &path, &ext, &strip))
256 return EXPP_ReturnPyObjError (PyExc_TypeError,
257 "expected one or two strings and an int (or nothing) as arguments");
260 if (ext) lenext = strlen(ext);
262 if ((len + lenext) > FILE_MAXFILE)
263 return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
265 c = PyObject_GetAttrString (g_sysmodule, "dirsep");
266 sep = PyString_AsString(c)[0];
269 p = strrchr(path, sep);
272 n = path + len - p - 1; /* - 1 because we don't want the sep */
274 BLI_strncpy(basename, p+1, n); /* + 1 to skip the sep */
278 BLI_strncpy(basename, path, len);
283 dot = strrchr(basename, '.');
285 /* now the extension: always remove the one in basename */
288 basename[dot - basename] = '\0';
289 else { /* if user gave an ext, append it */
291 if (dot) n = dot - basename;
292 else n = strlen(basename);
294 BLI_strncpy(basename + n, ext, lenext);
295 basename[n+lenext] = '\0';
299 return PyString_FromString(basename);
302 static PyObject *M_sys_time (PyObject *self)
304 double t = PIL_check_seconds_timer();
305 return Py_BuildValue("d", t);
308 static PyObject *M_sys_exists (PyObject *self, PyObject *args)
313 if (!PyArg_ParseTuple(args, "s", &fname))
314 return EXPP_ReturnPyObjError (PyExc_TypeError,
315 "expected string (file path) argument");
317 i = BLI_exists(fname);
319 if (i) return Py_BuildValue("i", 1); /* path was found */
321 return Py_BuildValue("i", 0); /* path doesn't exist */