From 7d9ccd90ff6f18f17f8b99722a3a53bc276be48c Mon Sep 17 00:00:00 2001 From: Bruce Korb <korbb@gcc.gnu.org> Date: Wed, 31 Mar 1999 11:51:29 +0000 Subject: [PATCH] Reworked method for traversing sym-linked directory hierarchies From-SVN: r26086 --- gcc/fixinc/fixincl.c | 46 +++++-- gcc/fixinc/hackshell.tpl | 58 +++++---- gcc/fixinc/inclhack.tpl | 263 ++++++++++++++++++++++----------------- 3 files changed, 215 insertions(+), 152 deletions(-) diff --git a/gcc/fixinc/fixincl.c b/gcc/fixinc/fixincl.c index c3b7fac2056b..36a86a70c6d5 100644 --- a/gcc/fixinc/fixincl.c +++ b/gcc/fixinc/fixincl.c @@ -139,6 +139,8 @@ struct fix_desc char *pz_dest_dir = NULL; char *pz_src_dir = NULL; char *pz_machine = NULL; +char *pz_find_base = NULL; +int find_base_len = 0; pid_t process_chain_head = (pid_t) -1; @@ -240,6 +242,17 @@ main (argc, argv) } } + { + static const char var[] = "FIND_BASE"; + pz_find_base = getenv (var); + if (pz_find_base == (char *) NULL) + { + fprintf (stderr, var_not_found, var); + exit (EXIT_FAILURE); + } + find_base_len = strlen( pz_find_base ); + } + /* Compile all the regular expressions now. That way, it is done only once for the whole run. */ @@ -298,10 +311,15 @@ main (argc, argv) errno, strerror (errno)); exit (EXIT_FAILURE); } -#ifdef DEBUG +#ifndef DEBUG + { + int status; + (void)wait (&status); + } +#else fprintf (stderr, "Waiting for %d to complete %d files\n", child, file_name_ct); -#endif + { int status; pid_t dead_kid = wait (&status); @@ -309,17 +327,18 @@ main (argc, argv) if (dead_kid != child) fprintf (stderr, "fixincl woke up from a strange child %d (not %d)\n", dead_kid, child); -#ifdef DEBUG else fprintf (stderr, "child finished %d files %s\n", file_name_ct, status ? strerror (status & 0xFF) : "ok"); -#endif } +#endif } #else #error "NON-BOGUS LIMITS NOT SUPPORTED?!?!" #endif + signal (SIGCLD, SIG_IGN); + #ifdef DEBUG fprintf (stderr, "Child start -- processing %d files\n", file_name_ct); @@ -411,8 +430,10 @@ load_file (pz_file_name) if (ferror (fp)) { - fprintf (stderr, "error %d (%s) reading %s\n", errno, - strerror (errno), pz_file_name); + int err = errno; + if (err != EISDIR) + fprintf (stderr, "error %d (%s) reading %s\n", err, + strerror (err), pz_file_name); free ((void *) pz_data); fclose (fp); return (char *) NULL; @@ -596,7 +617,16 @@ create_file (pz_file_name) FILE *pf; char fname[MAXPATHLEN]; - sprintf (fname, "%s/%s", pz_dest_dir, pz_file_name); +#ifdef DEBUG + if (strncmp( pz_file_name, pz_find_base, find_base_len ) != 0) + { + fprintf (stderr, "Error: input file %s does not match %s/*\n", + pz_file_name, pz_find_base ); + exit (1); + } +#endif + + sprintf (fname, "%s/%s", pz_dest_dir, pz_file_name + find_base_len); fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL); @@ -911,7 +941,7 @@ process (pz_data, pz_file_name) } } - fprintf (stderr, "Applying %-32s to %s\n", + fprintf (stderr, "Applying %-24s to %s\n", p_fixd->fix_name, pz_file_name); /* IF we do not have a read pointer, diff --git a/gcc/fixinc/hackshell.tpl b/gcc/fixinc/hackshell.tpl index 2dd5698ce9b3..aaa75d066014 100644 --- a/gcc/fixinc/hackshell.tpl +++ b/gcc/fixinc/hackshell.tpl @@ -5,19 +5,15 @@ # fixincl program. It is the repetitive guts of the fixincludes logic. # =] - if $LINKS; then - files=`find . -name '*.h' \( -type f -o -type l \) -print` - else - files=`find . -name '*.h' -type f -print` - fi echo Checking header files for file in $files; do - if ( test ! -r $file -o \ - -n "`fgrep 'This file is part of the GNU C Library' $file`" ) + if ( test ! -r ${file} -o \ + -n "`fgrep 'This file is part of the GNU C Library' ${file}`" ) then continue ; fi fixlist="" + DESTFILE=${DESTDIR}/`echo ${file} | sed "s;${FIND_BASE}/;;" ` [= # # FOR every fix description, @@ -30,7 +26,7 @@ _FOR fix "\n\n" =] # Fix [=_eval _index 1 + #%3d _printf=]: [=hackname _Cap=] #[= _IF files _exist=] - case "$file" in [=_FOR files " | \\\n\t"=]./[=files=][=/files=] )[= + case "${file}" in [=_FOR files " | \\\n\t"=]./[=files=][=/files=] )[= _ENDIF=][= _IF mach _exist=] @@ -52,8 +48,8 @@ _FOR fix "\n\n" =] true or false. It is enclosed in parenthesis to avoid precedence problems. The output looks like this: - if ( test -n "`egrep 'find-expr' $file`" -a - -z "`egrep 'not-find' $file`" -a + if ( test -n "`egrep 'find-expr' ${file}`" -a + -z "`egrep 'not-find' ${file}`" -a '(' <some-test-expression> ')' ) > /dev/null 2>&1 ; then @@ -62,13 +58,13 @@ _FOR fix "\n\n" =] _IF select _exist =] if ( test [= _FOR select " -a \\\n " - =]-n [=select _shrstr "#`egrep %s $file`" + =]-n [=select _shrstr "#`egrep %s ${file}`" _printf _shstr =][= /select=][= _IF bypass _exist =][= _FOR bypass=] -a \ - -z [=bypass _shrstr "#`egrep %s $file`" + -z [=bypass _shrstr "#`egrep %s ${file}`" _printf _shstr =][= /bypass=][= _ENDIF=][= @@ -89,7 +85,7 @@ _FOR fix "\n\n" =] _IF bypass _exist=][= _FOR bypass=] -a \ - -z [=bypass _shrstr "#`egrep %s $file`" + -z [=bypass _shrstr "#`egrep %s ${file}`" _printf _shstr=][= /bypass=][= _ENDIF=] @@ -98,16 +94,16 @@ _FOR fix "\n\n" =] _ELIF bypass _exist =] if ( test [=_FOR bypass " -a \\\n " - =]-z [=bypass _shrstr "#`egrep %s $file`" + =]-z [=bypass _shrstr "#`egrep %s ${file}`" _printf _shstr=][=/bypass=] ) > /dev/null 2>&1 ; then[= _ENDIF=] fixlist="${fixlist} [=hackname=]" - if [ ! -r ${DESTDIR}/$file ] - then infile=$file - else infile=${DESTDIR}/$file ; fi [= + if [ ! -r ${DESTFILE} ] + then infile=${file} + else infile=${DESTFILE} ; fi [= _IF sed _exist=][= _IF shell _exist =][= @@ -118,16 +114,16 @@ _FOR fix "\n\n" =] sed [= _FOR sed =]-e [=sed _shrstr=] \ [= - /sed=] < $infile > ${DESTDIR}/$file.[= + /sed=] < $infile > ${DESTFILE}.[= _ELIF shell _exist =] - ( [=shell=] ) < $infile > ${DESTDIR}/$file. + ( [=shell=] ) < $infile > ${DESTDIR}/FIXINC.tmp # Shell scripts have the potential of removing the output # We interpret that to mean the file is not to be altered # - if test ! -f ${DESTDIR}/$file. + if test ! -f ${DESTDIR}/fixinc.tmp then continue ; fi [= @@ -135,8 +131,8 @@ _FOR fix "\n\n" =] _ERROR hackname _get "ERROR: %s has no fixup" _printf=][= _ENDIF=] - - mv -f ${DESTDIR}/$file. ${DESTDIR}/$file[= + rm -f ${DESTFILE} + mv -f ${DESTDIR}/fixinc.tmp ${DESTFILE}[= # Close off any opened "if" or "case" statements in reverse order @@ -165,21 +161,23 @@ _FOR fix "\n\n" =] # THEN ensure the output is gone # ELSE look for local directory include syntax # - if ( test ! -f ${DESTDIR}/$file || \ - cmp $file ${DESTDIR}/$file ) > /dev/null 2>&1 + if ( test ! -f ${DESTFILE} || \ + cmp ${file} ${DESTFILE} ) > /dev/null 2>&1 then - rm -f ${DESTDIR}/$file + rm -f ${DESTFILE} else - echo "Fixed $file:${fixlist}" + echo "Fixed ${file}:${fixlist}" # Find any include directives that use "file". # + dir=`echo ${file} | sed -e s';/[^/]*$;;'` + ddir=`echo ${DESTDIR} | sed 's;/[^/]*$;;'`/$dir + for include in ` - egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${DESTDIR}/$file | - sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'` + egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${DESTFILE} | + sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'` do - dir=`echo $file | sed -e s'|/[^/]*$||'` - required="$required ${SRCDIR} $dir/$include ${DESTDIR}/$dir/$include" + required="$required ${SRCDIR} $dir/$include ${ddir}/$include" done fi done # for file in $files diff --git a/gcc/fixinc/inclhack.tpl b/gcc/fixinc/inclhack.tpl index 06b49aeabe95..7a30402f7861 100644 --- a/gcc/fixinc/inclhack.tpl +++ b/gcc/fixinc/inclhack.tpl @@ -87,7 +87,7 @@ case $LIB in esac echo Fixing headers into ${LIB} for ${target_canonical} target - + # Determine whether this system has symbolic links. if ln -s X $LIB/ShouldNotExist 2>/dev/null; then rm -f $LIB/ShouldNotExist @@ -98,7 +98,7 @@ elif ln -s X /tmp/ShouldNotExist 2>/dev/null; then else LINKS=false fi - + # # # # # # # # # # # # # # # # # # # # # # # Search each input directory for broken header files. @@ -116,6 +116,7 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} cd ${INPUT} || continue +INPUT=`${PWDCMD}` # # # # # # # # # # # # # # # # # # # # # # @@ -123,24 +124,27 @@ cd ${INPUT} || continue echo Finding directories and links to directories # Find all directories and all symlinks that point to directories. -# Put the list in $files. +# Put the list in $all_dirs. # Each time we find a symlink, add it to newdirs # so that we do another find within the dir the link points to. -# Note that $files may have duplicates in it; +# Note that $all_dirs may have duplicates in it; # later parts of this file are supposed to ignore them. dirs="." levels=2 +all_dirs="" +search_dirs="" + while [ -n "$dirs" ] && [ $levels -gt 0 ] do - levels=`expr $levels - 1` - newdirs= - for d in $dirs - do + levels=`expr $levels - 1` + newdirs= + for d in $dirs + do echo " Searching $INPUT/$d" - + # Find all directories under $d, relative to $d, excluding $d itself. # (The /. is needed after $d in case $d is a symlink.) - files="$files `find $d/. -type d -print | \ + all_dirs="$all_dirs `find $d/. -type d -print | \ sed -e '/\/\.$/d' -e 's@/./@/@g'`" # Find all links to directories. # Using `-exec test -d' in find fails on some systems, @@ -152,131 +156,151 @@ do theselinks=`find $d/. -type l -print | sed -e 's@/./@/@g'` for d1 in $theselinks --dummy-- do - # If the link points to a directory, - # add that dir to $newdirs - if [ -d $d1 ] - then - files="$files $d1" + # If the link points to a directory, + # add that dir to $newdirs + if [ -d $d1 ] + then + all_dirs="$all_dirs $d1" if [ "`ls -ld $d1 | sed -n 's/.*-> //p'`" != "." ] then - newdirs="$newdirs $d1" - fi + newdirs="$newdirs $d1" + search_dirs="$search_dirs $d1" fi + fi done - done - - dirs="$newdirs" + done + + dirs="$newdirs" done - + # # # # # # # # # # # # # # # # # # # # # # dirs= echo "All directories (including links to directories):" -echo $files - -for file in $files; do +echo $all_dirs + +for file in $all_dirs; do rm -rf $LIB/$file if [ ! -d $LIB/$file ] then mkdir $LIB/$file fi done mkdir $LIB/root - + # # # # # # # # # # # # # # # # # # # # # # # treetops gets an alternating list # of old directories to copy # and the new directories to copy to. -treetops="${INPUT} ${LIB}" - +treetops=". ${LIB}" + if $LINKS; then echo 'Making symbolic directory links' - for file in $files; do - dest=`ls -ld $file | sed -n 's/.*-> //p'` - if [ "$dest" ]; then - cwd=`${PWDCMD}` - # In case $dest is relative, get to $file's dir first. - cd ${INPUT} - cd `echo ./$file | sed -n 's&[^/]*$&&p'` - # Check that the target directory exists. - # Redirections changed to avoid bug in sh on Ultrix. - (cd $dest) > /dev/null 2>&1 - if [ $? = 0 ]; then - cd $dest - # X gets the dir that the link actually leads to. - x=`${PWDCMD}` - # Canonicalize ${INPUT} now to minimize the time an - # automounter has to change the result of ${PWDCMD}. - cinput=`cd ${INPUT}; ${PWDCMD}` - # If a link points to ., make a similar link to . - if [ $x = ${cinput} ]; then - echo $file '->' . ': Making link' - rm -fr ${LIB}/$file > /dev/null 2>&1 - ln -s . ${LIB}/$file > /dev/null 2>&1 - # If link leads back into ${INPUT}, - # make a similar link here. - elif expr $x : "${cinput}/.*" > /dev/null; then - # Y gets the actual target dir name, relative to ${INPUT}. - y=`echo $x | sed -n "s&${cinput}/&&p"` - # DOTS is the relative path from ${LIB}/$file's dir back to ${LIB}. - dots=`echo "$file" | - sed -e 's@^./@@' -e 's@/./@/@g' -e 's@[^/][^/]*@..@g' -e 's@..$@@'` - echo $file '->' $dots$y ': Making link' - rm -fr ${LIB}/$file > /dev/null 2>&1 - ln -s $dots$y ${LIB}/$file > /dev/null 2>&1 - else - # If the link is to a dir $target outside ${INPUT}, - # repoint the link at ${INPUT}/root$target - # and process $target into ${INPUT}/root$target - # treat this directory as if it actually contained the files. - echo $file '->' root$x ': Making link' - if [ -d $LIB/root$x ] - then true + cwd=`${PWDCMD}` + + for sym_link in $search_dirs; do + cd ${INPUT} + dest=`ls -ld ${sym_link} | sed -n 's/.*-> //p'` + + # In case $dest is relative, get to ${sym_link}'s dir first. + # + cd ./`echo ${sym_link} | sed 's;/[^/]*$;;'` + + # Check that the target directory exists. + # Redirections changed to avoid bug in sh on Ultrix. + # + (cd $dest) > /dev/null 2>&1 + if [ $? = 0 ]; then + cd $dest + + # full_dest_dir gets the dir that the link actually leads to. + # + full_dest_dir=`${PWDCMD}` + + # Canonicalize ${INPUT} now to minimize the time an + # automounter has to change the result of ${PWDCMD}. + # + cinput=`cd ${INPUT}; ${PWDCMD}` + + # If a link points to ., make a similar link to . + # + if [ ${full_dest_dir} = ${cinput} ]; then + echo ${sym_link} '->' . ': Making self link' + rm -fr ${LIB}/${sym_link} > /dev/null 2>&1 + ln -s . ${LIB}/${sym_link} > /dev/null 2>&1 + + # If link leads back into ${INPUT}, + # make a similar link here. + # + elif expr ${full_dest_dir} : "${cinput}/.*" > /dev/null; then + # Y gets the actual target dir name, relative to ${INPUT}. + y=`echo ${full_dest_dir} | sed -n "s&${cinput}/&&p"` + # DOTS is the relative path from ${LIB}/${sym_link} back to ${LIB}. + dots=`echo "${sym_link}" | + sed -e 's@^./@@' -e 's@/./@/@g' -e 's@[^/][^/]*@..@g' -e 's@..$@@'` + echo ${sym_link} '->' $dots$y ': Making local link' + rm -fr ${LIB}/${sym_link} > /dev/null 2>&1 + ln -s $dots$y ${LIB}/${sym_link} > /dev/null 2>&1 + else - dirname=root$x/ - dirmade=. - cd $LIB - while [ x$dirname != x ]; do - component=`echo $dirname | sed -e 's|/.*$||'` - mkdir $component >/dev/null 2>&1 - cd $component - dirmade=$dirmade/$component - dirname=`echo $dirname | sed -e 's|[^/]*/||'` - done - fi - # Duplicate directory structure created in ${LIB}/$file in new - # root area. - for file2 in $files; do - case $file2 in - $file/*) - dupdir=${LIB}/root$x/`echo $file2 | sed -n "s|^${file}/||p"` - echo "Duplicating ${file}'s ${dupdir}" - if [ -d ${dupdir} ] + # If the link is to a dir $target outside ${INPUT}, + # repoint the link at ${INPUT}/root$target + # and process $target into ${INPUT}/root$target + # treat this directory as if it actually contained the files. + # + echo ${sym_link} '->' root${full_dest_dir} ': Making rooted link' + if [ -d $LIB/root${full_dest_dir} ] then true else - mkdir ${dupdir} - fi - ;; - *) - ;; - esac + dirname=root${full_dest_dir}/ + dirmade=. + cd $LIB + while [ x$dirname != x ]; do + component=`echo $dirname | sed -e 's|/.*$||'` + mkdir $component >/dev/null 2>&1 + cd $component + dirmade=$dirmade/$component + dirname=`echo $dirname | sed -e 's|[^/]*/||'` done - # Get the path from ${LIB} to $file, accounting for symlinks. - parent=`echo "$file" | sed -e 's@/[^/]*$@@'` - libabs=`cd ${LIB}; ${PWDCMD}` - file2=`cd ${LIB}; cd $parent; ${PWDCMD} | sed -e "s@^${libabs}@@"` - # DOTS is the relative path from ${LIB}/$file's dir back to ${LIB}. - dots=`echo "$file2" | sed -e 's@/[^/]*@../@g'` - rm -fr ${LIB}/$file > /dev/null 2>&1 - ln -s ${dots}root$x ${LIB}/$file > /dev/null 2>&1 - treetops="$treetops $x ${LIB}/root$x" - fi + fi + + # Duplicate directory structure created in ${LIB}/${sym_link} in new + # root area. + # + for file2 in $all_dirs; do + case $file2 in + ${sym_link}/*) + dupdir=${LIB}/root${full_dest_dir}/`echo $file2 | + sed -n "s|^${sym_link}/||p"` + echo "Duplicating ${sym_link}'s ${dupdir}" + if [ -d ${dupdir} ] + then true + else + mkdir ${dupdir} + fi + ;; + *) + ;; + esac + done + + # Get the path from ${LIB} to ${sym_link}, accounting for symlinks. + # + parent=`echo "${sym_link}" | sed -e 's@/[^/]*$@@'` + libabs=`cd ${LIB}; ${PWDCMD}` + file2=`cd ${LIB}; cd $parent; ${PWDCMD} | sed -e "s@^${libabs}@@"` + + # DOTS is the relative path from ${LIB}/${sym_link} back to ${LIB}. + # + dots=`echo "$file2" | sed -e 's@/[^/]*@../@g'` + rm -fr ${LIB}/${sym_link} > /dev/null 2>&1 + ln -s ${dots}root${full_dest_dir} ${LIB}/${sym_link} > /dev/null 2>&1 + treetops="$treetops ${sym_link} ${LIB}/root${full_dest_dir}" fi - cd $cwd fi done fi - + # # # # # # # # # # # # # # # # # # # # # # required= @@ -287,6 +311,9 @@ while [ $# != 0 ]; do # SRCDIR=`cd ${INPUT} ; cd $1 ; ${PWDCMD}` export SRCDIR + + FIND_BASE=$1 + export FIND_BASE shift DESTDIR=`cd $1;${PWDCMD}` @@ -302,11 +329,17 @@ while [ $# != 0 ]; do touch ${DESTDIR}/DONE echo Fixing directory ${SRCDIR} into ${DESTDIR} - # Check .h files which are symlinks as well as those which are files. - # A link to a header file will not be processed by anything but this. + # Check files which are symlinks as well as those which are files. # - cd ${SRCDIR} -[=_IF PROGRAM _env ! =][= + cd ${INPUT}[= +_IF PROGRAM _env ! =] + files=`if $LINKS; then + find ${FIND_BASE}/. \( -type f -o -type l \) -print + else + find ${FIND_BASE}/. -type f -print + fi | \ + sed -e's;/\./;/;g' -e's;//*;/;g' ` +[= _include hackshell =][= @@ -314,10 +347,12 @@ while [ $# != 0 ]; do =] required="$required `if $LINKS; then - find . -name '*.h' \( -type f -o -type l \) -print + find ${FIND_BASE}/. \( -type f -o -type l \) -print else - find . -name '*.h' -type f -print - fi | ${FIXINCL}`"[= + find ${FIND_BASE}/. -type f -print + fi | \ + sed -e's;/\./;/;g' -e's;//*;/;g' | \ + ${FIXINCL}`"[= _ENDIF =] @@ -365,8 +400,8 @@ find . -name DONE -exec rm -f '{}' ';' echo 'Removing unneeded directories:' cd $LIB -files=`find . -type d -print | sort -r` -for file in $files; do +all_dirs=`find . -type d -print | sort -r` +for file in $all_dirs; do rmdir $LIB/$file > /dev/null 2>&1 | : done -- GitLab