summaryrefslogtreecommitdiff
path: root/solenv/bin/concat-deps.c
diff options
context:
space:
mode:
Diffstat (limited to 'solenv/bin/concat-deps.c')
-rw-r--r--solenv/bin/concat-deps.c147
1 files changed, 109 insertions, 38 deletions
diff --git a/solenv/bin/concat-deps.c b/solenv/bin/concat-deps.c
index 81a47929a266..813c39dd7be9 100644
--- a/solenv/bin/concat-deps.c
+++ b/solenv/bin/concat-deps.c
@@ -97,9 +97,11 @@
#ifdef __windows
#define FILE_O_RDONLY _O_RDONLY
#define FILE_O_BINARY _O_BINARY
+#define PATHNCMP strncasecmp /* MSVC converts paths to lower-case sometimes? */
#else /* not windaube */
#define FILE_O_RDONLY O_RDONLY
#define FILE_O_BINARY 0
+#define PATHNCMP strncmp
#endif /* not windaube */
#ifndef TRUE
@@ -111,7 +113,7 @@
int internal_boost = 0;
static char* base_dir;
-static char* out_dir;
+static char* work_dir;
#ifdef __GNUC__
#define clz __builtin_clz
@@ -711,18 +713,12 @@ static inline void eat_space(char ** token)
}
/*
- * Find substring in bounded length string
- */
-static inline const char *find_substr(const char *key, int key_len,
- const char *substr, int substr_len)
-{
-}
-
-/*
* Prune LibreOffice specific duplicate dependencies to improve
* gnumake startup time, and shrink the disk-space footprint.
*/
-static inline int elide_dependency(const char* key, int key_len, int *boost_count)
+static inline int
+elide_dependency(const char* key, int key_len,
+ int *boost_count, const char **unpacked_end)
{
#if 0
{
@@ -736,28 +732,52 @@ static inline int elide_dependency(const char* key, int key_len, int *boost_coun
#endif
/* .hdl files are always matched by .hpp */
- if (key_len > 4 && !strncmp(key + key_len - 4, ".hdl", 4))
+ if (key_len > 4 && !PATHNCMP(key + key_len - 4, ".hdl", 4))
return 1;
/* boost brings a plague of header files */
- if (internal_boost)
+ int i;
+ int boost = 0;
+ int unpacked = 0;
+ /* walk down path elements */
+ for (i = 0; i < key_len - 1; i++)
{
- int i;
- int hit = 0;
- /* walk down path elements */
- for (i = 0; i < key_len - 1; i++)
+ if (key[i] == '/')
{
- if (key[i] == '/')
+ if (internal_boost)
{
- if (!strncmp(key + i + 1, "solver/", 7))
- hit++;
- if (hit > 0 && !strncmp(key + i + 1, "inc/external/boost/", 19))
+ if (0 == boost)
+ {
+ if (!PATHNCMP(key + i + 1, "solver/", 7))
+ {
+ boost++;
+ continue;
+ }
+ }
+ else if (!PATHNCMP(key + i + 1, "inc/external/boost/", 19))
{
if (boost_count)
(*boost_count)++;
return 1;
}
}
+ if (0 == unpacked)
+ {
+ if (!PATHNCMP(key + i + 1, "workdir/", 8))
+ {
+ unpacked = 1;
+ continue;
+ }
+ }
+ else
+ {
+ if (!PATHNCMP(key + i + 1, "UnpackedTarball/", 16))
+ {
+ if (unpacked_end)
+ *unpacked_end = strchr(key + i + 17, '/');
+ return 1;
+ }
+ }
}
}
@@ -765,13 +785,23 @@ static inline int elide_dependency(const char* key, int key_len, int *boost_coun
}
/*
- * We collapse tens of internal boost headers to a single one, such
+ * We collapse tens of internal boost headers to the unpacked target, such
* that you can re-compile / install boost and all is well.
*/
static void emit_single_boost_header(void)
{
-#define BOOST_HEADER "/inc/external/boost/bind.hpp"
- fprintf(stdout, "%s" BOOST_HEADER " ", out_dir);
+#define BOOST_TARGET "/UnpackedTarball/boost.done"
+ fprintf(stdout, "%s" BOOST_TARGET " ", work_dir);
+}
+
+static void emit_unpacked_target(char const*const token, char const*const end)
+{
+ /* is there some obvious way to printf N characters that i'm missing? */
+ size_t size = end - token + 1;
+ char tmp[size];
+ snprintf(tmp, size, "%s", token);
+ fputs(tmp, stdout);
+ fputs(".done ", stdout);
}
/* prefix paths to absolute */
@@ -780,19 +810,34 @@ static inline void print_fullpaths(char* line)
char* token;
char* end;
int boost_count = 0;
+ const char * unpacked_end = 0; /* end of UnpackedTarget match (if any) */
+ /* for UnpackedTarget the target is GenC{,xx}Object, dont mangle! */
+ int target_seen = 0;
token = line;
eat_space(&token);
while (*token)
{
end = token;
- while (*end && (' ' != *end) && ('\t' != *end)) {
+ /* hard to believe that in this day and age drive letters still exist */
+ if (*end && (':' == *(end+1)) &&
+ (('\\' == *(end+2)) || ('/' == *(end+2))) && isalpha(*end))
+ {
+ end = end + 3; /* only one cross, err drive letter per filename */
+ }
+ while (*end && (' ' != *end) && ('\t' != *end) && (':' != *end)) {
++end;
}
int token_len = end - token;
- if(elide_dependency(token, token_len, &boost_count))
+ if (target_seen &&
+ elide_dependency(token, token_len, &boost_count, &unpacked_end))
{
- if (boost_count == 1)
+ if (unpacked_end)
+ {
+ emit_unpacked_target(token, unpacked_end);
+ unpacked_end = 0;
+ }
+ else if (boost_count == 1)
emit_single_boost_header();
else
{
@@ -803,22 +848,38 @@ static inline void print_fullpaths(char* line)
end = token + 2;
}
}
- else if(*token == ':' || *token == '\\' || *token == '/' ||
- *token == '$' || ':' == token[1])
- {
- fwrite(token, token_len, 1, stdout);
- fputc(' ', stdout);
- }
else
{
- fwrite(token, end - token, 1, stdout);
+ if (fwrite(token, token_len, 1, stdout) != 1)
+ abort();
fputc(' ', stdout);
}
token = end;
eat_space(&token);
+ if (!target_seen)
+ {
+ if (':' == *token)
+ {
+ target_seen = 1;
+ fputc(':', stdout);
+ ++token;
+ eat_space(&token);
+ }
+ }
}
}
+static inline char * eat_space_at_end(char * end)
+{
+ assert('\0' == *end);
+ char * real_end = end - 1;
+ while (' ' == *real_end || '\t' == *real_end || '\n' == *real_end
+ || ':' == *real_end)
+ { /* eat colon and whitespace at end */
+ --real_end;
+ }
+ return real_end;
+}
static int _process(struct hash* dep_hash, char* fn)
{
@@ -842,6 +903,12 @@ off_t size;
{
base = cursor_out = cursor = end = buffer;
end += size;
+
+ /* first eat unneeded space at the beginning of file
+ */
+ while(cursor < end && (*cursor == ' ' || *cursor == '\\'))
+ ++cursor;
+
while(cursor < end)
{
if(*cursor == '\\')
@@ -874,9 +941,9 @@ off_t size;
* these are the one for which we want to filter
* duplicate out
*/
- int key_len = cursor_out - base;
- if(!elide_dependency(base,key_len - 1, NULL) &&
- hash_store(dep_hash, base, key_len))
+ int key_len = eat_space_at_end(cursor_out) - base;
+ if (!elide_dependency(base,key_len + 1, NULL, NULL)
+ && hash_store(dep_hash, base, key_len))
{
/* DO NOT modify base after it has been added
as key by hash_store */
@@ -890,6 +957,7 @@ off_t size;
print_fullpaths(base);
putc('\n', stdout);
}
+ last_ns = ' '; // cannot hurt to reset it
}
cursor += 1;
base = cursor_out = cursor;
@@ -900,6 +968,7 @@ off_t size;
* i.e not a complete rule yet
*/
*cursor_out++ = *cursor++;
+ continuation = 0; // cancel current one (empty lines!)
}
}
else
@@ -918,7 +987,9 @@ off_t size;
{
if(last_ns == ':')
{
- if(hash_store(dep_hash, base, (int)(cursor_out - base)))
+ int key_len = eat_space_at_end(cursor_out) - base;
+ if (!elide_dependency(base,key_len + 1, NULL, NULL) &&
+ hash_store(dep_hash, base, key_len))
{
puts(base);
putc('\n', stdout);
@@ -967,7 +1038,7 @@ const char *env_str;
_usage();
return 1;
}
- if(get_var(&base_dir, "SRCDIR") || get_var(&out_dir, "OUTDIR"))
+ if(get_var(&base_dir, "SRCDIR") || get_var(&work_dir, "WORKDIR"))
return 1;
env_str = getenv("SYSTEM_BOOST");