1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: zfile1.c 9043 2008-08-28 22:48:19Z giles $ */
15 /* Special file operators */
16 
17 #include "memory_.h"
18 #include "string_.h"
19 #include "ghost.h"
20 #include "gp.h"
21 #include "ierrors.h"
22 #include "oper.h"
23 #include "ialloc.h"
24 #include "opdef.h"
25 #include "opcheck.h"
26 #include "store.h"
27 #include "gpmisc.h"
28 
29 /* <string> <string> <bool> .file_name_combine <string> true */
30 /* <string> <string> <bool> .file_name_combine <string> <string> false */
31 static int
zfile_name_combine(i_ctx_t * i_ctx_p)32 zfile_name_combine(i_ctx_t *i_ctx_p)
33 {
34     uint plen, flen, blen, blen0;
35     const byte *prefix, *fname;
36     byte *buffer;
37     os_ptr op = osp;
38     bool no_sibling;
39 
40     check_type(op[ 0], t_boolean);
41     check_type(op[-1], t_string);
42     check_type(op[-2], t_string);
43     plen = r_size(op - 2);
44     flen = r_size(op - 1);
45     blen = blen0 = plen + flen + 2; /* Inserts separator and ending zero byte. */
46     buffer = ialloc_string(blen, "zfile_name_combine");
47     if (buffer == 0)
48 	return_error(e_VMerror);
49     prefix = op[-2].value.const_bytes;
50     fname =  op[-1].value.const_bytes;
51     no_sibling = op[0].value.boolval;
52     if (gp_file_name_combine((const char *)prefix, plen,
53 			     (const char *)fname, flen, no_sibling,
54 		             (char *)buffer, &blen) != gp_combine_success) {
55 	make_bool(op, false);
56     } else {
57 	buffer = iresize_string(buffer, blen0, blen, "zfile_name_combine");
58 	if (buffer == 0)
59 	    return_error(e_VMerror);
60 	make_string(op - 2, a_all | icurrent_space, blen, buffer);
61 	make_bool(op - 1, true);
62 	pop(1);
63     }
64     return 0;
65 }
66 
67 /* This is compiled conditionally to let PS library to know
68  * whether it works with the new gp_combine_file_name.
69  */
70 
71 /* <string> .file_name_is_absolute <bool> */
72 static int
zfile_name_is_absolute(i_ctx_t * i_ctx_p)73 zfile_name_is_absolute(i_ctx_t *i_ctx_p)
74 {   os_ptr op = osp;
75 
76     check_type(op[0], t_string);
77     make_bool(op, gp_file_name_is_absolute((const char *)op->value.const_bytes,
78 					r_size(op)));
79     return 0;
80 }
81 
82 static int
push_string(i_ctx_t * i_ctx_p,const char * v)83 push_string(i_ctx_t *i_ctx_p, const char *v)
84 {   os_ptr op = osp;
85     int len = strlen(v);
86 
87     push(1);
88     make_const_string(op, avm_foreign | a_readonly,
89 		      len, (const byte *)v);
90     return 0;
91 }
92 
93 /* - .file_name_separator <string> */
94 static int
zfile_name_separator(i_ctx_t * i_ctx_p)95 zfile_name_separator(i_ctx_t *i_ctx_p)
96 {   return push_string(i_ctx_p, gp_file_name_separator());
97 }
98 
99 /* - .file_name_directory_separator <string> */
100 static int
zfile_name_directory_separator(i_ctx_t * i_ctx_p)101 zfile_name_directory_separator(i_ctx_t *i_ctx_p)
102 {   return push_string(i_ctx_p, gp_file_name_directory_separator());
103 }
104 
105 /* - .file_name_current <string> */
106 static int
zfile_name_current(i_ctx_t * i_ctx_p)107 zfile_name_current(i_ctx_t *i_ctx_p)
108 {   return push_string(i_ctx_p, gp_file_name_current());
109 }
110 
111 /* - .file_name_parent <string> */
112 static int
zfile_name_parent(i_ctx_t * i_ctx_p)113 zfile_name_parent(i_ctx_t *i_ctx_p)
114 {   return push_string(i_ctx_p, gp_file_name_parent());
115 }
116 
117 const op_def zfile1_op_defs[] =
118 {
119     {"0.file_name_combine", zfile_name_combine},
120     {"0.file_name_is_absolute", zfile_name_is_absolute},
121     {"0.file_name_separator", zfile_name_separator},
122     {"0.file_name_directory_separator", zfile_name_directory_separator},
123     {"0.file_name_current", zfile_name_current},
124     {"0.file_name_parent", zfile_name_parent},
125     op_def_end(0)
126 };
127 
128