1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/***
6*tmakepath_s.inl - general implementation of _tmakepath_s
7*
8
9*
10*Purpose:
11* This file contains the general algorithm for _makepath_s and its variants.
12*
13*******************************************************************************/
14
15_FUNC_PROLOGUE
16errno_t __cdecl _FUNC_NAME(__out_ecount_z(_SIZE) _CHAR *_DEST, __in_opt size_t _SIZE, __in_z_opt const _CHAR *_Drive, __in_z_opt const _CHAR *_Dir, __in_z_opt const _CHAR *_Filename, __in_z_opt const _CHAR *_Ext)
17{
18 size_t written;
19 const _CHAR *p;
20 _CHAR *d;
21
22 /* validation section */
23 _VALIDATE_STRING(_DEST, _SIZE);
24
25 /* copy drive */
26 written = 0;
27 d = _DEST;
28 if (_Drive != NULL && *_Drive != 0)
29 {
30 written += 2;
31 if(written >= _SIZE)
32 {
33 goto error_return;
34 }
35 *d++ = *_Drive;
36 *d++ = _T(':');
37 }
38
39 /* copy dir */
40 p = _Dir;
41 if (p != NULL && *p != 0)
42 {
43 do {
44 if(++written >= _SIZE)
45 {
46 goto error_return;
47 }
48 *d++ = *p++;
49 } while (*p != 0);
50
51#if _MBS_SUPPORT
52 p = _MBSDEC(_Dir, p);
53#else /* _MBS_SUPPORT */
54 p = p - 1;
55#endif /* _MBS_SUPPORT */
56 if (*p != _T('/') && *p != _T('\\'))
57 {
58 if(++written >= _SIZE)
59 {
60 goto error_return;
61 }
62 *d++ = _T('\\');
63 }
64 }
65
66 /* copy fname */
67 p = _Filename;
68 if (p != NULL)
69 {
70 while (*p != 0)
71 {
72 if(++written >= _SIZE)
73 {
74 goto error_return;
75 }
76 *d++ = *p++;
77 }
78 }
79
80 /* copy extension; check to see if a '.' needs to be inserted */
81 p = _Ext;
82 if (p != NULL)
83 {
84 if (*p != 0 && *p != _T('.'))
85 {
86 if(++written >= _SIZE)
87 {
88 goto error_return;
89 }
90 *d++ = _T('.');
91 }
92 while (*p != 0)
93 {
94 if(++written >= _SIZE)
95 {
96 goto error_return;
97 }
98 *d++ = *p++;
99 }
100 }
101
102 if(++written > _SIZE)
103 {
104 goto error_return;
105 }
106 *d = 0;
107 _FILL_STRING(_DEST, _SIZE, written);
108 _RETURN_NO_ERROR;
109
110error_return:
111 _RESET_STRING(_DEST, _SIZE);
112 _RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
113
114 /* should never happen, but compiler can't tell */
115 return EINVAL;
116}
117