10eb10989Smrg/*
20eb10989Smrg
30eb10989SmrgCopyright (c) 1993, 1994, 1998 The Open Group
40eb10989Smrg
50eb10989SmrgPermission to use, copy, modify, distribute, and sell this software and its
60eb10989Smrgdocumentation for any purpose is hereby granted without fee, provided that
70eb10989Smrgthe above copyright notice appear in all copies and that both that
80eb10989Smrgcopyright notice and this permission notice appear in supporting
90eb10989Smrgdocumentation.
100eb10989Smrg
110eb10989SmrgThe above copyright notice and this permission notice shall be included in
120eb10989Smrgall copies or substantial portions of the Software.
130eb10989Smrg
140eb10989SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
150eb10989SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
160eb10989SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
170eb10989SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
180eb10989SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
190eb10989SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
200eb10989Smrg
210eb10989SmrgExcept as contained in this notice, the name of The Open Group shall not be
220eb10989Smrgused in advertising or otherwise to promote the sale, use or other dealings
230eb10989Smrgin this Software without prior written authorization from The Open Group.
240eb10989Smrg
250eb10989Smrg*/
260eb10989Smrg
270eb10989Smrg#include "def.h"
280eb10989Smrg
290eb10989Smrgvoid
30d43532a6Smrgadd_include(struct filepointer *filep, struct inclist *file,
31fadff096Smrg            struct inclist *file_red, const char *include, int type,
32fadff096Smrg            boolean failOK)
330eb10989Smrg{
34fadff096Smrg    struct inclist *newfile;
35fadff096Smrg
36fadff096Smrg    /*
37fadff096Smrg     * First decide what the pathname of this include file really is.
38fadff096Smrg     */
39fadff096Smrg    newfile = inc_path(file->i_file, include, type);
40fadff096Smrg    if (newfile == NULL) {
41fadff096Smrg        if (failOK)
42fadff096Smrg            return;
43fadff096Smrg        if (file != file_red)
44fadff096Smrg            warning("%s (reading %s, line %ld): ",
45fadff096Smrg                    file_red->i_file, file->i_file, filep->f_line);
46fadff096Smrg        else
47fadff096Smrg            warning("%s, line %ld: ", file->i_file, filep->f_line);
48fadff096Smrg        warning1("cannot find include file \"%s\"\n", include);
49fadff096Smrg        show_where_not = TRUE;
50fadff096Smrg        newfile = inc_path(file->i_file, include, type);
51fadff096Smrg        show_where_not = FALSE;
52fadff096Smrg    }
53fadff096Smrg
54fadff096Smrg    if (newfile) {
55fadff096Smrg        included_by(file, newfile);
56fadff096Smrg        if (!(newfile->i_flags & SEARCHED)) {
57fadff096Smrg            struct filepointer *content;
58fadff096Smrg
59fadff096Smrg            newfile->i_flags |= SEARCHED;
60fadff096Smrg            content = getfile(newfile->i_file);
61fadff096Smrg            find_includes(content, newfile, file_red, 0, failOK);
62fadff096Smrg            freefile(content);
63fadff096Smrg        }
64fadff096Smrg    }
650eb10989Smrg}
660eb10989Smrg
67b2f5b1dbSmrg/**
68b2f5b1dbSmrg * Replaces all ":" occurrences in @p input with "\:" using @p outputbuffer (of size @p bufsize)
69b2f5b1dbSmrg * possibly to hold the result. @p returns the string with quoted colons
70b2f5b1dbSmrg */
71b2f5b1dbSmrgstatic const char *
72b2f5b1dbSmrgquoteColons(const char *input, char *outputbuffer, size_t bufsize)
73b2f5b1dbSmrg{
74fadff096Smrg    const char *tmp;
75fadff096Smrg    const char *loc;
76fadff096Smrg    char *output = outputbuffer;
77fadff096Smrg
78fadff096Smrg    loc = strchr(input, ':');
79fadff096Smrg    if (loc == NULL) {
80fadff096Smrg        return input;
81fadff096Smrg    }
82fadff096Smrg
83fadff096Smrg    tmp = input;
84fadff096Smrg    while (loc != NULL && bufsize > loc - tmp + 2) {
85fadff096Smrg        memcpy(output, tmp, loc - tmp);
86fadff096Smrg        output += loc - tmp;
87fadff096Smrg        bufsize -= loc - tmp + 2;
88fadff096Smrg        tmp = loc + 1;
89fadff096Smrg        *output = '\\';
90fadff096Smrg        output++;
91fadff096Smrg        *output = ':';
92fadff096Smrg        output++;
93fadff096Smrg        loc = strchr(tmp, ':');
94fadff096Smrg    }
95fadff096Smrg
96fadff096Smrg    if (strlen(tmp) <= bufsize)
97fadff096Smrg        strcpy(output, tmp);
98fadff096Smrg    else {
99fadff096Smrg        strncpy(output, tmp, bufsize - 1);
100fadff096Smrg        output[bufsize] = 0;
101fadff096Smrg    }
102fadff096Smrg    return outputbuffer;
103b2f5b1dbSmrg}
104b2f5b1dbSmrg
1050eb10989Smrgstatic void
10663165362Smrgpr(struct inclist *ip, const char *file, const char *base)
1070eb10989Smrg{
108fadff096Smrg    static const char *lastfile;
109fadff096Smrg    static int current_len;
110fadff096Smrg    int len;
111fadff096Smrg    const char *quoted;
112fadff096Smrg    char quotebuf[BUFSIZ];
113fadff096Smrg
114fadff096Smrg    printed = TRUE;
115fadff096Smrg    quoted = quoteColons(ip->i_file, quotebuf, sizeof(quotebuf));
116fadff096Smrg    len = strlen(quoted) + 1;
117fadff096Smrg    if (current_len + len > width || file != lastfile) {
118fadff096Smrg        lastfile = file;
119fadff096Smrg        current_len = fprintf(stdout, "\n%s%s%s: %s",
120fadff096Smrg                              objprefix, base, objsuffix, quoted);
121fadff096Smrg    }
122fadff096Smrg    else {
123fadff096Smrg        fprintf(stdout, " %s", quoted);
124fadff096Smrg        current_len += len;
125fadff096Smrg    }
126fadff096Smrg
127fadff096Smrg    /*
128fadff096Smrg     * If verbose is set, then print out what this file includes.
129fadff096Smrg     */
130fadff096Smrg    if (!verbose || ip->i_list == NULL || ip->i_flags & NOTIFIED)
131fadff096Smrg        return;
132fadff096Smrg    ip->i_flags |= NOTIFIED;
133fadff096Smrg    lastfile = NULL;
134fadff096Smrg    printf("\n# %s includes:", ip->i_file);
135fadff096Smrg    for (unsigned int i = 0; i < ip->i_listlen; i++)
136fadff096Smrg        printf("\n#\t%s", ip->i_list[i]->i_incstring);
1370eb10989Smrg}
1380eb10989Smrg
1390eb10989Smrgvoid
14063165362Smrgrecursive_pr_include(struct inclist *head, const char *file, const char *base)
1410eb10989Smrg{
142fadff096Smrg    if (head->i_flags & MARKED)
143fadff096Smrg        return;
144fadff096Smrg    head->i_flags |= MARKED;
145fadff096Smrg    if (head->i_file != file)
146fadff096Smrg        pr(head, file, base);
147fadff096Smrg    for (unsigned int i = 0; i < head->i_listlen; i++)
148fadff096Smrg        recursive_pr_include(head->i_list[i], file, base);
1490eb10989Smrg}
150