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