Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
An emerge wrapper for breaking emerges into chunks
View unanswered posts
View posts from last 24 hours

Goto page Previous  1, 2, 3 ... 8, 9, 10 ... 28, 29, 30  Next  
Reply to topic    Gentoo Forums Forum Index Unsupported Software
View previous topic :: View next topic  
Author Message
TrainedChimp
Tux's lil' helper
Tux's lil' helper


Joined: 25 Jun 2004
Posts: 87
Location: Just west of Earth

PostPosted: Thu Jul 14, 2005 1:29 am    Post subject: Reply with quote

Just to make sure I'm on the right track here (I got a little confused between the two scripts emwrap.sh an tcupdate.sh)

I just did an emerge sync and found that there is a sys-kernel/linux-headers update. So if I want to update everything properly should I follow the steps below yanked from the first page of this post?

Code:

gcc-config -l    # make sure of gcc before beginning
emwrap.sh -set
emwrap.sh -seb   # We rebuild the TC and then the rest of the system
emwrap.sh -se    # doing the 2nd system emerge minus the TC
emwrap.sh -wet   # rebuilds TC against clean system
emwrap.sh -r     # first build of the world files against clean TC system
emwrap.sh -r     # second world rebuild and done


Thanks.
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Thu Jul 14, 2005 3:47 am    Post subject: Reply with quote

That is the safest way. When you use -e and either-s/w and -t/b that builds the entire TC. Thats true because the filtering sees linux-headers. What I do is this and it generally works
Code:
emwrap.sh -seb
emwrap.sh -d
emwrap.sh -web
emwrap.sh -r

This is one TC emerge shorter. It rebuilds the TC once then the system files twice then the TC again and then the world files twice.
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
Pseud
Apprentice
Apprentice


Joined: 19 Mar 2004
Posts: 273
Location: Bangalore, India

PostPosted: Fri Jul 15, 2005 6:51 am    Post subject: Reply with quote

I have two computers (call them comp1 and comp2) running Gentoo, with the same MARCHs, gcc versions, etc. The only difference, in fact is that comp1 and comp2 differ slightly with respect to the world packages installed, with a large part common (lets call them world1 and world2)

Here's my plan to nail down the tool chains and rebuild the system/world packages on the two machines (without having to repeat steps on both of them):

On comp1, I have buildpkg as part of FEATURES, and I do exactly what the first page of this thread recommends:
Code:
gcc-config -l    # make sure of gcc before beginning
emwrap.sh -set
emwrap.sh -seb   # We rebuild the TC and then the rest of the system
emwrap.sh -se    # doing the 2nd system emerge minus the TC
emwrap.sh -wet   # rebuilds TC against clean system
emwrap.sh -r     # first build of the world files against clean TC system
emwrap.sh -r     # second world rebuild and done


On comp2, I then do these steps:
Code:
//copy the packages built on comp1 into the {$PKGDIR} of comp2
emerge -ek world
emerge --oneshot --nodeps <all packages in world2 not in world1, listed in the right order of dependencies>


Please let me know if what I plan to do is correct, and if not, please suggest what I should do instead.

TIA!
_________________
eschew obfuscation
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Fri Jul 15, 2005 2:45 pm    Post subject: Reply with quote

Pseud That should work. If you grab sys-build.sh and on comp1 when your through do " emerge world -ep>basesys-build.lst " and on comp2 Edit sys-build.sh in "function get_build" where it says " wrld_lst system " and change "system to world " ==> wrld_lst world ".Then with sys-build on comp2 use your comp1 basesys list and run it twice. It should auotamatically filer out comp1s list from comp2. Oh and you can use -p with sys-build.sh to test.
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
Stephonovich
n00b
n00b


Joined: 20 May 2004
Posts: 72
Location: United States

PostPosted: Fri Jul 15, 2005 11:07 pm    Post subject: Reply with quote

I've had a Jackass! installation going quite nicely for awhile now, and after reading several threads on the matter, decided to go ahead and upgrade to GCC 3.4.4. I also decided to use prelinking, so I read up on that, followed the steps, and then started up emwrap. First, I assume that -N works the same as it does in emerge? The help portion seemed to indicate so. In any case, I got linux-headers and glibc updated when I had to kill it. I figured the -c option would bring it up where it left off. Not so. It wants to re-do those. Is there any reason for this? I checked the versions, and they updated just fine. There's no reason I can see to do this. I don't mind all that much, as it's only another 1.5 hours or so, but it seems a bit strange.

Also, I read earlier in this thread that sys-build is still in beta, or something to that effect. Is it recommended to use it in addition to emwrap now, or is it not required?
_________________
Who needs reincarnation when you've got parallel universes?
Back to top
View user's profile Send private message
dagurasu
n00b
n00b


Joined: 29 Apr 2005
Posts: 74

PostPosted: Sun Jul 17, 2005 4:31 am    Post subject: Reply with quote

I have noob question/or confusion about the topic, but then maybe it's a bit OT. I do alot of scientific programming, nothing on the scale of developing operating systems and most of it just needs to be useable for a few people, so it's a diferent kind of thing entirely than real package development. Still, I have alot of libraries (my own and third party) that are used by alot of diferent bits of code and such. Even so, so long as I don't link anything statically (or at least before I do), and so long as all the header files are in place and up2date, it's not gonna make 2 cents differnce what order I compile my object files in. They don't know about the other binary files anyway, just the headers. Then I have a bunch of object files... and I'm lazy and old fashioned and don't need to worry about space much anyway so I usually just statically link stuff then.

Now I can see if one code statically links a library and then the library changes then that maybe could problems if it needs to handle things the same way as some other code, but I thought pretty much everything in linux is dynamically linked these days. I can imagine that maybe recompiling the compiler itself is a diferent issue, but I have trouble seeing why world and even system packages excluding the tool-chain need to be built twice.

Anyway... I see 3 issues
1) recompiling the compiler maybe
2) Statically linking before the libraries get rebuilt (which I wouldn't think would happen)
3)... or just plain not having the latest headers in place because they haven't been downloaded and insalled by emerge yet (which surely could be solved by implementing some ebuild function to just install headers...)

EDIT: Actually I originally thought the whole idea of the emwrap.sh script was to make it so I could emerge the toolchain twice without needing to emerge to the whole world or system twice and so that after doing that I could emerge the rest of the world or system JUST ONCE without emerging the toolchain yet again in the wrong order anyway. Wow, if you really need to emerge world twice, then it seems like it would be easier to mount the system from another live distro or something, unmerge pretty much everything but the toolchain.. and then just re-emerge it all from scratch once.

Is it possible, just for my curiosity, to clear up my confusion at least in some handwaving way in a couple of sentences, or do I just have way too much to learn to understand this problem?
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Sun Jul 17, 2005 10:40 pm    Post subject: Reply with quote

Ok this script started because of Rob_moss, during the early days gcc-3.4 testing, when it was still in CVS. Since he was being very conscinces about what built and what worked correctly after building by gcc-3.4 he was doing the famous " emerge system -e && emerge system -e && emerge world -e && emerge world -e ". This was to insure that any bugs were form gcc-3.4 and not screwed up libraries or binaries.

The other reason was, I wanted finer controll of emerge. While playing with the onlliners I also found that I could skip over "circulaur dependencies " and come back to them latter. I was also interested in combineihg a bunch of oneliners into something more usefull.

As to whether this script is needed or not ? Do you need to need faithfully rebuild your TC and all files after words no. Most of the time, 98% to 99% in my experince, if your running stable or testing an " emerge world -uD " works fine. Throw in a " emerge world -e " quarterly or bi-annually and your system should run fine. There is a big BUT in this. To take full advantage of gcc-3.4 you should rebuild everthing and if your going to do that then you might as well rebuild the TC in the correct order. So for most people emwrap.sh -suDb and a following emwrap.sh -wuD is fine.
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
dagurasu
n00b
n00b


Joined: 29 Apr 2005
Posts: 74

PostPosted: Sun Jul 17, 2005 11:26 pm    Post subject: Reply with quote

OK thanks, that helps make me much less paranoid, which I greatly apreciate. Don't get me wrong, I see the script as useful if nothing else just so I an isolate and build the toolchain before rebuilding everything else. And clearly that much is useful(at least since I know that includes the compiler). I'm even not shocked that the toolchain needs to be built in order, obviously the headers should be installed first at least, and if there's no way to pull in headers without emerging first then I'm not shocked a few more headers come in with the other parts and they thus need to be done in order too (although I'm curious if just doing an emerge --fetch wouldn't have the same effect...but maybe that doesn't really INSTALL the headers where they need to be; I still wonder if there's not a way to get around actually compiling in order... but then why not). I can also see that compiling the compiler with an updated compiler could be good. So toolchain twice, in order, I wont question.

As for building the rest of the world twice though... I wonder if this is just legend from some over-paranoid(no offense) guy who wanted to make sure no-one had any case for acusing him of causing incidental bugs, or can anyone actually do a checksum comparison or something which actually proves that some binary somewhere in the rest of the world actually does come out diferent the second time around? If so, can we trace down PRECISELY why for at least one example, and if that turns out to be just an issue of installing headers, can we see if an fetch or something would solve it? The world packages were only compiled once the first time and it all worked just fine, and it seems portage knows what order to compile them when it updates or remerges. I'm just a bit concerned that alot of people are getting overly worried about something that might be more myth than fact. I've seen posts that people are more worried about this issue than the fact that portage loses track of packages you have installed and updates them unecesarily because they are longer in the official tree (for example).

Note:
To do my propsed checksum experiement, the toolchain would have to not be touched between world compiles and/or it shoudl already be proven to be PERFECTLY (bit for bit) stable under rebuilds by checsum testing rebuilds of it. IE when the rest-of-the-world is rebuilt twice, I want to be dead sure the thing doing the rebuilding hasn't changed before trying to see if the results of the rest-of-the-world build change. Under those conditions, if someone can really prove that the-rest-of-the-world builds come out diferent the second time... that would be kinda nice to know. I'm not claiming this hasn't been done either. I wouldn't know.

Anyway, as I said, I'm really glad to hear I don't need to be sooooo paranoid about it. The rest is mostly just accademic curiosity. I'm not trying to say work on these scipts is useless or anytying either, just wanted to see if I should get all fanatic about it. Glad to hear that I should not. Thanks heilvc
.
Back to top
View user's profile Send private message
Stephonovich
n00b
n00b


Joined: 20 May 2004
Posts: 72
Location: United States

PostPosted: Wed Jul 20, 2005 3:40 pm    Post subject: Reply with quote

hielvc wrote:
As to whether this script is needed or not ? Do you need to need faithfully rebuild your TC and all files after words no. Most of the time, 98% to 99% in my experince, if your running stable or testing an " emerge world -uD " works fine. Throw in a " emerge world -e " quarterly or bi-annually and your system should run fine. There is a big BUT in this. To take full advantage of gcc-3.4 you should rebuild everthing and if your going to do that then you might as well rebuild the TC in the correct order. So for most people emwrap.sh -suDb and a following emwrap.sh -wuD is fine.


THANK YOU. I'd always wondered if running it so many times was actually necessary, since my system seemed perfectly stable.
_________________
Who needs reincarnation when you've got parallel universes?
Back to top
View user's profile Send private message
dagurasu
n00b
n00b


Joined: 29 Apr 2005
Posts: 74

PostPosted: Thu Jul 21, 2005 3:06 am    Post subject: Reply with quote

oh and stpanohvich, as for the -N option. Maybe I can answer that. I suggested it be added awhile back. I think heilvc was kinda like "why not, I'll throw it and maybe it will work right" I'm sure you can find his exact words a few pages back or in another thread or something. Anyway. I did scour over the script myself for awhile before requesting it and my conclusion was that the -N could indeed just be passed through and it should work like in emerge. I'm sure heilvc knows his own script well too and wouldn't have added it if he didn't think it might work. Anyway, the short answer is yes... it is just passed to the emerge command when deciding which builds to update and thus works just like in emerge.
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Thu Jul 21, 2005 4:20 am    Post subject: Reply with quote

Ive been sort of busy recently. Anyway as dagurasu said -N works. What dosent is -v. My filters wipe out all the output.

The point Im trying make about updateing your TC is play it safe. Do it when you have time do the full double double in case you get bit. My behaviour has changed . I use to just dive right in now I plan it a little. Ive given up thinking that the alatest greatest TC in going to make my Athlon=xp 2K frun like a optron 3500 :cry:
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
PRHumphrey
n00b
n00b


Joined: 23 Jan 2004
Posts: 6
Location: Tideswell, Derbyshire, UK

PostPosted: Thu Jul 28, 2005 6:35 pm    Post subject: Reply with quote

Pardon my butting in, but after reading this topic and the one on ecatmur's dep script I tried running sys-build.sh, but I got the following error:

Code:

wstn ~ # ./sys-build.sh -p

1 of 143
These are the packages that I would merge, in order:

Calculating dependencies
emerge: there are no ebuilds to satisfy "=<title>Linux".

 <title>Linux failed to build. Stoping script. Maually emerge <title>Linux
 and then rerun script useing -r, resume


What have I missed? This is a dual-Opteron box running ~amd64 in case it makes a difference. I wonder if the parsing of line 165 in sys-build.sh is going wrong (bash 3.0-r12 is the latest of three installed versions). The line is:
Code:

for e in $(< build.lst);do


Up to now I've been running this much simpler script whenever I thought the tool chain needed a rebuild:

Code:

emerge --nodeps --oneshot --quiet linux-headers glibc binutils gcc && \
        emerge --nodeps --oneshot --quiet linux-headers glibc binutils gcc portage
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Fri Jul 29, 2005 4:12 am    Post subject: Reply with quote

Its not the bash version. Im running the same on my box. I t might be Saturday before I have a chance to look at it but could you past your " emerge system -ep "? If your wondering about the $(< ...) that is just a builtin for "cat file".

How long does it take to run your script? Warning if you say 45 minutes Im gonna send you a bag of poop with a can of lighter fluid and a box matches :twisted:
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
PRHumphrey
n00b
n00b


Joined: 23 Jan 2004
Posts: 6
Location: Tideswell, Derbyshire, UK

PostPosted: Fri Jul 29, 2005 11:03 am    Post subject: Reply with quote

I wondered about bash because I'm unfamiliar with the particular incantation you've used.

This is the output you asked for:

Code:

prh@wstn ~ $ emerge -ep system

These are the packages that I would merge, in order:

Calculating system dependencies  ...done!
[ebuild  N    ] sys-devel/patch-2.5.9-r1
[ebuild  N    ] app-arch/bzip2-1.0.3-r5
[ebuild  N    ] app-arch/cpio-2.6-r4
[ebuild  N    ] sys-devel/gettext-0.14.2
[ebuild  N    ] app-arch/gzip-1.3.5-r8
[ebuild  N    ] app-arch/tar-1.15.1
[ebuild  N    ] sys-libs/gpm-1.20.1-r4
[ebuild  N    ] sys-libs/ncurses-5.4.20050319
[ebuild  N    ] app-shells/bash-3.0-r12
[ebuild  N    ] sys-devel/binutils-config-1.8-r4
[ebuild  N    ] sys-devel/gnuconfig-20050602
[ebuild  N    ] sys-devel/binutils-2.16-r1
[ebuild  N    ] sys-devel/m4-1.4.3
[ebuild  N    ] sys-devel/bison-2.0
[ebuild  N    ] sys-apps/sed-4.1.4
[ebuild  N    ] sys-devel/gcc-config-1.3.12
[ebuild  N    ] sys-apps/texinfo-4.8
[ebuild  N    ] sys-libs/zlib-1.2.3
[ebuild  N    ] sys-devel/gcc-3.4.4
[ebuild  N    ] sys-kernel/linux-headers-2.6.11-r2
[ebuild  N    ] sys-libs/glibc-2.3.5-r1
[ebuild  N    ] dev-python/python-fchksum-1.7.1
[ebuild  N    ] sys-libs/readline-5.0-r2
[ebuild  N    ] sys-apps/diffutils-2.8.7-r1
[ebuild  N    ] dev-libs/openssl-0.9.7g
[ebuild  N    ] dev-libs/expat-1.95.8
[ebuild  N    ] dev-lang/python-2.4.1-r1
[ebuild  N    ] dev-java/java-config-1.2.11-r1
[ebuild  N    ] dev-java/blackdown-jre-1.4.2.02
[ebuild  N    ] dev-java/blackdown-jdk-1.4.2.02
[ebuild  N    ] sys-libs/db-4.2.52_p2
[ebuild  N    ] sys-apps/groff-1.19.1-r2
[ebuild  N    ] sys-devel/libperl-5.8.7
[ebuild  N    ] dev-lang/perl-5.8.7
[ebuild  N    ] sys-process/cronbase-0.3.2
[ebuild  N    ] sys-apps/man-1.6-r1
[ebuild  N    ] app-admin/perl-cleaner-1.01
[ebuild  N    ] net-misc/iputils-021109-r3
[ebuild  N    ] dev-libs/popt-1.7-r1
[ebuild  N    ] sys-apps/sandbox-1.2.11
[ebuild  N    ] sys-apps/debianutils-2.14.1-r1
[ebuild  N    ] sys-apps/portage-2.0.51.22-r2
*** Please update portage to the above version before proceeding.
    Failure to do so may result in failed or improper merges.
    A simple 'emerge -u portage' is sufficient.

[ebuild  N    ] net-misc/rsync-2.6.5
[ebuild  N    ] sys-devel/autoconf-2.13
[ebuild  N    ] sys-devel/autoconf-wrapper-3.1
[ebuild  N    ] sys-devel/autoconf-2.59-r7
[ebuild  N    ] net-misc/wget-1.10
[ebuild  N    ] sys-apps/sysvinit-2.86
[ebuild  N    ] perl-core/Test-Harness-2.52
[ebuild  N    ] perl-core/Test-Simple-0.60
[ebuild  N    ] dev-perl/Locale-gettext-1.05
[ebuild  N    ] sys-apps/help2man-1.35.1
[ebuild  N    ] sys-devel/automake-1.5
[ebuild  N    ] sys-devel/automake-1.9.6
[ebuild  N    ] sys-devel/automake-1.6.3
[ebuild  N    ] sys-devel/automake-1.7.9-r1
[ebuild  N    ] sys-devel/automake-1.4_p6
[ebuild  N    ] sys-devel/automake-wrapper-1-r1
[ebuild  N    ] sys-devel/automake-1.8.5-r3
[ebuild  N    ] sys-apps/coreutils-5.2.1-r6
[ebuild  N    ] sys-apps/baselayout-1.11.13
[ebuild  N    ] sys-apps/file-4.14
[ebuild  N    ] sys-apps/findutils-4.2.20
[ebuild  N    ] sys-apps/gawk-3.1.4-r4
[ebuild  N    ] sys-apps/grep-2.5.1-r8
[ebuild  N    ] sys-apps/kbd-1.12-r5
[ebuild  N    ] sys-apps/less-385_p4
[ebuild  N    ] sys-apps/man-pages-2.07
[ebuild  N    ] sys-apps/net-tools-1.60-r11
[ebuild  N    ] sys-process/procps-3.2.5-r1
[ebuild  N    ] sys-devel/libtool-1.5.18-r1
[ebuild  N    ] sys-process/psmisc-21.6
[ebuild  N    ] sys-libs/cracklib-2.8.3-r1
[ebuild  N    ] sys-devel/flex-2.5.4a-r6
[ebuild  N    ] dev-util/pkgconfig-0.18.1-r1
[ebuild  N    ] sys-libs/pam-0.78-r2
[ebuild  N    ] sys-apps/shadow-4.0.7-r4
[ebuild  N    ] sys-apps/pam-login-3.17
[ebuild  N    ] sys-apps/which-2.16
[ebuild  N    ] sys-devel/make-3.80-r2
[ebuild  N    ] sys-libs/com_err-1.38
[ebuild  N    ] sys-libs/ss-1.38
[ebuild  N    ] sys-fs/e2fsprogs-1.38
[ebuild  N    ] sys-apps/hotplug-base-20040401
[ebuild  N    ] sys-fs/udev-064
[ebuild  N    ] app-editors/nano-1.3.8
[ebuild  N    ] sys-apps/module-init-tools-3.2_pre7-r1
[ebuild  N    ] sys-apps/tcp-wrappers-7.6-r8
[ebuild  N    ] net-misc/openssh-4.1_p1-r1
[ebuild  N    ] sys-apps/busybox-1.00-r4
[ebuild  N    ] sys-apps/hdparm-6.1
[ebuild  N    ] app-crypt/hashalot-0.3
[ebuild  N    ] sys-apps/util-linux-2.12q-r1
[ebuild  N    ] sys-libs/pwdb-0.62-r1
[ebuild  N    ] sys-apps/linux32-2.0


45 minutes! :x

No, seriously, I can't tell you because I have a stability problem at the moment which causes seg faults whenever I compiile anything big and heavy, such as glibc or gcc. Actually, last night it happend with binutils, so it isn't just big beasts that cause it. The upshot is that I have to emerge --resume from time to time, and of course quite a lot of compiling tasks are repeated.
_________________
Rgds
Peter

Linux counter 5290, Aug 93.
Back to top
View user's profile Send private message
PRHumphrey
n00b
n00b


Joined: 23 Jan 2004
Posts: 6
Location: Tideswell, Derbyshire, UK

PostPosted: Fri Jul 29, 2005 1:27 pm    Post subject: Reply with quote

I decided to "killall boinc" before running my one-liner (BOINC is a distributed-computing client which crunches numbers at nice=19). The script ran to completion! First time for several months that anything more than a trivial emerge has finished in one go.

wstn ~ # time tcrebuild
... (much logging snipped)

real 113m58.019s
user 83m43.994s
sys 52m19.423s

tcrebuild is what I've called my version of the script, which I quoted before:
Code:
emerge --nodeps --oneshot --quiet linux-headers glibc binutils gcc && \
        emerge --nodeps --oneshot --quiet linux-headers glibc binutils gcc portage


So it seems to take a little under two hours, or about 2.3 times your 45 minutes :)
I have MAKEOPTS="-j5" in /etc/make.conf to make sure there's always something for each CPU to do.
_________________
Rgds
Peter

Linux counter 5290, Aug 93.
Back to top
View user's profile Send private message
kimmie
Guru
Guru


Joined: 08 Sep 2004
Posts: 531
Location: Australia

PostPosted: Mon Aug 08, 2005 7:40 pm    Post subject: Reply with quote

Ummm... forgive me if this is a n00b question but... is it safe to be using ccache through all this rebuilding? Should the cache be cleaned before starting?
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Tue Aug 09, 2005 3:20 am    Post subject: Reply with quote

If emerge and ccache are happy togather when you normally emerge then you wont have any probs with emwrap.sh.
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
maguire
Tux's lil' helper
Tux's lil' helper


Joined: 27 May 2004
Posts: 103
Location: Longmont, Colorado

PostPosted: Thu Aug 11, 2005 7:15 pm    Post subject: A completely-revised implementation of EMWRAP! Reply with quote

OK, get ready... :wink:

What does 1066 represent? The year of the Norman invasion of England?
No...
The number of lines in my own, thoroughly revised, completely re-worked, not-necessarily-better-but-definitely-more-readable version of emwrap.sh.

I decided to start modifying the emwrap.sh text, because I thought the formatting was so horrible. It really breaks about every best-practices convention for writing readable, maintainable code. I was also disappointed that the "continue" option of emwrap.sh really meant the equivalent of the "resume" option of emerge, and the "resume" option of emwrap.sh was something completely different. The way that the build process could be broken into pieces---although a good idea---seemed to be implemented in a more-confusing-than-necessary manner. You may very well disagree. I also completely re-worked the "help" page, making it truly huge and descriptive (and I therefore also added a shortened "usage" page). Finally, I don't like naming executable shell scripts with a ".sh" extension. Why differentiate the script from any other command? Commands don't have extensions, so my personal belief is that shell scripts (and Perl scripts) shouldn't have extensions. Does the end-user care in what language the program/command is written?

This script adds some new functionality for compiling Tool Chain elements. Namely, if gcc is recompiled, then immediately after the emerge of gcc, gcc-config is run to switch all subsequent compilations to the new compiler (See the 2005.0 Stage 1/3 NPTL by Bob Predaina). ***This is completely untested in this script!*** It may completely bomb, it may have a minor bug, I do not know, because I haven't had the opportunity to test it. I have only used this script to update system and world components. So, if you use this for TC components, be very careful, and let me know what happens! Thanks.

Here it is:

EDIT:
Due to problems copy-pasting code, please get the code from the link graciously provided by dol-sen on the next page (page 10), or on the first page (thanks hielvc!).
:D Failing that, I'll put the code here, but if the following file-integrity tests don't match, you may be experiencing the "copy-paste problem"! (And, unfortunately, after several versions, it no longer has 1066 lines... :( )

Code:
#!/bin/bash
#
# EMWRAP
#
# emwrap - A wrapper for 'emerge'.  Type:  $ emwrap --help
#
# 23-Aug-2005: * Extracted the 'emerge' from the SYSTEM+WORLD and the TC
# Version 4.2    updates---to eliminate a lot of common code.  Also, fixed a
# WBMII          bug in the selection of the GCC version with GCC-CONFIG.
#                Thanks "sfp-a7x" (from the Gentoo Forums)!
#                (There were a *lot* of modifications made for this version!)
#
# 18-Aug-2005: * When removing system packages from the world file in
# Version 4.1    "create_emerge_package_lists", I was sorting the contents
# WBMII          so that I could use 'comm'.  But I cannot re-order all the
#                files---dependencies matter!
#
# 11-Aug-2005: * Completely re-coded "emwrap.sh", using several key ideas
# Version 4.0    from that script, to create this script, "emwrap".
# WBMII
#
#_______________________________________________________________________________
# ---------------------------------------------------
# Comments from the original---"emwrap.sh"---version:
# ---------------------------------------------------
#
# Date 06-24-05 Removed the "v" option to emerge, and added clean_up to
#     remove dir created by emwrap Ver3.0.4
# Date 06-14-05 Version 3.0.2 fix function clean to clean up failed and sys
#     list.  Also added gcc-config and binutils-config to tc_filter.
# Date 05-08-05 Version 3.0.1 changed TC emerge || die, the old one didn't
#     die.  Also added -N.
# Date 05-02-05 Version 3.0.0 all functions
# Date 01-19-05 version 1.8.6 Hiel Van Campen
#
# This program is distributed under the terms of the GPL version 2
# Parts contributed by Ed Catmur <ed@catmur.co.uk> ;^), the parts that work,
# the help setup.
# Use at yee own risk. It works for me, but then I wrote it.
#
# Toolchain thang
# emerge linux-headers glibc && emerge glibc binutils gcc && emerge binutils gcc
#
# The build script for the edited wrld.lst-->build.lst. Anything that fails to
# emerge is copied to failed.lst  To view the build.lst or failed.lst use
# "less failed.lst" or your favorite pager.
#
# Version 2.0.5 , 3-30-05
# Now does sytem builds and then world minus the system files big time saver
# remove -o option since it redundit, added emptytree system and world were
# the world build does not include the system files. Rewrote help info.
# 4-6-05 Cleaned up where files that are created are put, and worked on fetch opotion.
# 4-23-05 Added -c for continue, aka resume, works with all functions. Thanks dol-sen
#_______________________________________________________________________________


# Boilerplate:
shopt -s -o nounset

#________________________________________________________________
#
# Explicitly set search PATH---for security!  Order is important:
#
declare -r PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
#
#               /bin
#               /usr/bin
#               /usr/local/bin
#               /sbin
#               /usr/sbin
#               /usr/local/sbin
#________________________________________________________________

#________________________________________________________________
#
# USER-MODIFIED variable declarations:
#
#
#----------------------------------------------------------------

#----------------------------------------------------------------
#
# INTERNAL variable declarations:
#
# This funtion's name:
declare me=$( echo ${0##*/} | tr '[:upper:]' '[:lower:]' )
#
# Version number w.r.t. the old, "emwrap.sh", number:
declare VERSION="4.2"
#
declare emerge_opts # All the option letters passed through to emerge.
declare pretend_flag
declare fetch_flag
declare do_tc_flag
declare do_system_flag
declare do_world_flag
declare resume_emwrap_flag # resume emwrap from where it stoped.
declare no_color_flag
# Flags indicating which Tool Chain packages need updating:
declare linux_headers_pkg
declare glibc_pkg
declare binutils_pkg
declare gcc_pkg
declare binutils_config_pkg
declare gcc_config_pkg
declare portage_pkg
# A temporary variable to hold a line from a package-list file:
declare file_line=
# Regular Expressions for matching all the TC components (including the
# config. packages and portage), and declare them read-only variables:
declare -r RE_hdrs='\/linux-headers-[0-9]'
declare -r RE_glibc='\/glibc-[0-9]'
declare -r RE_bin='\/binutils-[0-9]'
declare -r RE_bincfg='\/binutils-config-[0-9]'
declare -r RE_gcc='\/gcc-[0-9]'
declare -r RE_gcccfg='\/gcc-config-[0-9]'
declare -r RE_portage='\/portage-[0-9]'
# Color-holding variables...:
declare nc # NO color
declare RD ; declare Rd # Bold and Normal RED
declare GR ; declare Gr # Bold and Normal GREEN
declare YL ; declare Yl # Bold and Normal YELLOW
declare BL ; declare Bl # Bold and Normal BLUE
declare MG ; declare Mg # Bold and Normal MAGENTA
declare CY ; declare Cy # Bold and Normal CYAN
declare WH ; declare Wh # Bold and Normal WHITE
#
#----------------------------------------------------------------


###########################################################################
#    F U N C T I O N S       F U N C T I O N S       F U N C T I O N S    #
###########################################################################


function set_terminal_color_codes {
   # Use color!  Assign the terminal color-codes:
   # (Clear the color before *every* color setting!)
   nc=$'\x1b[0;0m' # NO color
   # BOLD color:                NORMAL color:
   # ------------------------   --------------------------
   RD=$'\x1b[0;0m\x1b[31;01m' ; Rd=$'\x1b[0;0m\x1b[00;31m' # RED
   GR=$'\x1b[0;0m\x1b[32;01m' ; Gr=$'\x1b[0;0m\x1b[00;32m' # GREEN
   YL=$'\x1b[0;0m\x1b[33;01m' ; Yl=$'\x1b[0;0m\x1b[00;33m' # YELLOW
   BL=$'\x1b[0;0m\x1b[34;01m' ; Bl=$'\x1b[0;0m\x1b[00;34m' # BLUE
   MG=$'\x1b[0;0m\x1b[35;01m' ; Mg=$'\x1b[0;0m\x1b[00;35m' # MAGENTA
   CY=$'\x1b[0;0m\x1b[36;01m' ; Cy=$'\x1b[0;0m\x1b[00;36m' # CYAN
   WH=$'\x1b[0;0m\x1b[37;01m' ; Wh=$'\x1b[0;0m\x1b[00;37m' # WHITE
}


function clear_terminal_color_codes {
   # Do *NOT* use color!  Un-assign the terminal color-codes:
   # (Every color-variable is unset!)
   nc=
   RD= ; Rd=
   GR= ; Gr=
   YL= ; Yl=
   BL= ; Bl=
   MG= ; Mg=
   CY= ; Cy=
   WH= ; Wh=
}


function print_usage {
   cat <<ENDusage
${GR}$me${Gr}: A wrapper for emerge.  ${Yl}Built with Bash + ${YL}WBMII ${Yl}(c)2005.${nc}
${Cy}Usage:  $me  [option ...]  {class}${nc}
${Mg}v.$VERSION.
${Gr}
Options:

These ${GR}$me${Gr} options are passed through to 'emerge' (all leading hyphens are
removed, so "help" is the same as "--help" and "-h").  See the 'emerge' MAN
page for descriptions of their functions:

   ${CY}-f, fetch${Gr}
   ${CY}-u, update${Gr}
   ${CY}-D, deep${Gr}
   ${CY}-e, empty[tree]${Gr}
   ${CY}-p, pretend${Gr}
   ${CY}-N, new[use]${Gr}
   ${CY}-r, res[ume]${Gr}  Resume the 'emerge' list from where it stopped.
                 To use, re-run the *exact same* command, but add the
                 "r" option.  It will start from where it stopped,
                 without having to rebuild everything before.  This
                 is analogous to the "--resume" in emerge.

The three '$me' build classes are unique to ${GR}$me${Gr} (at least one must be
specified, but any combination is allowed):

   ${CY}-t, tc, tool[chain]${Gr}  Build the ${YL}Tool Chain packages${Gr}.
   ${CY}-s, system${Gr}           Build the ${YL}SYSTEM packages${Yl}, *excluding* the TC packages${Gr}.
   ${CY}-w, world${Gr}            Build the ${YL}WORLD packages${Yl}, *excluding* the TC packages,
   ${CY}         ${Gr}              and *excluding* the SYSTEM packages${Gr}.

Miscellaneous ${GR}$me${Gr} options:

   ${CY}use, usage, opt[ions], <no args>${Gr}  Displays this Usage/options reminder.
   ${CY}-h, help, man${Gr}                     Displays the huge help page.
   ${CY}nc, nocol[or]${Gr}                     Turns off all colored output.
${Mg}
IMPORTANT: The definition of SYSTEM and WORLD are therefore *different* here
           than they are in 'emerge':

               '$me' flag:    'emerge' equivalent:
               --------------    --------------------
                  ${MG}-ts         ${Mg}=>${MG}    system
                  ${MG}-tsw        ${Mg}=>${MG}    world
                  ${MG}-t          ${Mg}=>    <only TC packages>
                  ${MG}-s          ${Mg}=>    <SYSTEM packages, but *not* TC packages>
                  ${MG}-w          ${Mg}=>    <WORLD packages, but *not* TC packages
                  ${MG}            ${Mg}       and *not* SYSTEM packages>
                  ${MG}-sw         ${Mg}=>    <WORLD packages, but *not* TC packages>
${nc}
ENDusage
}


function print_help {
   cat <<ENDhelp
${GR}$me${Gr}: A wrapper for emerge.  ${Yl}Built with Bash + ${YL}WBMII ${Yl}(c)2005.${nc}
${Cy}Usage:  $me  [option ...]  {class}${nc}
${Mg}v.$VERSION.
${Gr}
A wrapper for emerge to give special attention to the Tool Chain!
version $VERSION.

The Tool Chain (TC) is the group of packages that controls how the entire
system is built.  It is composed of the following packages:

   binutils[-config], gcc[-config], glibc, linux-headers, and portage.

If the Tool Chain (TC) is built using '$me', it is built in a special
order, and several packages are built twice.  This procedure insures that
critical TC packages are built against the newest versions of the other
TC components.

'$me' checks if the TC is scheduled to be updated and if so, allows several
options for handling the TC packages.  It uses an edited list of packages
generated by "emerge --pretend uD/e system/world", with the TC packages
removed, so that TC packages are considered seperately from all the other
system/world packages.  The TC packages may then be 'emerge'd seperately,
or they may be ignored while all the remaining packages are 'emerge'd.

'$me' has two primary uses:

1. Do a system/world update *without* updating any TC packages that have
   updates available.  This allows you to keep your system current, while
   maintaining a stable set of TC components upon which to build your
   entire system.

2. Test if there is a TC update in "emerge system/world -uD", and if there
   is, allow you several options for rebuilding your TC and all the
   remaining non-TC packages.

The first use above (1) will be used most frequently.  When you *do* want
to update your Tool Chain, the second use above (2) will allow you to
rebuild the Tool Chain packages first---in an optimal order---and then
optionally rebuild all the non-Tool-Chain packages of either the SYSTEM
or WORLD class.

The flags are chainable and determine whether you do a system or world
emerge, and whether you do a "deep update" emerge or an "emptytree" emerge.
There is also a "pretend" mode, which behaves the same as the pretend flag
in emerge.  It is *strongly* recommended that you run your desired command
with the "-p" option first, and *if* everything looks good, *then* run the
command again without the pretend flag.

Remember, only *you* can prevent forest files!  ;-)

Options:

These ${GR}$me${Gr} options are passed through to 'emerge' (all leading hyphens are
removed, so "help" is the same as "--help", "-h", and "h").  See the 'emerge' MAN
page for descriptions of their functions:

   ${CY}-f, fetch${Gr}
   ${CY}-u, update${Gr}
   ${CY}-D, deep${Gr}
   ${CY}-e, empty[tree]${Gr}
   ${CY}-p, pretend${Gr}
   ${CY}-N, new[use]${Gr}
   ${CY}-r, res[ume]${Gr}  Resume the 'emerge' list from where it stopped.
                 To use, re-run the *exact same* command, but add the
                 "r" option.  It will start from where it stopped,
                 without having to rebuild everything before.  This
                 is analogous to the "--resume" in emerge.

The three '$me' build classes are unique to ${GR}$me${Gr} (at least one must be
specified, but any combination is allowed):

   ${CY}-t, tc, tool[chain]${Gr}  Build the ${YL}Tool Chain packages${Gr}.
   ${CY}-s, system${Gr}           Build the ${YL}SYSTEM packages${Gr}, *excluding* the TC packages.
   ${CY}-w, world${Gr}            Build the ${YL}WORLD packages${Gr}, *excluding* the TC packages,
   ${CY}         ${Gr}              and *excluding* the SYSTEM packages.

Miscellaneous ${GR}$me${Gr} options:

   ${CY}use, usage, opt[ions], <no args>${Gr}  Displays a Usage/options reminder.
   ${CY}-h, help, man${Gr}                     Displays this huge help page.
   ${CY}nc, nocol[or]${Gr}                     Turns off all colored output.
${Mg}
IMPORTANT: The definition of SYSTEM and WORLD are therefore *different* here
           than they are in 'emerge':

               '$me' flag:    'emerge' equivalent:
               --------------    --------------------
                  ${MG}-ts         ${Mg}=>${MG}    system
                  ${MG}-tsw        ${Mg}=>${MG}    world
                  ${MG}-t          ${Mg}=>    <only TC packages>
                  ${MG}-s          ${Mg}=>    <SYSTEM packages, but *not* TC packages>
                  ${MG}-w          ${Mg}=>    <WORLD packages, but *not* TC packages
                  ${MG}            ${Mg}       and *not* SYSTEM packages>
                  ${MG}-sw         ${Mg}=>    <WORLD packages, but *not* TC packages>
${Gr}
            The reason for the new definitions of "system" (doesn't include
            TC packages) and "world" (doesn't include TC or SYSTEM packages)
            is to give you maximum flexibility to compile each of the three
            groups of packages separately.  In reality, though, you will
            most likely just use ${Cy}emwrap -uDsw${Gr} in place of the usual
            ${Cy}emerge -uD world${Gr}, to update all your packages---but not touching
            any Tool Chain packages.  Then, when you want to spend the time
            to upgrade the TC, you can split the workload by first updating
            all the TC packages with ${Cy}emwrap -et${Gr}, and then rebuilding all the
            SYSTEM and WORLD packages with ${Cy}emwrap -esw${Gr}.  (Or you could just
            do it *all* in one fell swoop with ${Cy}emwrap -etsw${Gr}.)

Examples:      ( TC <=> Tool Chain )

   Emerge updated packages in the emerge WORLD class, *except* TC packages:
      ${Cy}$ emwrap -puDsw${Gr}
      ${Cy}$ emwrap -uDsw${Gr}  =>  emerge -uD world

   Emerge *all* packages in the emerge SYSTEM class, *except* TC packages:
      ${Cy}$ emwrap -pes${Gr}
      ${Cy}$ emwrap -es${Gr}    =>  emerge -e system

   Emerge updated TC packages:
      ${Cy}$ emwrap -puDt${Gr}
      ${Cy}$ emwrap -uDt${Gr}   =>  emerge -uD <TC packages>

   Emerge *all* TC packages (a full TC rebuild):
      ${Cy}$ emwrap -pet${Gr}
      ${Cy}$ emwrap -et${Gr}    =>  emerge -e <TC packages>

   Emerge *all* TC packages, then *all* the non-TC SYSTEM and WORLD packages:
      ${Cy}$ emwrap -petsw${Gr}
      ${Cy}$ emwrap -etsw${Gr}  =>  emerge -e <TC packages>
                          && emerge -e <all non-TC WORLD packages>

   Fetch the appropriate packages, but don't do any building:
      ${Cy}$ emwrap -f...${Gr}  =>  emerge -f...

${Rd}
   Here are the TC build lists used in '$me' when doing updates:

   linux-headers:  linux-headers glibc [*] binutils gcc glibc binutils gcc
   glibc:                        glibc [*] binutils gcc glibc binutils gcc
   binutils or gcc:                    [*] binutils gcc       binutils gcc

   [*] => Whatever updates are in the following list: binutils-config
                                                      gcc-config
                                                      portage
${nc}
ENDhelp
}


function get_command_line_options {
   # The total number of function arguments (CL parameters):
   declare -i numparams=$#
   # Local variables:
   declare opt # The "getopts" CL flag
   declare got_one # A flag set when a CL parameter is decoded.

   # By default, assign the terminal color-codes:
   # (If the "--nocolor" command-line option is found, then they
   #  will be cleared using "clear_terminal_color_codes", and the
   #  "--nocolor" flag will also be passed through to 'emerge'!)
   set_terminal_color_codes

   # No parameters passed?  Print Usage and quit:
   if [ "$numparams" -eq 0 ] ; then
      print_usage
      exit 1
   fi

   # While there is still a command-line parameter on the $@ list, process
   # it:
   while [ "$numparams" -gt 0 ] ; do
      # Reset the flag saying whether I decoded a CL parameter:
      got_one=
      # Remove any number of dashes (-) from the argument, and then check
      # the value against a 'case' list to see if this is a "word"
      # parameter::
      # ------------------------------------------------------------------+
      # Debugging CL parsing:                                             |
      case ${1##*-} in
             use ) echo "${Yl}--use${nc}"       ;; #                      |
           usage ) echo "${Yl}--usage${nc}"     ;; #                      |
            opt* ) echo "${Yl}--opt${nc}"       ;; #                      |
            help ) echo "${Yl}--help${nc}"      ;; #                      |
             man ) echo "${Yl}--man${nc}"       ;; #                      |
           world ) echo "${Yl}--world${nc}"     ;; #                      |
          system ) echo "${Yl}--system${nc}"    ;; #                      |
           tool* ) echo "${Yl}--toolchain${nc}" ;; #                      |
              tc ) echo "${Yl}--toolchain${nc}" ;; #                      |
          update ) echo "${Yl}--update${nc}"    ;; #                      |
            deep ) echo "${Yl}--deep${nc}"      ;; #                      |
          empty* ) echo "${Yl}--emptytree${nc}" ;; #                      |
            new* ) echo "${Yl}--newuse${nc}"    ;; #                      |
         pretend ) echo "${Yl}--pretend${nc}"   ;; #                      |
          resume ) echo "${Yl}--resume${nc}"    ;; #                      |
          fetch* ) echo "${Yl}--fetch${nc}"     ;; #                      |
          nocol* ) echo "${Yl}--nocolor${nc}"   ;; #                      |
             nc* ) echo "${Yl}--nc${nc}"        ;; #                      |
         verbose ) echo "${Yl}--verbose${nc}"   ;; #                      |
      esac
      # ------------------------------------------------------------------+
      case ${1##*-} in
             use ) print_usage                   ; exit 2        ;;
           usage ) print_usage                   ; exit 2        ;;
            opt* ) print_usage                   ; exit 2        ;;
            help ) print_help                    ; exit 2        ;;
             man ) print_help                    ; exit 2        ;;
           world ) do_world_flag="yes"           ; got_one="yes" ;;
          system ) do_system_flag="yes"          ; got_one="yes" ;;
           tool* ) do_tc_flag="yes"              ; got_one="yes" ;;
              tc ) do_tc_flag="yes"              ; got_one="yes" ;;
          update ) emerge_opts="${emerge_opts}u" ; got_one="yes" ;;
            deep ) emerge_opts="${emerge_opts}D" ; got_one="yes" ;;
          empty* ) emerge_opts="${emerge_opts}e" ; got_one="yes" ;;
            new* ) emerge_opts="${emerge_opts}N" ; got_one="yes" ;;
         pretend ) pretend_flag="-p"             ; got_one="yes" ;;
          resume ) resume_emwrap_flag="yes"      ; got_one="yes" ;;
          fetch* ) fetch_flag="-f"               ; got_one="yes" ;;
          nocol* ) no_color_flag="--nocolor"
                      clear_terminal_color_codes ; got_one="yes" ;;
             nc* ) no_color_flag="--nocolor"
                      clear_terminal_color_codes ; got_one="yes" ;;
         verbose ) :                             ; got_one="yes" ;;
               * ) :                                             ;;
                   # Have to ignore unknown words---to process them
                   # in the other 'case' statement!
      esac

      # Reset the "getopts" parameter-index couter manually.  The getopts
      # man page clearly says that the counter must be manually reset when
      # getopts is called again in the same script:
      OPTIND=1

      # If I didn't already decode a parameter above, then try "getopts":
      if [ ! -n "$got_one" ] ; then
         while getopts ":DefhNprstuvw " opt $1 ; do
            # Decode a flag letter:
            # ------------------------------------------------+
            # Debugging CL parsing:                           |
            case $opt in
               h ) echo "${Yl}--help (h)${nc}"      ;; #      |
               w ) echo "${Yl}--world (w)${nc}"     ;; #      |
               s ) echo "${Yl}--system (s)${nc}"    ;; #      |
               t ) echo "${Yl}--toolchain (t)${nc}" ;; #      |
               u ) echo "${Yl}--update (u)${nc}"    ;; #      |
               D ) echo "${Yl}--deep (D)${nc}"      ;; #      |
               e ) echo "${Yl}--emptytree (e)${nc}" ;; #      |
               N ) echo "${Yl}--newuse (N)${nc}"    ;; #      |
               p ) echo "${Yl}--pretend (p)${nc}"   ;; #      |
               r ) echo "${Yl}--resume (r)${nc}"    ;; #      |
               f ) echo "${Yl}--fetch (f)${nc}"     ;; #      |
               v ) echo "${Yl}--verbose (v)${nc}"   ;; #      |
            esac
            # ------------------------------------------------+
            case $opt in
               h ) print_help                    ; exit 3        ;;
               w ) do_world_flag="yes"           ; got_one="yes" ;;
               s ) do_system_flag="yes"          ; got_one="yes" ;;
               t ) do_tc_flag="yes"              ; got_one="yes" ;;
               u ) emerge_opts="${emerge_opts}u" ; got_one="yes" ;;
               D ) emerge_opts="${emerge_opts}D" ; got_one="yes" ;;
               e ) emerge_opts="${emerge_opts}e" ; got_one="yes" ;;
               N ) emerge_opts="${emerge_opts}N" ; got_one="yes" ;;
               p ) pretend_flag="-p"             ; got_one="yes" ;;
               r ) resume_emwrap_flag="yes"      ; got_one="yes" ;;
               f ) fetch_flag="-f"               ; got_one="yes" ;;
               v ) :                             ; got_one="yes" ;;
               * ) :                                             ;;
                   # Have to ignore unknown letters---to process them
                   # in the other 'case' statement!
            esac

            # Check for a bad CL option:
            if [ "$opt" == "?" ] ; then
               # If I got here, it means that there was a bad CL option
               # (with a leading dash---since 'getopts' "saw" it):
               echo >&2
               echo "${RD}ERROR: $me: ${Rd}Unknown option: \"${RD}$OPTARG${Rd}\"!${nc}" >&2
               echo >&2
               print_usage
               exit 7
            fi
         done #<--End of the 'while' loop over "getopts".
      fi #<--End of the 'if' testing if a "word" option was already found.

      # Check for a bad CL option:
      if [ ! -n "$got_one" ] ; then
         # If I got here, it means that there was a bad CL option
         # (*without* any leading dashes---because 'getopts' missed it):
         echo >&2
         echo "${RD}ERROR: $me: ${Rd}Unknown option: \"${RD}${1##*-}${Rd}\"!${nc}" >&2
         echo >&2
         print_usage
         exit 4
      fi

      # Shift the just-processed CL argument off of "$@":
      (( numparams-- )) ; shift #<--Remove this positional parameter
   done #<--End of the 'while' loop over all the command-line parameters.

   # Make sure that *at least one* class was supplied as a
   # command-line option (-t|-s|-w|--tool|--system|--world):
   if [ ! -n "$do_tc_flag" ] \
   && [ ! -n "$do_world_flag"  ] \
   && [ ! -n "$do_system_flag" ] ; then
      echo >&2
      echo "${RD}ERROR: $me: ${Rd}Must supply one or more classes: {-t|tool} {-s|system} {-w|world}!${nc}" >&2
      echo >&2
      print_usage
      exit 4
   fi

   # Debugging CL parsing:
   echo
}


function change_to_tmp_emwrap_directory {
   # Local variables:
   declare -i return_code=0 # Hold return status.

   # (If this is a brand new build, $HOME isn't set!)
   # Does the directory already exist?:
   if [ ! -d /tmp/emwrap ] ; then
      # No; create it:
      mkdir /tmp/emwrap \
      || {
         return_code=$?
         echo "${RD}ERROR: $me: ${Rd}Cannot create \"/tmp/emwrap\" directory!${nc}" >&2
         exit $return_code
      }
      # Optional (these don't *need* to succeed):
      chmod 775 /tmp/emwrap             >/dev/null 2>&1
      chown portage:portage /tmp/emwrap >/dev/null 2>&1
   fi
   # Does the directory have the necessary permissions?:
   if [ ! -r /tmp/emwrap ] \
   || [ ! -w /tmp/emwrap ] \
   || [ ! -x /tmp/emwrap ]; then
      # Bad permissions!
      echo "${RD}ERROR: $me: ${Rd}Don't have r|w|x permissions on \"/tmp/emwrap\" directory!${nc}" >&2
      exit 9
   fi
   # Change pwd to the temporary directory:
   cd /tmp/emwrap \
   || {
      return_code=$?
      echo "${RD}ERROR: $me: ${Rd}Cannot 'cd' to the \"/tmp/emwrap\" directory!${nc}" >&2
      exit $return_code
   }
   # Just to be super-duper safe:
   if [ "$( pwd )" != "/tmp/emwrap" ] ; then
      echo "${RD}ERROR: $me: ${Rd}The 'pwd' is not \"/tmp/emwrap\"?!?  How?!?${nc}" >&2
      exit 19
   fi

   # I *always* want to clear-out the failed-list file:
   cat /dev/null >failed_list.txt
}


function get_all_tc_packages {
   # For efficiency, use 'awk' rather than one giant 'grep' command:
   # (Also, more specifically match with the RegEx to not get unintended
   # packages (see comment at top of file) and added portage.)
   # Use the Regular Expression variables declared at the top of the file:
   awk "/$RE_hdrs|$RE_glibc|$RE_bin|$RE_bincfg|$RE_gcc|$RE_gcccfg|$RE_portage/"
}


function remove_all_tc_packages {
   # For efficiency, use 'awk' rather than chained 'grep -vE' commands:
   # (Also, more specifically match with the RegEx to not filter-out
   # unintended packages (see comment at top of file) and added portage.)
   # Use the Regular Expression variables declared at the top of the file:
   awk "!/$RE_hdrs|$RE_glibc|$RE_bin|$RE_bincfg|$RE_gcc|$RE_gcccfg|$RE_portage/"
}


function create_emerge_package_lists {
   # Local variables:
   declare -i return_code=0 # Hold return status.

   # Extract the package names and versions from the printed lines:
   # Make sure that all the list files exist, and are empty:
   cat /dev/null >world_list.txt
   cat /dev/null >system_list.txt
   cat /dev/null >world_and_system_list.txt
   cat /dev/null >alltools_list.txt
   # The EMERGE WORLD package list (includes TC and SYSTEM packages):
   echo "${Gr}Building a list of EMERGE WORLD packages...${nc}"
   emerge --pretend "-$emerge_opts" --nocolor --nospinner world \
      | cut -s -f2 -d ']'        \
      | cut    -f1 -d '['        \
      | sed 's/^[ ]\+//'         \
      | sed 's/[ ].*$//'         \
      >world_and_system_list.txt \
   || {
      return_code=$?
      echo "${RD}ERROR: $me: ${Rd}emerge --pretend >world_and_system_list.txt failed!${nc}" >&2
      exit $return_code
   }
   # The EMERGE SYSTEM package list (includes TC packages):
   echo "${Gr}Building a list of EMERGE SYSTEM packages...${nc}"
   emerge --pretend "-$emerge_opts" --nocolor --nospinner system \
      | cut -s -f2 -d ']'      \
      | cut    -f1 -d '['      \
      | sed 's/^[ ]\+//'       \
      | sed 's/[ ].*$//'       \
      >system_list.txt         \
   || {
      return_code=$?
      echo "${RD}ERROR: $me: ${Rd}emerge --pretend >system_list.txt failed!${nc}" >&2
      exit $return_code
   }
   # The ALL TOOLS package list (all the TC packages):
   echo "${Gr}Building a list of (emptytree) TOOL CHAIN packages...${nc}"
   emerge --pretend --emptytree --nocolor --nospinner world \
      | cut -s -f2 -d ']'      \
      | cut    -f1 -d '['      \
      | sed 's/^[ ]\+//'       \
      | sed 's/[ ].*$//'       \
      | get_all_tc_packages    \
      >alltools_list.txt       \
   || {
      return_code=$?
      echo "${RD}ERROR: $me: ${Rd}emerge --pretend >all_tools_list.txt failed!${nc}" >&2
      exit $return_code
   }
   echo

   # If the user chooses a SYSTEM emerge, then the packages will be in the
   # *exact* order of the 'emerge system' results.
   #
   # If the user chooses a SYSTEM + WORLD emerge, then the packages will be
   # in the *exact* order of the 'emerge world' results.
   #
   # If the user chooses a WORLD emerge, then the packages will be the
   # world-only (no system) packages, in the order they were in the
   # 'emerge world' results.

   {
      # Read a line from "world_and_system_list.txt", and if it is *not* in the
      # "system_list.txt" file, append it to the world_list file:
      while read file_line ; do
         # Hopefully, no meta-character will cause a problem:
         if ! grep --line-regexp "$file_line" system_list.txt >/dev/null 2>&1 ; then
            echo "$file_line" >>world_list.txt
         fi
      done
   } < world_and_system_list.txt
}


function check_for_tc_updates {
   # Test for TC packages:
   linux_headers_pkg=$( grep $RE_hdrs  world_and_system_list.txt )
           glibc_pkg=$( grep $RE_glibc world_and_system_list.txt )
        binutils_pkg=$( grep $RE_bin   world_and_system_list.txt )
             gcc_pkg=$( grep $RE_gcc   world_and_system_list.txt )
   #
   # Even if there are newer versions of the FOLLOWING packages, they will
   # *NOT* trigger a message telling you that there are TC package updates
   # available and they will not be updated until an actual TC update is
   # performed.  The logic is, that although they are critical components,
   # they alone do not justify a new TC build.
   #
   binutils_config_pkg=$( grep $RE_bincfg  world_and_system_list.txt )
        gcc_config_pkg=$( grep $RE_gcccfg  world_and_system_list.txt )
           portage_pkg=$( grep $RE_portage world_and_system_list.txt )

   # Show what configs and portage have updates (not done until a TC build):
   if [ -n "$binutils_config_pkg" ] \
   || [ -n "$gcc_config_pkg"      ] \
   || [ -n "$portage_pkg"         ] ; then
      echo "${Yl}A Tool Chain config-file or portage update was found.${nc}"
      echo "${Yl}'emerge'ing these packages will only occur with a TC build:${nc}"
      echo
      if [ -n "$binutils_config_pkg" ] ; then echo "${Yl}   ${binutils_config_pkg##*/}${nc}" ; fi
      if [ -n "$gcc_config_pkg" ]      ; then echo "${Yl}   ${gcc_config_pkg##*/}${nc}"      ; fi
      if [ -n "$portage_pkg" ]         ; then echo "${Yl}   ${portage_pkg##*/}${nc}"         ; fi
      echo
   fi
   # Show what main TC items have updates:
   if [ -n "$linux_headers_pkg" ] \
   || [ -n "$glibc_pkg"         ] \
   || [ -n "$binutils_pkg"      ] \
   || [ -n "$gcc_pkg"           ] ; then
      echo "${RD}A Tool Chain update was found!${nc}"
      echo "${RD}'emerge'ing these packages will only occur with a TC build:${nc}"
      echo
      if [ -n "$linux_headers_pkg" ] ; then echo "${Rd}   ${linux_headers_pkg##*/}${nc}" ; fi
      if [ -n "$glibc_pkg" ]         ; then echo "${Rd}   ${glibc_pkg##*/}${nc}"         ; fi
      if [ -n "$binutils_pkg" ]      ; then echo "${Rd}   ${binutils_pkg##*/}${nc}"      ; fi
      if [ -n "$gcc_pkg" ]           ; then echo "${Rd}   ${gcc_pkg##*/}${nc}"           ; fi
      echo
   else
      echo ${GR}"No primary Tool Chain updates are available.${nc}"
      echo
   fi
}


function emerge_packages_from_this_list {
   # The total number of function arguments (CL parameters):
   declare -i numparams=$#
   # Function parameters (initialized below!):
   declare    packages  # Either a FILE name or a single PACKAGE name.
   declare    classname # SYSTEM, WORLD,... (just a string to print).
   declare -i total_package_count # The total number of packages to merge.
   declare -i this_package_count  # An optional parameter.
   # Variables local to this function:
   declare -i return_code=0 # Hold return status.
   declare -a package_list #<--Bash array of package names
   declare -i count=0
   declare    package
   declare    loop_counter
   declare    failed_merge
   # A global variable that must be declared in the caller code:
   #     successful_emerges <- 0
   # (because I cannot return any value >255 via exit codes!)

   # INITIALIZE funtion parameters (CL arguments):
   #
   # MANDATORY arguments:
   if [ "$numparams" -lt 3 ] ; then
      # Must have AT LEAST two arguments:
      echo "${RD}ERROR: $me: ${Rd}Not enough params!?!${nc}" >&2
      exit 10
   fi
   packages=$1  # Either a FILE name or a single PACKAGE name.
   classname=$2 # SYSTEM, WORLD,... (just a string to print).
   total_package_count=$3 # The total number of packages to merge.
   # The OPTIONAL argument:
   if [ "$numparams" -ge 4 ] ; then this_package_count=$4 ; fi

   # In the case of SYSTEM and WORLD 'emerge's, this will be a FILENAME
   # containing packages to merge.  In the case of TOOLCHAIN 'emerge's, this
   # will be a single package name.  Which is it?:
   if [ -s "$packages" ] ; then
      # The argument is a FILE, put its contents into "package_list":
      package_list=$( cat $packages )
   else
      # The argument is a single package name, put it into "package_list":
      package_list="$packages"
   fi

   # Loop over all the packages that need 'emerge'ing:
   for package in $package_list ; do
      # Use our own count here, or the one supplied via the optional argument:
      if [ -n "$this_package_count" ] ; then
         count=$this_package_count
      else
         count=$(( count + 1 ))
      fi
      echo "${BL}$count of $total_package_count  $classname packages:${nc}"
      echo "${GR}$package${nc}"
      if [ ! -n "$pretend_flag" ] ; then
         echo "${Yl}Kill me NOW, or forever hold your peace!${nc}"
         echo "${Yl}(sleeping for 10 seconds...)${nc}"
         for loop_counter in 10 9 8 7 6 5 4 3 2 1 ; do
            echo -n "$loop_counter "
            sleep 1
         done
         echo
         echo "${Yl}(continuing...)${nc}"
      fi
      emerge $pretend_flag $fetch_flag $no_color_flag --verbose --oneshot --nodeps --nospinner =$package \
      || {
         failed_merge='failed'
         return_code=$?
         echo "${RD}Warning: $me: ${Rd}$package failed to build.  'emerge' exited code: $return_code.${nc}" >&2
         echo "$package" >>failed_list.txt
      }
      echo
      if [ ! -n "$pretend_flag" ] \
      && [ ! -n "$failed_merge" ] ; then
         # Bump the GLOBAL-variable:
         (( successful_emerges++ ))
         # Remove the just-merged package name from every package list
         # (don't bother with the "alltools_list.txt" file!):
         # SYSTEM list:
         grep -v "$package" system_list.txt            >temp_list.txt
         cat temp_list.txt >system_list.txt
         # WORLD list:
         grep -v "$package" world_list.txt             >temp_list.txt
         cat temp_list.txt >world_list.txt
         # WORLD *and* SYSTEM list:
         grep -v "$package" world_and_system_list.txt  >temp_list.txt
         cat temp_list.txt >world_list.txt
         # Remove the temporary file:
         rm -f temp_list.txt
      fi
   done
   # Return with the last 'emerge' failure code (if any):
   return $return_code
}


function emerge_tc_updates {
   # Variables local to this function:
   declare -i return_code=0 # Hold return status.
   declare -i count=0
   declare -i num_packages=0
   declare    tc_list
   declare    package
   declare    chost       # The value of the CHOST in "/etc/make.conf".
   declare    gcc_current # The number of the current GCC (from "gcc-config").
   declare    gcc_version_number # The version number of the new GCC pkg.
   declare    gcc_regex
   declare    gcc_for_gcc_config # The gcc version handed to gcc-config.
   declare    loop_counter
   # A global variable in the scope of the function call to:
   # "emerge_packages_from_this_list" (because if I use the
   # return code as a return value, it can only be <=255!):
   declare -i successful_emerges=0

   # Original TC lists:
   #
   #TC="linux-headers glibc $binutils_config $gcc_config $portage binutils gcc glibc binutils gcc"
   #TC_glib="glibc $binutils_config $gcc_config $portage  binutils gcc glibc binutils gcc"
   #TC_mini="$binutils_config $gcc_config $portage  binutils gcc binutils gcc"

   # Proceed to test in the order of smallest-list to largest-list (least
   # inclusive emerge list to most inclusive emerge list), so that the last
   # component matched should force the largest rebuild:

   if [ -n "$gcc_pkg"      ] \
   || [ -n "$binutils_pkg" ] ; then
      tc_list="                        \
                  $binutils_config_pkg \
                  $gcc_config_pkg      \
                  $portage_pkg         \
                  binutils             \
                  gcc                  \
                  _RUN_GCC_CONFIG_     \
                  binutils gcc         \
              "
   fi
   if [ -n "$glibc_pkg" ] ; then
      tc_list="                        \
                  glibc                \
                  $binutils_config_pkg \
                  $gcc_config_pkg      \
                  $portage_pkg         \
                  binutils             \
                  gcc                  \
                  _RUN_GCC_CONFIG_     \
                  glibc                \
                  binutils             \
                  gcc                  \
              "
   fi
   if [ -n "$linux_headers_pkg" ] ; then
      tc_list="                        \
                  linux-headers        \
                  glibc                \
                  $binutils_config_pkg \
                  $gcc_config_pkg      \
                  $portage_pkg         \
                  binutils             \
                  gcc                  \
                  _RUN_GCC_CONFIG_     \
                  glibc                \
                  binutils             \
                  gcc                  \
              "
   fi

   # Now that the Tool Chain list has been constructed---containing the
   # appropriate list of Tool Chain packages to 'emerge' in the proper order
   # ---I need to fill the "$gcc_pkg" variable with the name of the gcc
   # package (even if it wasn't a package that originally needed updating).
   # This is because *other* packages (glibc for example) will require gcc to
   # be 'emerge'd!  So, just fill *all* the package variables with their
   # values from an 'emerge -pe' (since I no longer need their values as
   # *flags*, as I used prior to this point):
   linux_headers_pkg=$( grep $RE_hdrs    alltools_list.txt )
           glibc_pkg=$( grep $RE_glibc   alltools_list.txt )
        binutils_pkg=$( grep $RE_bin     alltools_list.txt )
             gcc_pkg=$( grep $RE_gcc     alltools_list.txt )
 binutils_config_pkg=$( grep $RE_bincfg  alltools_list.txt )
      gcc_config_pkg=$( grep $RE_gcccfg  alltools_list.txt )
         portage_pkg=$( grep $RE_portage alltools_list.txt )

   if [ -n "$tc_list" ] ; then
      echo "${RD}+---------------------------+${nc}"
      echo "${RD}| Begin Tool Chain updates! |${nc}"
      echo "${RD}+---------------------------+${nc}"
      echo
      for package in $tc_list ; do
         if [ "$package" != "_RUN_GCC_CONFIG_" ] ; then
            (( num_packages++ ))
            echo -n "   "
            echo "${RD}$package${nc}" | tr -s ' '
         fi
      done
      echo

      for package in $tc_list ; do
         if [ "$package" != "_RUN_GCC_CONFIG_" ] ; then
            #
            # A normal TC package to emerge:
            #
            count=$(( count + 1 ))
            # emerge this TOOL CHAIN package:
            # (Called with the OPTIONAL parameter: package count):
            emerge_packages_from_this_list "$package"    \
                                           "TOOL CHAIN"  \
                                           $num_packages \
                                           $count        \
            || {
               # There was a FAILED TC emerge!
               # I cannot survive this!  Exit!:
               return_code=$?
               echo >&2
               echo "${RD}ERROR: $me: ${Rd}$package TC-package failed to build!${nc}" >&2
               echo >&2
               exit $return_code # The 'emerge' exit code.
            }
         else
            #
            # I hit the special flag telling me to run GCC-CONFIG:
            #
            # Get the currently active GCC:
            gcc_current=$( gcc-config -l | grep '\*' | sed 's/^[^ ]*[ ]*\([a-zA-Z0-9_.-]\+\).*$/\1/' )
            #              \____the current GCC____/   \____extract just the CHOST-gcc-version____/
            #
            # Get the name of the new, updated GCC version:
            gcc_version_number=$( echo "$gcc_pkg" | sed 's/^.*\(-[0-9].*\)/\1/' | sed 's/-r[0-9][^-.]*$//' )
            #                     \__whole pkg__/   \__just version numbers!__/   \__strip end "-r..."__/
            #
            # (The above extraction of the version number---minus any trailing
            #  "-r[0-9]<anything but a dash or dot>"---using SED *could* be
            #  done in a single 'sed' command, but I think it is clearer to
            #  split it up!)
            #
            # Get the CHOST:
            chost=$( grep "^[^#]*CHOST=" /etc/make.conf | sed 's/^[^#]*CHOST=["]\?\([a-zA-Z0-9_-]\+\).*$/\1/' )
            #        \_______get the CHOST name_______/   \_________extract just the CHOST string_________/
            #
            # Now, since the gcc version number from 'emerge' seems to
            # sometimes differ slightly from the version number in the
            # "/etc/env.d/gcc/" directory---which is the one that I need to
            # give to 'gcc-config'---find the proper filename from that
            # directory.  The trick here, is that all dot, underscore, and
            # dash characters will be converted to "[._-]" in the RegEx string
            # so that those characters are interchangeable!:
            gcc_regex=$( echo "${chost}${gcc_version_number}" | sed 's/[._-]/[._-]/g' )
            # Pick that RegEx out of the directory listing:
            gcc_for_gcc_config=$( ls /etc/env.d/gcc | grep "^${gcc_regex}$" )
            #
            # Select the new GCC version for future compilations:
            echo
            echo "${RD}BEFORE selecting new GCC:${nc}"
            gcc-config -l
            echo
            if [ -n "$pretend_flag" ] ; then
               echo "${RD}**********************************************************************${nc}"
               echo "${RD}I would do:  # gcc-config \$( \\${nc}"
               echo "${RD}                 ls /etc/env.d/gcc \\${nc}"
               echo "${RD}                 | grep \"^$gcc_regex$\" \\${nc}"
               echo "${RD}               )${nc}"
               echo "${RD}**********************************************************************${nc}"
               echo
            else
               echo "${RD}**********************************************************************${nc}"
               echo "${RD}I'm going to execute:  # gcc-config ${gcc_for_gcc_config}${nc}"
               echo "${RD}**********************************************************************${nc}"
               echo "${Rd}Kill me NOW, or forever hold your peace!${nc}"
               echo "${Rd}(sleeping for 15 seconds...)${nc}"
               for loop_counter in 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 ; do
                  echo -n "$loop_counter "
                  sleep 1
               done
               echo
               echo "${Rd}(continuing...)${nc}"
               gcc-config "$gcc_for_gcc_config" \
               || {
                  return_code=$?
                  echo "${RD}ERROR: $me: ${Rd}gcc-config $gcc_for_gcc_config failed!${nc}" >&2
                  exit $return_code
               }
               echo
               echo "${RD}AFTER selecting new GCC:${nc}"
               gcc-config -l
               echo
            fi #<--End of the 'if-then-else' I'm pretending.
            # The newly-'emerge'd GCC should now be selected for futures
            # compilations!
         fi #<--End of 'if-then-else' for "_RUN_GCC_CONFIG_" parameter.
      done #<--End of 'for' loop over the packages in the supplied list.
   fi #<--End of the 'if' there are any TC packages to be emerged.

   if [ "$successful_emerges" -eq 0 ] ; then
      echo "${BL}NO TOOL CHAIN packages were 'emerge'd.${nc}"
      echo
   fi
}


function remove_tc_packages_from_lists {
   # Remove from all *but* the "alltools_list.txt" file:
   # SYSTEM list:
   cat system_list.txt         \
      | remove_all_tc_packages \
      >temp_list.txt ;
      cat temp_list.txt        \
      >system_list.txt
   # WORLD list:
   cat world_list.txt          \
      | remove_all_tc_packages \
      >temp_list.txt ;
      cat temp_list.txt        \
      >world_list.txt
   # WORLD *and* SYSTEM list:
   cat world_and_system_list.txt \
      | remove_all_tc_packages   \
      >temp_list.txt ;
      cat temp_list.txt          \
      >world_and_system_list.txt
   # Remove the temporary file:
   rm -f temp_list.txt
}


function emerge_system_or_world {
   # Variables local to this function:
   declare -i num_packages
   declare -i num_packages_total=0
   # A global variable in the scope of the function call to:
   # "emerge_packages_from_this_list" (because if I use the
   # return code as a return value, it can only be <=255!):
   declare -i successful_emerges=0

   # Get the total number of 'emerge's:
   if [ -n "$do_system_flag" ] ; then
      num_packages=$( cat system_list.txt | wc -l )
      num_packages_total=$(( num_packages_total + num_packages ))
   fi
   if [ -n "$do_world_flag" ] ; then
      num_packages=$( cat world_list.txt | wc -l )
      num_packages_total=$(( num_packages_total + num_packages ))
   fi

   # emerge SYSTEM (*not* WORLD) packages?:
   if [   -n "$do_system_flag" ] \
   && [ ! -n "$do_world_flag" ] ; then
      # (Ignore the number-of-failures return code for now):
      emerge_packages_from_this_list "system_list.txt" \
                                     "SYSTEM"          \
                                     $num_packages_total
   fi

   # emerge WORLD (*not* SYSTEM) packages?:
   if [ ! -n "$do_system_flag" ] \
   && [   -n "$do_world_flag" ] ; then
      # (Ignore the number-of-failures return code for now):
      emerge_packages_from_this_list "world_list.txt" \
                                     "WORLD"          \
                                     $num_packages_total
   fi

   # emerge *BOTH* SYSTEM and WORLD packages?:
   if [   -n "$do_system_flag" ] \
   && [   -n "$do_world_flag" ] ; then
      # (Ignore the number-of-failures return code for now):
      emerge_packages_from_this_list "world_and_system_list.txt" \
                                     "WORLD + SYSTEM"            \
                                     $num_packages_total
   fi

   if [ "$successful_emerges" -eq 0 ] ; then
      echo "${BL}NO SYSTEM or WORLD packages were 'emerge'd.${nc}"
      echo
   fi
}


function check_for_failed_emerges {
   # Just print out any failures; if none, then delete the file:
   if [ -s "failed_list.txt" ] ; then
      # There was a FAILED emerge!:
      echo >&2
      echo "${YL}Packages that failed to 'emerge':${RD}" >&2
      cat failed_list.txt >&2
      echo "${nc}" >&2
   else
      # No failures, so remove the file:
      rm -f failed_list.txt
   fi
}


###########################################################################
#       M A I N      M A I N      M A I N      M A I N      M A I N       #
###########################################################################


#
# Pass all the CL arguments and set flags/values:
#
get_command_line_options $@

#
# Test for ROOT using the UID *number*:
# (Unless the "--pretend" command-line option was found!)
#
if [ ! -n "$pretend_flag" ] ; then
   if [ "`id -u`" -ne 0 ]; then
      # Non-root user!
      # Fail:
      echo "${RD}ERROR: $me: ${Rd}Must be run by ROOT if no \"pretend\" flag is supplied!${nc}" >&2
      exit 9
   fi
fi

#
# Change to the temporary EMWRAP directory (so that state files
# can be created in the new current-directory):
#
change_to_tmp_emwrap_directory

#
# Create the list of all packages retuened by 'emerge -p ...':
# (Unless the "--resume" command-line option was found!)
#
if [ ! -n "$resume_emwrap_flag" ] ; then
   create_emerge_package_lists
fi

#
# Build the list of updated TC packages and display them:
#
check_for_tc_updates

#
# EMERGE any necessary TC packages:
# (If the "--toolchain" command-line option was found!)
#
if [ -n "$do_tc_flag" ] ; then
   emerge_tc_updates
fi

#
# Remove all the TC packages from all the package lists:
#
remove_tc_packages_from_lists

#
# EMERGE any necessary SYSTEM and/or WORLD packages:
# (If either the "--system" or "--world" command-line option was found!)
#
if [ -n "$do_world_flag"  ] \
|| [ -n "$do_system_flag" ] ; then
   emerge_system_or_world
fi

#
# Any failed emerges?:
#
check_for_failed_emerges

#
# Successfully finished!
#
echo "${GR}Done!${nc}"
exit 0


There should be no blank lines at the top of the file, and one blank line as the last line of the file.

Make sure that these match!:
Code:

$ md5sum emwrap
a052cd56dc4286300a29bf12c16e3a74  emwrap

$ wc emwrap
 1189  5964 49138 emwrap

_________________
BillyBear: I'm scared Poncho.
Poncho: Bullsh!t. You ain't afraid of no man!
BillyBear: There's something out there waiting for us, and it ain't no man. We're all gonna die.
<ominous music>
<enter Hillary Clinton>
;-)


Last edited by maguire on Tue Aug 23, 2005 9:53 pm; edited 5 times in total
Back to top
View user's profile Send private message
Pseud
Apprentice
Apprentice


Joined: 19 Mar 2004
Posts: 273
Location: Bangalore, India

PostPosted: Fri Aug 12, 2005 12:49 pm    Post subject: Reply with quote

Code:
$ ./emwrap
./emwrap: line 1070: syntax error: unexpected end of file

The 1066 lines, and my ultra-newbie bash-scripting abilities are keeping me from finding the very-likely-to-be-trivial bug, so please do it for me ;)
Oh, and why does it say 1070 lines although I havent added any redundant newlines?
_________________
eschew obfuscation


Last edited by Pseud on Fri Aug 12, 2005 5:24 pm; edited 1 time in total
Back to top
View user's profile Send private message
maguire
Tux's lil' helper
Tux's lil' helper


Joined: 27 May 2004
Posts: 103
Location: Longmont, Colorado

PostPosted: Fri Aug 12, 2005 4:58 pm    Post subject: Reply with quote

Well, that's pretty strange... :?

I just copy-pasted the code from my browser, and I found that the code above has four extra blank lines that are not in the original text! Line numbers 355, 899, 902 and 1057 should not be blank (if all four of those lines are blank lines in the source that you copy-pasted, then just delete them---but do it in reverse order so the line numbers don't change! i.e.: 1057, 902, 899, and 355). The only other discrepency that I see is that my original source has a blank line as the final line (I just think it makes the code easier to read), whereas the copy-pasted code I just did had no blank last line.

But, importantly, the copy-paste version that I just created still works fine (with the minor exception that the new blank line number 355 is inserted in the middle of the "./emwrap help" text).

So, my first suggestion would be to copy-paste the text again, and see if it changes. I'll edit the above text to remove the extra blank lines that were somehow created when I pasted the original text.

But do this: Make sure the code has a blank line as the last line of the file, and make sure that the source has exactly 1066 lines:
Code:

$ wc emwrap
1066  5470  45332  emwrap

and then I get the following MD5SUM:
Code:

$ md5sum emwrap
1f962cf917b7bbc1036698cdeb5b150d  emwrap


If re-copy-pasting it doesn't work, maybe I can e-mail you a copy of the source, and we can figure-out where the problem is being introduced. I'll go make the edits to the above source now.

Let me know.

Bruce.
_________________
BillyBear: I'm scared Poncho.
Poncho: Bullsh!t. You ain't afraid of no man!
BillyBear: There's something out there waiting for us, and it ain't no man. We're all gonna die.
<ominous music>
<enter Hillary Clinton>
;-)


Last edited by maguire on Fri Aug 12, 2005 5:28 pm; edited 1 time in total
Back to top
View user's profile Send private message
maguire
Tux's lil' helper
Tux's lil' helper


Joined: 27 May 2004
Posts: 103
Location: Longmont, Colorado

PostPosted: Fri Aug 12, 2005 5:08 pm    Post subject: Reply with quote

Hold on. I just found a few more issues. Don't get the above code just yet... :?

I'll post again when I'm sure that the above code pasted correctly!

Bruce.
Back to top
View user's profile Send private message
maguire
Tux's lil' helper
Tux's lil' helper


Joined: 27 May 2004
Posts: 103
Location: Longmont, Colorado

PostPosted: Fri Aug 12, 2005 5:26 pm    Post subject: Reply with quote

OK. I think I fixed all the discrepencies! I copy-pasted the above code twice, and both times it was an exact match.

I found that my original source had seven lines that had a trailing space. Since that obviously changes the character-count and the md5sum, I fixed that in my original. Now a copy-pasted version of the above source exactly matches my source code.

After you copy-paste the above code (make sure that there is one blank line after the "exit 0" line at the end), make sure that you get these exact results:

Code:

wc emwrap
1066  5470 45332 emwrap

Code:

md5sum emwrap
1f962cf917b7bbc1036698cdeb5b150d  emwrap


Let me know if there are any more issues in getting the source. I have no idea why copy-pasting the source into the Gentoo Forum would have introduced extra blank lines... It would obviously be best if I could put the code somewhere to be downloaded. My code uses only spaces for indents, so the copy-paste should---theoretically---yield exactly the same source as the original. When I downloaded the emwrap.sh source (from the link on page 1), I found that the code was riddled with tabs---but completely inconsistently! Some lines used spaces to indent, some lines used tabs! In my book, that's just inexcusable. What coder doesn't check the code by turning-on invisible characters? Oh well...

Bruce.
_________________
BillyBear: I'm scared Poncho.
Poncho: Bullsh!t. You ain't afraid of no man!
BillyBear: There's something out there waiting for us, and it ain't no man. We're all gonna die.
<ominous music>
<enter Hillary Clinton>
;-)
Back to top
View user's profile Send private message
Pseud
Apprentice
Apprentice


Joined: 19 Mar 2004
Posts: 273
Location: Bangalore, India

PostPosted: Fri Aug 12, 2005 5:31 pm    Post subject: Reply with quote

Missed your post by a few minutes I guess, but this might be useful with the debugging:
I removed the four extra (blank) lines and added one blank line at the end like you suggested and the code still had the same issue. But the interesting this is, wc gives a different byte-count:
Code:
$ wc emwrap
 1066  5470 46298 emwrap

So my guess is this: some spurious white space is also getting introduced, which is causing sytax errors (as bash is very intolerant of cavalier white-spacing).

[edit]
Drat, it happened again, haha! :P
I'll check it out now.
[/edit]
_________________
eschew obfuscation
Back to top
View user's profile Send private message
Pseud
Apprentice
Apprentice


Joined: 19 Mar 2004
Posts: 273
Location: Bangalore, India

PostPosted: Fri Aug 12, 2005 5:57 pm    Post subject: Reply with quote

Ok, I tried out the modified code, but again have the same problem. My wc byte-count is the same as my previous attempt (ok 1 more, but that's negligible)
Code:
$ wc emwrap
 1066  5470 46299 emwrap

I notice that each line (in the forum post) has a trailing blank character (just select a portion with your mouse and check now :)) ... is this how you intended it to be?
The reason I'm asking is that the difference in our byte counts is 966 ... which suggests that all of it is probably trailing blank spaces ...

[EDIT]
Well, following my hunch, I removed all trailing blank spaces, and got an exact match of both your wc and md5sum outputs, and emwrap -h worked ... so the fix is: just remove the trailing blank spaces from the forum post.
Oh and btw, thanks for your effort with the script--much appreciated!
[/EDIT]

[EDIT:2]
In case anyone wants to know how, I did the above removal of trailing blanks using Kate, my (favourite) text editor, using the Find-replace dialog that accepts regular expressions (so I asked it to replace the reg-ex " $" with ""). Of course, there should be a one-liner with sed or awk that does this, but I've procrastinated on learning them both till now, so I dont know :)
[/EDIT:2]
_________________
eschew obfuscation
Back to top
View user's profile Send private message
maguire
Tux's lil' helper
Tux's lil' helper


Joined: 27 May 2004
Posts: 103
Location: Longmont, Colorado

PostPosted: Fri Aug 12, 2005 6:19 pm    Post subject: Reply with quote

That is very strange... :? This must be a function of the browser and/or OS. I see a blank character too, at the end of a line, when I select some text, but this character is converted into a newline when I paste the text into my editor (Vim). I guess we can assume that you are using Linux (since this is a Gentoo forum! :wink: ) I'm using Firefox as my browser, and I'm selecting all the text and opening Vim, going into "insert" mode, and pasting the text using my mouse's middle button. I think I remember hearing about trailing spaces before when people copy-pasted text from the forum... Just out of curiosity, if you remove all trailing spaces, do you get the correct 'wc' and 'md5sum' results? You could use the following perl one-liner:
Code:
$ perl -pi -e 's/ +$//' emwrap


What are the results after that?

Bruce.

EDIT: Another user said that he had leading spaces on all the lines. If---and only if---you have leading spaces on all the lines, this will remove one leading space from every line that begins with one or more spaces:

Code:
$ perl -pi -e 's/^ //' emwrap

But don't do that if you don't need to, because it will screw-up the indentation on an otherwise-good file (and the md5sum and wc won't match)!
_________________
BillyBear: I'm scared Poncho.
Poncho: Bullsh!t. You ain't afraid of no man!
BillyBear: There's something out there waiting for us, and it ain't no man. We're all gonna die.
<ominous music>
<enter Hillary Clinton>
;-)


Last edited by maguire on Wed Aug 24, 2005 4:22 pm; edited 1 time in total
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Unsupported Software All times are GMT
Goto page Previous  1, 2, 3 ... 8, 9, 10 ... 28, 29, 30  Next
Page 9 of 30

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum