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