1 /* Copyright (C) 1993, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gsfname.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
18 /* File name utilities */
19 #include "memory_.h"
20 #include "gserror.h"
21 #include "gserrors.h"
22 #include "gsmemory.h"
23 #include "gstypes.h"
24 #include "gsfname.h"
25 #include "gxiodev.h"
26
27 /* Parse a file name into device and individual name. */
28 /* The device may be NULL, or the name may be NULL, but not both. */
29 /* According to the Adobe documentation, %device and %device% */
30 /* are equivalent; both return name==NULL. */
31 int
gs_parse_file_name(gs_parsed_file_name_t * pfn,const char * pname,uint len)32 gs_parse_file_name(gs_parsed_file_name_t * pfn, const char *pname, uint len)
33 {
34 uint dlen;
35 const char *pdelim;
36 gx_io_device *iodev;
37
38 if (len == 0)
39 return_error(gs_error_undefinedfilename); /* null name not allowed */
40 if (pname[0] != '%') { /* no device */
41 pfn->memory = 0;
42 pfn->iodev = NULL;
43 pfn->fname = pname;
44 pfn->len = len;
45 return 0;
46 }
47 pdelim = memchr(pname + 1, '%', len - 1);
48 if (pdelim == NULL) /* %device */
49 dlen = len;
50 else if (pdelim[1] == 0) { /* %device% */
51 pdelim = NULL;
52 dlen = len;
53 } else {
54 dlen = pdelim - pname;
55 pdelim++, len--;
56 }
57 iodev = gs_findiodevice((const byte *)pname, dlen);
58 if (iodev == 0)
59 return_error(gs_error_undefinedfilename);
60 pfn->memory = 0;
61 pfn->iodev = iodev;
62 pfn->fname = pdelim;
63 pfn->len = len - dlen;
64 return 0;
65 }
66
67 /* Parse a real (non-device) file name and convert to a C string. */
68 int
gs_parse_real_file_name(gs_parsed_file_name_t * pfn,const char * pname,uint len,gs_memory_t * mem,client_name_t cname)69 gs_parse_real_file_name(gs_parsed_file_name_t * pfn, const char *pname,
70 uint len, gs_memory_t *mem, client_name_t cname)
71 {
72 int code = gs_parse_file_name(pfn, pname, len);
73
74 if (code < 0)
75 return code;
76 if (pfn->len == 0)
77 return_error(gs_error_invalidfileaccess); /* device only */
78 return gs_terminate_file_name(pfn, mem, cname);
79 }
80
81 /* Convert a file name to a C string by adding a null terminator. */
82 int
gs_terminate_file_name(gs_parsed_file_name_t * pfn,gs_memory_t * mem,client_name_t cname)83 gs_terminate_file_name(gs_parsed_file_name_t * pfn, gs_memory_t *mem,
84 client_name_t cname)
85 {
86 uint len = pfn->len;
87 char *fname;
88
89 if (pfn->iodev == NULL) /* no device */
90 pfn->iodev = iodev_default;
91 if (pfn->memory)
92 return 0; /* already copied */
93 /* Copy the file name to a C string. */
94 fname = (char *)gs_alloc_string(mem, len + 1, cname);
95 if (fname == 0)
96 return_error(gs_error_VMerror);
97 memcpy(fname, pfn->fname, len);
98 fname[len] = 0;
99 pfn->memory = mem;
100 pfn->fname = fname;
101 pfn->len = len + 1; /* null terminator */
102 return 0;
103 }
104
105 /* Free a file name that was copied to a C string. */
106 void
gs_free_file_name(gs_parsed_file_name_t * pfn,client_name_t cname)107 gs_free_file_name(gs_parsed_file_name_t * pfn, client_name_t cname)
108 {
109 if (pfn->fname != 0)
110 gs_free_const_string(pfn->memory, (const byte *)pfn->fname, pfn->len,
111 cname);
112 }
113