From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, HTML_MESSAGE,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 27298 invoked from network); 31 Jul 2021 22:10:40 -0000 Received: from minnie.tuhs.org (45.79.103.53) by inbox.vuxu.org with ESMTPUTF8; 31 Jul 2021 22:10:40 -0000 Received: by minnie.tuhs.org (Postfix, from userid 112) id CFAC29CA48; Sun, 1 Aug 2021 08:10:38 +1000 (AEST) Received: from minnie.tuhs.org (localhost [127.0.0.1]) by minnie.tuhs.org (Postfix) with ESMTP id 4374F9C9B4; Sun, 1 Aug 2021 08:10:17 +1000 (AEST) Authentication-Results: minnie.tuhs.org; dkim=pass (2048-bit key; unprotected) header.d=bsdimp-com.20150623.gappssmtp.com header.i=@bsdimp-com.20150623.gappssmtp.com header.b="BCMND672"; dkim-atps=neutral Received: by minnie.tuhs.org (Postfix, from userid 112) id 073389C9B4; Sun, 1 Aug 2021 08:10:16 +1000 (AEST) Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) by minnie.tuhs.org (Postfix) with ESMTPS id 2C18B9C9B2 for ; Sun, 1 Aug 2021 08:10:15 +1000 (AEST) Received: by mail-qt1-f174.google.com with SMTP id d2so9124342qto.6 for ; Sat, 31 Jul 2021 15:10:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdimp-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=p7ZQz2gzstEAqT9wChplrCJdE6WYklPrrCVLmZfNjvY=; b=BCMND672GAEoApP07dssfGTpre0CQambm00aSIQmuUCOAnAMUE5Bd4U8TpDssb8tkN Wjbp1+Al6g7xD/j3FKGKapprYqPHZgnlazLzFYvtn0+R0W7Ur/Vp18dlj7amIEM7ieI/ 9MNcYHoYmOd7M8eI/uuSpZphsdcTLzryCxrTA6VJJ+sy4r8PuGWRmpVpPSV+RlxV3ZaM Lw9qQVV3w9jebbeG4/VjHpOVHSVcWGG+2/qT096ihENoBJJfVfrYpGbfz3pQp5zonkrD 37H8LY+jQrkyKUXyfF8fy1+KJL6cQOOQDoRKdQ9VM0/ibJDD/yJOA16kl4xRa1KMb02c oy9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=p7ZQz2gzstEAqT9wChplrCJdE6WYklPrrCVLmZfNjvY=; b=l43NyS4BG49++85f1x6VqP/d6IrxHUnLW2yd889y1hbPQ4mMO5EkolCD29a1tH6hqE uaHT2zUZQspFfrMN4YjJ23st8jGBQi+oFwfHFI3kvlSc+GQCa2wusfHR6VNrbdU2frvL rtJH4406Cb3/+Dau+xSEX3KfAEjJx+Wrnx1+2gmlrRyhoA+H16KIU44Wy2xUypCWAytO dwsDtkxvuZBGJXJVZhYDYlX7HM0VLHf4KOSXL4Hs6Z0O0v/AqI+vcP5VCIaMgT3+G3zT nisvwe9hommxyAq3kJWTahRj/AvUqOlU3B2+jSUAAbIl7AIsN8GOWbVl0exMZgPEAcuj 4Ehw== X-Gm-Message-State: AOAM5317OjnPu0apSPrWhVyICYyG99SQsxXWg7px4Hgia4JLJU3UrsaA jffVmY99JbPMLnWZk1PBLgXBCwbj9StIDfsL5bF12AM3m9A= X-Google-Smtp-Source: ABdhPJxTmEa8m4kSRr3NuA+bhGe6f24xoHQvRmQch7J5q/GYYRbgTHsr4K16kDJ+wn4jpWZisTWRn5q00Ap3Tb9+Cz4= X-Received: by 2002:ac8:6645:: with SMTP id j5mr8031555qtp.244.1627769414158; Sat, 31 Jul 2021 15:10:14 -0700 (PDT) MIME-Version: 1.0 References: <20210731142533.69caf929@moon> <202107311920.16VJK2jT2362871@fourwinds.com> <202107312132.16VLW6VD2410038@fourwinds.com> In-Reply-To: <202107312132.16VLW6VD2410038@fourwinds.com> From: Warner Losh Date: Sat, 31 Jul 2021 16:10:04 -0600 Message-ID: To: Jon Steinhart Content-Type: multipart/alternative; boundary="000000000000b5237105c87299b8" Subject: Re: [TUHS] Systematic approach to command-line interfaces [ meta issues ] X-BeenThere: tuhs@minnie.tuhs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: The Unix Heritage Society mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: TUHS main list Errors-To: tuhs-bounces@minnie.tuhs.org Sender: "TUHS" --000000000000b5237105c87299b8 Content-Type: text/plain; charset="UTF-8" On Sat, Jul 31, 2021 at 3:33 PM Jon Steinhart wrote: > Richard Salz writes: > > On Sat, Jul 31, 2021 at 3:21 PM Jon Steinhart wrote: > > > > > opinion, it doesn't add value to do something that's already been done > > > but differently; it detracts from value because now there's yet another > > > competing way to do something. > > > > > > > You mean like not using getopt and rolling your own? Shrug. > > > > while ((i = getopt(argc, argv, "xxxxx:xxxx")) != -1) > > switch (i) { > > case .... > > } > > argc -= optind; > > argv += optind; > > > > So I never got getopt(). One of my rules is that I don't use a library > > > in cases where the number of lines of gunk that that it takes to use a > > > library function is >= the number of lines to just write it myself. > > > > > > I don't know, what lines in the above are extra beyond what you write? > The > > last two if being generous I suppose. > > Well, in my opinion that's not really an accurate representation of using > getopt. > > I would of course write the #include line, and the table of options, which > would > end up being >= the number of lines that it takes me to do this... > > while (--argc > 0) { > if (*(++argv)[0] == '-') { > for (p = *argv + 1; *p != '\0'; p++) { > switch (*p) { > Except for all the things this gets wrong, it's ok. The problem with inlining getopt is that you wind up with cases like -f foo'' on the command line being treated differently than '-ffoo'. Inlined code like this can be quite frustrating for the user to use. Your locality of reference is cut and paste bugs that getopt eliminates because it handles all the special cases in a uniform way. > Even if it took a few more lines to do it my way, I'm a believer that good > coding > style keeps "meatspace locality of reference" in mind. As programmers, we > put in > a lot of effort to ensure locality of reference for computers, but then > completely > toss it for people who aren't as good as it. So given a choice of a few > lines of > code versus having to look something up somewhere else, I choose the few > lines of > code. > And a few more bugs... Being a geezer, I have lots of code lying around from which I can extract > working > fragments such as the one above. Writing those few lines of code provides > insulation > from supply-side attack vectors bugs in libraries, versioning issues, > having to load > debug libraries, and so on. > getopt has been standardized since the 80s and has had universal adoption since the 90s. Hardly a version chasing issue since it's in everybody's libc. > I realize that this isn't a huge deal by itself; it's a philosophical > point. When > I strace any random program that I didn't write I'm astonished by the > amount of > library loading that takes place. So any issues are multiplied by n. > The flip side to this is that libraries can be debugged once, while inline code like the above needs to be deugged over and over.... > Don't get me wrong; I use plenty of libraries. But I tend to use those > for stuff > that is so common that there is a benefit from shared libraries (or at > least there > was before everything got containerized) and for libraries that do actual > hard stuff. > But I don't use libraries for small snippets of code that I could easily > write > myself yielding better code clarity for others reading my code. > Given the number of times I've been burned by trying to roll my own getopt, I stopped trying years ago. It's harder than it looks. Warner > Jon > --000000000000b5237105c87299b8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Sat, Jul 31, 2021 at 3:33 PM Jon S= teinhart <jon@fourwinds.com>= wrote:
Richard = Salz writes:
> On Sat, Jul 31, 2021 at 3:21 PM Jon Steinhart <jon@fourwinds.com> wrote:
>
> > opinion, it doesn't add value to do something that's alre= ady been done
> > but differently; it detracts from value because now there's y= et another
> > competing way to do something.
> >
>
> You mean like not using getopt and rolling your own?=C2=A0 Shrug.
>
> while ((i =3D getopt(argc, argv, "xxxxx:xxxx")) !=3D -1)
>=C2=A0 =C2=A0 switch (i) {
>=C2=A0 =C2=A0 case ....
>=C2=A0 =C2=A0}
> argc -=3D optind;
> argv +=3D optind;
>
> So I never got getopt().=C2=A0 One of my rules is that I don't use= a library
> > in cases where the number of lines of gunk that that it takes to = use a
> > library function is >=3D the number of lines to just write it = myself.
>
>
> I don't know, what lines in the above are extra beyond what you wr= ite?=C2=A0 The
> last two if being generous I suppose.

Well, in my opinion that's not really an accurate representation of usi= ng getopt.

I would of course write the #include line, and the table of options, which = would
end up being >=3D the number of lines that it takes me to do this...

=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (--argc > 0) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (*(++argv)[0] = =3D=3D '-') {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 for (p =3D *argv + 1; *p !=3D '\0'; p++) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (*p) {
<= br>
Except for all the things this gets wrong, it's ok. The p= roblem with inlining getopt
is that you wind up with cases like -= f foo'' on the command line being treated differently
tha= n '-ffoo'. Inlined code like this can be quite frustrating for the = user to use. Your
locality of reference is cut and paste bugs tha= t getopt eliminates because it handles
all the special cases in a= uniform way.
=C2=A0
Even if it took a few more lines to do it my way, I'm a believer that g= ood coding
style keeps "meatspace locality of reference" in mind.=C2=A0 As p= rogrammers, we put in
a lot of effort to ensure locality of reference for computers, but then com= pletely
toss it for people who aren't as good as it.=C2=A0 So given a choice of= a few lines of
code versus having to look something up somewhere else, I choose the few li= nes of
code.

And a few more bugs...
=
Being a geezer, I have lots of code lying around from which I can extract w= orking
fragments such as the one above.=C2=A0 Writing those few lines of code prov= ides insulation
from supply-side attack vectors bugs in libraries, versioning issues, havin= g to load
debug libraries, and so on.

getopt has = been standardized since the 80s and has had universal adoption since
<= div>the 90s. Hardly a version chasing issue since it's in everybody'= ;s libc.
=C2=A0
I realize that this isn't a huge deal by itself; it's a philosophic= al point.=C2=A0 When
I strace any random program that I didn't write I'm astonished by t= he amount of
library loading that takes place.=C2=A0 So any issues are multiplied by n.<= br>

The flip side to this is that libraries= can be debugged once, while inline code
like the above needs to = be deugged over and over....
=C2=A0
Don't get me wrong; I use plenty of libraries.=C2=A0 But I tend to use = those for stuff
that is so common that there is a benefit from shared libraries (or at leas= t there
was before everything got containerized) and for libraries that do actual h= ard stuff.
But I don't use libraries for small snippets of code that I could easil= y write
myself yielding better code clarity for others reading my code.

Given the number of times I've been burned by = trying to roll my own getopt,
I stopped trying years ago. It'= s harder than it looks.

Warner
=C2= =A0
Jon
--000000000000b5237105c87299b8--