diff options
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/Edge.m | 1 | ||||
-rw-r--r-- | src/common/RegularPolyShape.m | 1 | ||||
-rw-r--r-- | src/common/tikzlexer.lm | 2 | ||||
-rw-r--r-- | src/common/tikzparser.ym | 8 | ||||
-rw-r--r-- | src/common/util.h | 4 | ||||
-rw-r--r-- | src/linux/CairoRenderContext.m | 3 | ||||
-rw-r--r-- | src/linux/NSFileManager+Glib.m | 1 | ||||
-rw-r--r-- | src/linux/mkdtemp.h | 32 | ||||
-rw-r--r-- | src/linux/mkdtemp.m | 204 |
11 files changed, 253 insertions, 10 deletions
diff --git a/configure.ac b/configure.ac index 5814ad5..eba5901 100644 --- a/configure.ac +++ b/configure.ac @@ -80,16 +80,18 @@ AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_INT8_T AC_TYPE_SIZE_T -AC_HEADER_STDBOOL AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T +AC_HEADER_STDBOOL +AC_HEADER_STAT +AC_CHECK_HEADERS([stdint.h inttypes.h unistd.h sys/time.h time.h]) # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS([floor memset sqrt strdup]) +AC_CHECK_FUNCS([floor gettimeofday memset mkdtemp sqrt strdup]) TZ_OBJC2_FEATURES AS_IF([test "x$tz_cv_objc_properties$tz_cv_objc_fast_enumeration$tz_cv_objc_optional_keyword" != "xyesyesyes"], diff --git a/src/Makefile.am b/src/Makefile.am index a520ee6..117bedf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,7 @@ tikzit_SOURCES = linux/CairoRenderContext.m \ linux/cairo_helpers.m \ linux/clipboard.m \ linux/gtkhelpers.m \ + linux/mkdtemp.m \ linux/main.m \ common/BasicMapTable.m \ common/CircleShape.m \ diff --git a/src/common/Edge.m b/src/common/Edge.m index 9ecfebc..c89be6d 100644 --- a/src/common/Edge.m +++ b/src/common/Edge.m @@ -24,7 +24,6 @@ #import "Edge.h" #import "util.h" - @implementation Edge - (id)init { diff --git a/src/common/RegularPolyShape.m b/src/common/RegularPolyShape.m index a369ae1..cd5858c 100644 --- a/src/common/RegularPolyShape.m +++ b/src/common/RegularPolyShape.m @@ -24,6 +24,7 @@ #import "RegularPolyShape.h" #import "Node.h" #import "Edge.h" +#import "util.h" @implementation RegularPolyShape diff --git a/src/common/tikzlexer.lm b/src/common/tikzlexer.lm index ef1cf8e..4fe39d1 100644 --- a/src/common/tikzlexer.lm +++ b/src/common/tikzlexer.lm @@ -67,7 +67,7 @@ at return AT; \\?[a-zA-Z<>\-\']+ { //' yylval.nsstr=[NSString stringWithUTF8String:yytext]; - return WORD; + return LWORD; } diff --git a/src/common/tikzparser.ym b/src/common/tikzparser.ym index fe8e1d9..e55a881 100644 --- a/src/common/tikzparser.ym +++ b/src/common/tikzparser.ym @@ -60,7 +60,7 @@ extern void yyerror(const char *str); %token AT %token REALNUMBER %token NATURALNUMBER -%token WORD +%token LWORD %token QUOTEDSTRING %token DELIMITEDSTRING @@ -113,7 +113,7 @@ propsyms: }; propsym: - WORD { $$ = $<nsstr>1; } + LWORD { $$ = $<nsstr>1; } | number { $$ = $<nsstr>1; }; @@ -138,7 +138,7 @@ nodelabel: optanchor: | ANCHORCENTER; nodename: LEFTPARENTHESIS nodeid optanchor RIGHTPARENTHESIS { $$ = $<nsstr>2; }; -nodeid: WORD { $$ = $<nsstr>1; } | NATURALNUMBER { $$ = $<nsstr>1; }; +nodeid: LWORD { $$ = $<nsstr>1; } | NATURALNUMBER { $$ = $<nsstr>1; }; coords: LEFTPARENTHESIS number COMMA number RIGHTPARENTHESIS @@ -166,7 +166,7 @@ optedgenode: } bbox_ignoreprops: - | LEFTBRACKET WORD WORD WORD WORD RIGHTBRACKET; + | LEFTBRACKET LWORD LWORD LWORD LWORD RIGHTBRACKET; boundingbox: PATH bbox_ignoreprops coords RECTANGLE coords SEMICOLON diff --git a/src/common/util.h b/src/common/util.h index 652278e..74871dc 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -22,6 +22,10 @@ #include <math.h> +#ifndef M_PI +#define M_PI 3.141592654 +#endif + /*! @brief Compute a bounding rectangle for two given points. @param p1 a point. diff --git a/src/linux/CairoRenderContext.m b/src/linux/CairoRenderContext.m index 550a1a3..bed06a6 100644 --- a/src/linux/CairoRenderContext.m +++ b/src/linux/CairoRenderContext.m @@ -18,10 +18,9 @@ #import "CairoRenderContext.h" #import "cairo_helpers.h" +#import "util.h" #import <pango/pangocairo.h> -// for M_PI: -#import <math.h> @implementation PangoTextLayout diff --git a/src/linux/NSFileManager+Glib.m b/src/linux/NSFileManager+Glib.m index 01c3eaa..b3e9de6 100644 --- a/src/linux/NSFileManager+Glib.m +++ b/src/linux/NSFileManager+Glib.m @@ -17,6 +17,7 @@ #import "NSFileManager+Glib.h" #import "TZFoundation.h" +#import "mkdtemp.h" @implementation NSFileManager(Glib) diff --git a/src/linux/mkdtemp.h b/src/linux/mkdtemp.h new file mode 100644 index 0000000..65ee99e --- /dev/null +++ b/src/linux/mkdtemp.h @@ -0,0 +1,32 @@ +/* Creating a private temporary directory. + Copyright (C) 2001-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if HAVE_MKDTEMP + +/* Get mkdtemp() declaration. */ +#include <stdlib.h> + +#else + +/* Create a unique temporary directory from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the directory name unique. + Returns TEMPLATE, or a null pointer if it cannot get a unique name. + The directory is created mode 700. */ +extern char * mkdtemp (char *template); + +#endif diff --git a/src/linux/mkdtemp.m b/src/linux/mkdtemp.m new file mode 100644 index 0000000..0866e54 --- /dev/null +++ b/src/linux/mkdtemp.m @@ -0,0 +1,204 @@ +/* Copyright (C) 1999, 2001-2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Extracted from misc/mkdtemp.c and sysdeps/posix/tempname.c. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Specification. */ +#include "mkdtemp.h" + +#include <errno.h> +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include <stdio.h> +#ifndef TMP_MAX +# define TMP_MAX 238328 +#endif + +#if HAVE_STDINT_H || _LIBC +# include <stdint.h> +#endif +#if HAVE_INTTYPES_H +# include <inttypes.h> +#endif + +#if HAVE_UNISTD_H || _LIBC +# include <unistd.h> +#endif + +#if HAVE_GETTIMEOFDAY || _LIBC +# if HAVE_SYS_TIME_H || _LIBC +# include <sys/time.h> +# endif +#else +# if HAVE_TIME_H || _LIBC +# include <time.h> +# endif +#endif + +#include <sys/stat.h> +#if STAT_MACROS_BROKEN +# undef S_ISDIR +#endif +#if !defined S_ISDIR && defined S_IFDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#if !S_IRUSR && S_IREAD +# define S_IRUSR S_IREAD +#endif +#if !S_IRUSR +# define S_IRUSR 00400 +#endif +#if !S_IWUSR && S_IWRITE +# define S_IWUSR S_IWRITE +#endif +#if !S_IWUSR +# define S_IWUSR 00200 +#endif +#if !S_IXUSR && S_IEXEC +# define S_IXUSR S_IEXEC +#endif +#if !S_IXUSR +# define S_IXUSR 00100 +#endif + +#ifdef __MINGW32__ +/* mingw's mkdir() function has 1 argument, but we pass 2 arguments. + Therefore we have to disable the argument count checking. */ +# define mkdir ((int (*)()) mkdir) +#endif + +#if !_LIBC +# define __getpid getpid +# define __gettimeofday gettimeofday +# define __mkdir mkdir +#endif + +/* Use the widest available unsigned type if uint64_t is not + available. The algorithm below extracts a number less than 62**6 + (approximately 2**35.725) from uint64_t, so ancient hosts where + uintmax_t is only 32 bits lose about 3.725 bits of randomness, + which is better than not having mkstemp at all. */ +#if !defined UINT64_MAX && !defined uint64_t +# define uint64_t uintmax_t +#endif + +/* These are the characters used in temporary filenames. */ +static const char letters[] = +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed + does not exist at the time of the call to __gen_tempname. TMPL is + overwritten with the result. + + KIND is: + __GT_DIR: create a directory, which will be mode 0700. + + We use a clever algorithm to get hard-to-predict names. */ +static int +gen_tempname (char *tmpl) +{ + int len; + char *XXXXXX; + static uint64_t value; + uint64_t random_time_bits; + int count, fd = -1; + int save_errno = errno; + + len = strlen (tmpl); + if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) + { + __set_errno (EINVAL); + return -1; + } + + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6]; + + /* Get some more or less random data. */ +#ifdef RANDOM_BITS + RANDOM_BITS (random_time_bits); +#else +# if HAVE_GETTIMEOFDAY || _LIBC + { + struct timeval tv; + __gettimeofday (&tv, NULL); + random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; + } +# else + random_time_bits = time (NULL); +# endif +#endif + value += random_time_bits ^ __getpid (); + + for (count = 0; count < TMP_MAX; value += 7777, ++count) + { + uint64_t v = value; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % 62]; + v /= 62; + XXXXXX[1] = letters[v % 62]; + v /= 62; + XXXXXX[2] = letters[v % 62]; + v /= 62; + XXXXXX[3] = letters[v % 62]; + v /= 62; + XXXXXX[4] = letters[v % 62]; + v /= 62; + XXXXXX[5] = letters[v % 62]; + + fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); + + if (fd >= 0) + { + __set_errno (save_errno); + return fd; + } + else if (errno != EEXIST) + return -1; + } + + /* We got out of the loop because we ran out of combinations to try. */ + __set_errno (EEXIST); + return -1; +} + +/* Generate a unique temporary directory from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + The directory is created, mode 700, and its name is returned. + (This function comes from OpenBSD.) */ +char * +mkdtemp (char *template) +{ + if (gen_tempname (template)) + return NULL; + else + return template; +} |