1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  */
9 
10 #include "root/dsystem.h"
11 #include "mars.h"
12 #include "globals.h"
13 #include "root/file.h"
14 #include "root/filename.h"
15 #include "root/outbuffer.h"
16 #include "root/rmem.h"
17 
18 /**
19  * Normalize path by turning forward slashes into backslashes
20  *
21  * Params:
22  *   src = Source path, using unix-style ('/') path separators
23  *
24  * Returns:
25  *   A newly-allocated string with '/' turned into backslashes
26  */
toWinPath(const char * src)27 const char * toWinPath(const char *src)
28 {
29     if (src == NULL)
30         return NULL;
31 
32     char *result = mem.xstrdup(src);
33     char *p = result;
34     while (*p != '\0')
35     {
36         if (*p == '/')
37             *p = '\\';
38         p++;
39     }
40     return result;
41 }
42 
43 /**
44  * Reads a file, terminate the program on error
45  *
46  * Params:
47  *   loc = The line number information from where the call originates
48  *   f = a `ddmd.root.file.File` handle to read
49  */
readFile(Loc loc,File * f)50 void readFile(Loc loc, File *f)
51 {
52     if (f->read())
53     {
54         error(loc, "Error reading file '%s'", f->name->toChars());
55         fatal();
56     }
57 }
58 
59 /**
60  * Writes a file, terminate the program on error
61  *
62  * Params:
63  *   loc = The line number information from where the call originates
64  *   f = a `ddmd.root.file.File` handle to write
65  */
writeFile(Loc loc,File * f)66 void writeFile(Loc loc, File *f)
67 {
68     if (f->write())
69     {
70         error(loc, "Error writing file '%s'", f->name->toChars());
71         fatal();
72     }
73 }
74 
75 /**
76  * Ensure the root path (the path minus the name) of the provided path
77  * exists, and terminate the process if it doesn't.
78  *
79  * Params:
80  *   loc = The line number information from where the call originates
81  *   name = a path to check (the name is stripped)
82  */
ensurePathToNameExists(Loc loc,const char * name)83 void ensurePathToNameExists(Loc loc, const char *name)
84 {
85     const char *pt = FileName::path(name);
86     if (*pt)
87     {
88         if (FileName::ensurePathExists(pt))
89         {
90             error(loc, "cannot create directory %s", pt);
91             fatal();
92         }
93     }
94     FileName::free(pt);
95 }
96 
97 /**
98  * Takes a path, and escapes '(', ')' and backslashes
99  *
100  * Params:
101  *   buf = Buffer to write the escaped path to
102  *   fname = Path to escape
103  */
escapePath(OutBuffer * buf,const char * fname)104 void escapePath(OutBuffer *buf, const char *fname)
105 {
106     while (1)
107     {
108         switch (*fname)
109         {
110             case 0:
111                 return;
112             case '(':
113             case ')':
114             case '\\':
115                 buf->writeByte('\\');
116                 /* fall through */
117             default:
118                 buf->writeByte(*fname);
119                 break;
120         }
121         fname++;
122     }
123 }
124