xref: /plan9/sys/src/cmd/gs/src/gsfname.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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