Re: [DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
On Mon, Jan 25, 2016 at 05:44:11PM -0500, Peter Olson wrote: [cut] > > This also brings up the question of whether you should roll your own get_name > or > use basename(3) which already does the same thing except in some edge cases. > It's easier for the student to understand the code if it is implemented as > get_name, but the student ought to learn about dirname and basename pretty > early > in their study. Apart from students' interest, the Unix phylosophy is all about designing simple, orthogonal, robust components and functions that can be reused and combined together to accomplish tasks unforseen to their initial developer. Unix is not about reinventing the wheel every single day. HND KatolaZ -- [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ] [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ] [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ] [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ] ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
On Mon, Jan 25, 2016 at 12:23:01PM +, Rainer Weikusat wrote: > KatolaZwrites: > > [...] > > > I still don't see the need for an internal buffer to print out a > > formatted string, to be honest :) > > Everything in code can always be implemented in a number of different > ways, hence, whatever the code ends up doing is "not really needed" --- > it could have achieved the same in a different way. > > In this case, the function is part of a 79 lines program whose main > looks like this: > > int main(int argc, char **argv) > { > char const *name; > int status; > > name = get_name(*argv); > openlog(name, LOG_PID | LOG_PERROR, LOG_DAEMON); > if (argc < 3) usage(); > > print_start(name, argv[1]); > > switch (fork()) { > case -1: > die(__func__, "fork"); > > case 0: > execvp(argv[2], argv + 2); > > syslog(LOG_ERR, "main: execvp: %m(%d)", errno); > _exit(1); > } > > wait(); > print_stop(status); > > return 0; > } > > and whose purpose is to enable me to write > > starting "unleashed VPN" \ > daemon -n chdir / monitor -n qvpn ssh-vpn mes-pgsql 5000 unleashed > unleashed4 > > in an init script to get a 'start: ok (or failed)' message printed to > file descriptor 2 with having to put two printf invocation around the > start command. And in the context of that, using stdio for the sole > purpose of performing a trivial string formatting operation seemed very > inappropriate --- that's new-fangled, ill-thought out stuff supposed to > make UNIX(*) easier to use by moron^WUCB students and who really needs > that? I did not dispute your preference for not using stdio, but the choice to copy strings into internal buffers just to change one character and spit them on stdout. And in fact my 6-lines proposal for doing exactly the same was: void another_print_start(char *name, char *what){ char c[3] = " :"; c[2] = name[0] & ~0x20; write(2, c+2, 1); write(2, name+1, strlen(name) -1); write(2, c, 2); write(2, what, strlen(what)); } You asked for comments, I commented that alloca was probably not needed and potentially dangerous, and that you could achieve the same with simpler code, but apparently you didn't like the comment :D > > The program also contains a very nice example of why the post-increment > operators is useful (and I means 'useful', not 'common because of > mindless copying of example code'): > > static char const *get_name(char const *arg0) > { > char const *n, *r; > > n = r = arg0; > while (*r) if (*r++ == '/') n = r; > return n; > } That's pretty straight-forward C-programming, IMHO, but I agree that it could be seen as interesting by a mor^H^H^Hstudent who approaches C for the first time. Peace, love and hacking. KatolaZ -- [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ] [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ] [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ] [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ] ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
> On January 25, 2016 at 7:40 AM KatolaZwrote: > > > On Mon, Jan 25, 2016 at 12:23:01PM +, Rainer Weikusat wrote: > > KatolaZ writes: > > > > [...] [...] > > The program also contains a very nice example of why the post-increment > > operators is useful (and I means 'useful', not 'common because of > > mindless copying of example code'): > > > > static char const *get_name(char const *arg0) > > { > > char const *n, *r; > > > > n = r = arg0; > > while (*r) if (*r++ == '/') n = r; > > return n; > > } > > That's pretty straight-forward C-programming, IMHO, but I agree that > it could be seen as interesting by a mor^H^H^Hstudent who approaches C > for the first time. > > Peace, love and hacking. > > KatolaZ This also brings up the question of whether you should roll your own get_name or use basename(3) which already does the same thing except in some edge cases. It's easier for the student to understand the code if it is implemented as get_name, but the student ought to learn about dirname and basename pretty early in their study. Peter Olson ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
[DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
KatolaZwrites: [...] > I still don't see the need for an internal buffer to print out a > formatted string, to be honest :) Everything in code can always be implemented in a number of different ways, hence, whatever the code ends up doing is "not really needed" --- it could have achieved the same in a different way. In this case, the function is part of a 79 lines program whose main looks like this: int main(int argc, char **argv) { char const *name; int status; name = get_name(*argv); openlog(name, LOG_PID | LOG_PERROR, LOG_DAEMON); if (argc < 3) usage(); print_start(name, argv[1]); switch (fork()) { case -1: die(__func__, "fork"); case 0: execvp(argv[2], argv + 2); syslog(LOG_ERR, "main: execvp: %m(%d)", errno); _exit(1); } wait(); print_stop(status); return 0; } and whose purpose is to enable me to write starting "unleashed VPN" \ daemon -n chdir / monitor -n qvpn ssh-vpn mes-pgsql 5000 unleashed unleashed4 in an init script to get a 'start: ok (or failed)' message printed to file descriptor 2 with having to put two printf invocation around the start command. And in the context of that, using stdio for the sole purpose of performing a trivial string formatting operation seemed very inappropriate --- that's new-fangled, ill-thought out stuff supposed to make UNIX(*) easier to use by moron^WUCB students and who really needs that? The program also contains a very nice example of why the post-increment operators is useful (and I means 'useful', not 'common because of mindless copying of example code'): static char const *get_name(char const *arg0) { char const *n, *r; n = r = arg0; while (*r) if (*r++ == '/') n = r; return n; } ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng