Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #156943 > unrolled thread
| Started by | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| First post | 2020-12-05 08:25 -0800 |
| Last post | 2021-01-06 23:07 -0800 |
| Articles | 20 on this page of 399 — 24 participants |
Back to article view | Back to comp.lang.c
Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-05 08:25 -0800
Re: Programming exercise/challenge Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> - 2020-12-05 17:33 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 11:58 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-30 09:40 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-30 18:20 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-31 01:04 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-02 22:05 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-02 14:48 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-02 19:17 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-02 19:04 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-30 21:44 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-31 02:54 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-03 09:49 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-04 00:15 +0300
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-03 21:57 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-03 23:00 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 00:00 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-04 20:04 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-05 07:15 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-07 22:30 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 18:42 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 21:23 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 23:41 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 16:39 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 16:58 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 17:08 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 17:11 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 17:24 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 17:52 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 18:30 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 19:56 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-06 14:51 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-05 17:49 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 18:34 +0000
Re: Programming exercise/challenge Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-05 19:40 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 18:47 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 23:19 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 23:56 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-08 02:26 +0000
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 16:04 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:39 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-12 23:34 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:28 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-29 10:34 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 20:05 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 06:03 -0800
Re: Programming exercise/challenge dfs <nospam@dfs.com> - 2020-12-05 13:58 -0500
Re: Programming exercise/challenge Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-12-05 21:37 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 06:13 -0800
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-06 18:00 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 12:31 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 06:26 -0800
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-05 23:32 +0100
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-06 17:18 +0100
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-06 17:51 +0100
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-06 22:27 +0000
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-07 09:37 +0100
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 07:36 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:49 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-06 17:51 +0000
Re: Programming exercise/challenge dfs <nospam@dfs.com> - 2020-12-06 13:03 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-06 23:53 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-06 19:53 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-06 23:38 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 00:17 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 02:09 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-07 01:03 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 12:05 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 12:25 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 13:33 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 14:18 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 14:31 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 12:58 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:03 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 07:12 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 21:55 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:59 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:55 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 07:45 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:26 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-24 12:24 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-24 17:19 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-27 05:16 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-27 04:17 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-27 08:27 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 19:18 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 05:15 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 13:42 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:53 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 01:49 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 22:35 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 21:17 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 21:44 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:46 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-13 12:21 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:35 -0800
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2020-12-31 00:46 +0100
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2020-12-31 00:52 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-31 00:34 -0800
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2021-01-01 08:23 +0100
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2021-01-01 10:09 +0100
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2021-01-01 11:38 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-01 08:24 -0800
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-07 07:03 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 02:16 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 02:39 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:18 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:17 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 00:27 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:20 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-07 13:44 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-07 14:01 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 22:16 +0000
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-07 15:10 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 01:07 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 00:34 +0000
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-08 18:17 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-09 00:56 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 02:30 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-09 15:14 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-09 15:44 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-12 23:56 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-12 13:29 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:46 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-12 13:59 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 14:17 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-13 12:58 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-13 20:57 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-14 20:44 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-23 11:15 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-23 23:45 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-23 21:36 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-24 09:11 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 15:30 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-24 23:18 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-24 23:56 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-28 12:01 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 19:31 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 14:47 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 01:59 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:26 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 19:02 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 01:15 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 20:38 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 02:19 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 11:44 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-08 07:32 -0500
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 14:40 +0000
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-08 06:52 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 17:31 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-08 20:16 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 20:48 +0000
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-08 15:34 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 02:54 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 12:33 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 12:43 +0300
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-09 01:52 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:28 +0300
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 21:40 +0000
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-12 13:48 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-09 01:46 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:29 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-08 10:45 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 17:16 +0000
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-08 06:39 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-07 17:48 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 21:03 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:02 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 08:02 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 16:49 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 13:33 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 19:57 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-10 01:45 +0000
Re: Programming exercise/challenge Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2020-12-10 02:15 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:24 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 21:57 -0500
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-10 03:32 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-10 08:19 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:04 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-24 19:34 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 02:22 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:04 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 11:59 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 08:11 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 00:02 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 15:12 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 10:36 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 22:11 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-10 23:34 +0000
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-10 20:11 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 21:06 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 03:03 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-08 21:21 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 12:50 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 08:16 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:32 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-09 12:21 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-02 19:15 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-07 01:54 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-22 22:36 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-22 23:07 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-22 20:27 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-23 13:05 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 07:45 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-23 16:49 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 11:22 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-23 16:53 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 09:55 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 21:35 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-24 18:17 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 07:57 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 11:28 -0800
Re: Programming exercise/challenge "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-08 11:30 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-08 20:31 +0000
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-08 22:17 +0100
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-08 22:15 +0100
Re: Programming exercise/challenge "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-08 13:28 -0800
Re: Programming exercise/challenge "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-09 12:05 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:04 +0300
Re: Programming exercise/challenge Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2020-12-08 21:38 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:25 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 01:00 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 03:09 +0000
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:35 +0300
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 22:57 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 23:43 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:47 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 23:27 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-13 14:44 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:47 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:36 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 14:51 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 11:35 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-10 02:33 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 00:05 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-10 14:59 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 20:32 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-12 23:45 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:24 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:17 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:23 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-09 19:31 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 12:01 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 12:25 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-23 01:00 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 14:34 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-26 23:03 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-27 06:29 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-28 11:52 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 00:38 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-28 15:29 +0300
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-28 17:12 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-28 23:54 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-29 10:26 -0600
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-29 10:37 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 19:59 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-30 09:17 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-31 16:54 +0300
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-31 09:16 -0600
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-31 15:56 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-07 02:41 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-31 13:01 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-31 14:15 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-01 08:03 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-01 07:42 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-02 21:59 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-02 14:52 -0500
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-02 12:30 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-02 18:17 -0500
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-02 19:22 -0500
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-02 17:48 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-02 22:35 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-02 18:02 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-03 00:42 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-04 20:12 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-04 07:04 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-04 20:22 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 04:24 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 06:22 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 08:55 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-05 20:22 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-05 20:27 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 14:20 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-05 17:23 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 10:18 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-05 18:57 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 12:58 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-05 17:31 -0500
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-05 17:50 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 19:33 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-05 23:02 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 21:00 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-06 07:42 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-06 08:55 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-06 13:29 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-06 14:09 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 22:11 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-07 03:10 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-07 06:40 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-09 06:27 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-10 04:32 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-11 06:58 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-11 14:40 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-15 09:46 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-17 04:13 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-17 14:18 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-17 18:02 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-17 15:12 -0500
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-17 21:39 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-20 10:57 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-21 11:37 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-22 00:30 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-22 09:09 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-22 13:47 -0500
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-22 19:00 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-22 19:42 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-22 21:16 +0000
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-22 16:41 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 17:46 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 09:51 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-23 18:38 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 04:52 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-23 15:45 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 09:04 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-23 23:10 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 15:39 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-23 15:59 +0000
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-25 11:40 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 09:47 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-23 18:32 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 17:26 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-24 01:55 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 08:40 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 20:51 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-24 02:28 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-24 03:49 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-24 15:38 +0300
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-24 14:04 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-25 07:26 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-25 16:58 +0100
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2021-01-25 09:14 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 07:32 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-27 16:24 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-28 00:11 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-28 12:25 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 06:18 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-28 16:54 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 09:15 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-28 20:07 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 15:58 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-29 00:07 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 16:17 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-29 00:03 +0300
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-28 03:37 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-28 22:50 +0000
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-30 23:14 +0300
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-30 20:49 +0000
Re: Programming exercise/challenge M Joshua Ryan <luser.droog@gmail.com> - 2021-01-28 00:05 -0600
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-27 11:51 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-25 17:22 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-25 12:21 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-25 14:27 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-25 19:41 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-26 04:46 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-26 06:30 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-26 15:46 +0100
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-27 03:43 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-27 13:43 +0100
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-27 17:51 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-27 11:02 -0500
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-27 17:03 +0100
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-27 07:21 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-27 17:09 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-27 17:04 +0000
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-28 10:41 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 18:25 +0000
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-28 10:44 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 21:33 +0000
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-29 10:39 +0100
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-25 23:52 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-26 11:37 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 08:04 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-27 19:16 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 23:38 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 13:43 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-28 03:16 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 06:42 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-28 13:01 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 13:35 -0500
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-06 19:27 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-06 21:25 +0000
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 00:37 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-06 04:34 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 11:54 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 15:28 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-05 13:27 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 15:43 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 20:10 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-06 23:07 -0800
Page 6 of 20 — ← Prev page 1 … 4 5 [6] 7 8 … 20 Next page →
| From | Rosario19 <Ros@invalid.invalid> |
|---|---|
| Date | 2021-01-01 10:09 +0100 |
| Message-ID | <8iptuftts74li5jpblinf41aqsf4ks3f6l@4ax.com> |
| In reply to | #158046 |
On Fri, 01 Jan 2021 08:23:41 +0100, Rosario19 <Ros@invalid.invalid>
wrote:
>On Thu, 31 Dec 2020 00:34:09 -0800, Tim Rentsch wrote:
>>Rosario19 <Ros@invalid.invalid> writes:
>>
>>[...]
>>> this is my try
>>>
>>> #include <stdio.h>
>>> main()
>>> {int c, cp;
>>> for(;(c=getchar())!=EOF;)
>>> {if(c=='/')
>>> {cp=c;
>>> if((c=getchar())=='*')
>>> {for(cp='a';(c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
>>> else if(c=='/')
>>> {for(;cp!='\n'&&(cp=getchar())!=EOF;);if(cp!=EOF)putchar(cp);}
>>> else if(c=='\''||c=='\"')
>>> for(putchar('/'),putchar(c),cp='a';cp!=c&&(cp=getchar())!=EOF;putchar(cp));
>>> else if(c!=EOF) {putchar(cp); putchar(c);cp=c;}
>>> else {putchar(cp); break;}
>>> }
>>> else if(c=='\''||c=='\"')
>>> for(putchar(c),cp='a';cp!=c&&(cp=getchar())!=EOF;putchar(cp));
>>> else {putchar(c);cp=c;}
>>> if(cp==EOF)break;
>>> }
>>> return 0;
>>> }
>>
>>Try running your program on this input
>>
>> enum {
>> QUOTE = '\'',
>> };
>>
>> /* Here is a comment */
>>
>>which is a valid C translation unit. Does it produce what
>>you think it should?
>
>this use ungetc on stdin and would remove all \\n from the input (if
>in the code and not in the string) it should be bugged too
>
>#include <stdio.h>
>main() // use ungetc on stdin, remove \\n
>{int c,cp,cpp;
> for(cp='a';cp!=EOF&&(c=getchar())!=EOF;)
> {if(c=='*'&&cp=='/') {for(;(
>c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
> else if(c=='/')
> {if(cp=='/') {for(;cp!='\n'&&(cp=getchar())!=EOF; );
>if(cp!=EOF)putchar(cp);}
> else {cp=c;
> if((c=getchar())=='*') {for(; (
>c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
> else if(c=='/')
>{for(;cp!='\n'&&(cp=getchar())!=EOF; ); if(cp!=EOF)putchar(cp);}
> else if(c==EOF) {putchar(cp);
>break;}
> else if(c=='\\'||c=='\''||c=='\"') ungetc(c,stdin);
> else {putchar(cp);
>putchar(c);}
> }
> }
> else if(c=='\\'){cpp=cp;cp=c;
> if((c=getchar())==EOF){putchar(cp);break;}
> else if (c=='\n') cp=cpp;
> else
>{putchar(cp);putchar(c);}
> } // there would be some bug cp=cpp is ok
> else
>if(c=='\''||c=='\"'){for(putchar(c),cpp=cp,cp='a';(cpp!='\\'&&cp!=c)&&(cp=getchar())!=EOF;putchar(cp))cpp=cp;if(cp!=EOF)cp=cpp;
> }
> else {putchar(c);cp=c;}
> }
> return 0;
>}
this is the one easy, possible bugged too
#include <stdio.h>
main()
{int c,cp,cpp;
for(cp='a';cp!=EOF&&(c=getchar())!=EOF;)
{if(c=='/')
{cp=c;
if((c=getchar())=='*') {for(; (
c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
else if(c=='/')
{for(;cp!='\n'&&(cp=getchar())!=EOF; ); if(cp!=EOF)putchar(cp);}
else if(c==EOF) {putchar(cp); break;}
else {putchar(cp); putchar(c);}
}
else if(c=='\''||c=='\"')
/*it is not clear why "if(cp!=EOF)cp=cpp;"*/
{for(putchar(c),cpp=cp,cp='a';(cpp!='\\'&&cp!=c)&&(cp=getchar())!=EOF;putchar(cp))cpp=cp;if(cp!=EOF)cp=cpp;}
else {putchar(c);cp=c;}
}
return 0;
}
[toc] | [prev] | [next] | [standalone]
| From | Rosario19 <Ros@invalid.invalid> |
|---|---|
| Date | 2021-01-01 11:38 +0100 |
| Message-ID | <onutuf5hfadbuh741849ttsgvd6b0t72mo@4ax.com> |
| In reply to | #158050 |
On Fri, 01 Jan 2021 10:09:16 +0100, Rosario19 <Ros@invalid.invalid>
wrote:
...
find one bug...
the easy version does not handle case as
/\
\
\* comment *\
#include <stdio.h>
main()
{int c,cp,cpp;
for(cp='a';cp!=EOF&&(c=getchar())!=EOF;)
{if(c=='/')
{cp=c;
if((c=getchar())=='*') {for(; (
c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
else if(c=='/')
{for(;cp!='\n'&&(cp=getchar())!=EOF; ); if(cp!=EOF)putchar(cp);}
else if(c==EOF) {putchar(cp); break;}
else {putchar(cp); putchar(c);}
}
else if(c=='\''||c=='\"')
{for(putchar(c),cpp='a';(cp=getchar())!=EOF;cpp=cp,putchar(cp))if(cp==c&&cpp!='\\'){putchar(cp);break;}}
else {putchar(c);cp=c;}
}
return 0;
}
the version handle case as
/\
\
\* comment *\
but change the code, make union of lines if find \\ \n
#include <stdio.h>
main() // use ungetc on stdin, remove \\n
{int c,cp,cpp;
for(cp='a';cp!=EOF&&(c=getchar())!=EOF;)
{if(c=='*'&&cp=='/') {for(;(
c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
else if(c=='/')
{if(cp=='/') {for(;cp!='\n'&&(cp=getchar())!=EOF; );
if(cp!=EOF)putchar(cp);}
else {cp=c;
if((c=getchar())=='*') {for(; (
c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
else if(c=='/')
{for(;cp!='\n'&&(cp=getchar())!=EOF; ); if(cp!=EOF)putchar(cp);}
else if(c==EOF) {putchar(cp);
break;}
else if(c=='\\'||c=='\''||c=='\"') ungetc(c,stdin);
else {putchar(cp);
putchar(c);}
}
}
else if(c=='\\'){cpp=cp;cp=c;
if((c=getchar())==EOF){putchar(cp);break;}
else if (c=='\n') cp=cpp; //
unisce tutte le linee
else
{putchar(cp);putchar(c);}
}
else
if(c=='\''||c=='\"'){for(putchar(c),cpp='a';(cp=getchar())!=EOF;cpp=cp,putchar(cp))if(cp==c&&cpp!='\\'){putchar(cp);break;}}
else {putchar(c);cp=c;}
}
return 0;
}
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-01 08:24 -0800 |
| Message-ID | <86ble8tykg.fsf@linuxsc.com> |
| In reply to | #158070 |
Rosario19 <Ros@invalid.invalid> writes:
> On Fri, 01 Jan 2021 10:09:16 +0100, Rosario19 <Ros@invalid.invalid>
> wrote:
> ...
>
> find one bug...
>
> the easy version does not handle case as
> /\
> \
> \* comment *\
>
>
> #include <stdio.h>
> main()
> {int c,cp,cpp;
> for(cp='a';cp!=EOF&&(c=getchar())!=EOF;)
> {if(c=='/')
> {cp=c;
> if((c=getchar())=='*') {for(; (
> c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
> else if(c=='/')
> {for(;cp!='\n'&&(cp=getchar())!=EOF; ); if(cp!=EOF)putchar(cp);}
> else if(c==EOF) {putchar(cp); break;}
> else {putchar(cp); putchar(c);}
> }
> else if(c=='\''||c=='\"')
>
> {for(putchar(c),cpp='a';(cp=getchar())!=EOF;cpp=cp,putchar(cp))if(cp==c&&cpp!='\\'){putchar(cp);break;}}
> else {putchar(c);cp=c;}
> }
> return 0;
> }
>
>
> the version handle case as
> /\
> \
> \* comment *\
>
> but change the code, make union of lines if find \\ \n
>
> #include <stdio.h>
> main() // use ungetc on stdin, remove \\n
> {int c,cp,cpp;
> for(cp='a';cp!=EOF&&(c=getchar())!=EOF;)
> {if(c=='*'&&cp=='/') {for(;(
> c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
> else if(c=='/')
> {if(cp=='/') {for(;cp!='\n'&&(cp=getchar())!=EOF; );
> if(cp!=EOF)putchar(cp);}
> else {cp=c;
> if((c=getchar())=='*') {for(; (
> c=getchar())!=EOF;cp=c)if(cp=='*'&&c=='/')break;}
> else if(c=='/')
> {for(;cp!='\n'&&(cp=getchar())!=EOF; ); if(cp!=EOF)putchar(cp);}
> else if(c==EOF) {putchar(cp);
> break;}
> else if(c=='\\'||c=='\''||c=='\"') ungetc(c,stdin);
> else {putchar(cp);
> putchar(c);}
> }
> }
> else if(c=='\\'){cpp=cp;cp=c;
> if((c=getchar())==EOF){putchar(cp);break;}
> else if (c=='\n') cp=cpp; //
> unisce tutte le linee
> else
> {putchar(cp);putchar(c);}
> }
> else
> if(c=='\''||c=='\"'){for(putchar(c),cpp='a';(cp=getchar())!=EOF;cpp=cp,putchar(cp))if(cp==c&&cpp!='\\'){putchar(cp);break;}}
> else {putchar(c);cp=c;}
> }
> return 0;
> }
For future postings, I ask that you give main() a return type of int
(so 'int main(){ ... }'), and format the program using 'indent -kr'.
I have collected the programs you have posted so far, but may very
well ignore future submissions that look as awful as this.
[toc] | [prev] | [next] | [standalone]
| From | "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-12-07 07:03 -0800 |
| Message-ID | <0a4bfb4f-b0b6-4698-a7f5-4ff126a3affen@googlegroups.com> |
| In reply to | #157014 |
On Monday, December 7, 2020 at 4:04:17 AM UTC-5, Tim Rentsch wrote: > Ben Bacarisse <ben.u...@bsb.me.uk> writes: > > > Tim Rentsch <tr.1...@z991.linuxsc.com> writes: > > > >> Prompted by some recent discussion regarding 'goto' statements and > >> state machines, I would like to propose a programming exercise. > >> (It is perhaps a bit too large to be called an exercise, but not so > >> difficult that it deserves the label of challenge. On the other > >> hand there are some constraints so maybe challenge is apropos. In > >> any case somewhere in between those two bounds.) > >> > >> Short problem statement: a C program to remove comments from C > >> source input. ... > It's a nice program, but it doesn't quite do what was asked for. > The problem statement says to remove comments. This program does > remove comments, but it also takes out line splices to replace > multiple physical lines with their corresponding logical line. > Line continuation sequences outside of comments should be > preserved in the output. The standard never uses the term "line continuation". The standard does refer to "a backslash character (\) immediately followed by a new-line character", but doesn't name that construct. They are often referred to outside the standard as "escaped newlines". It does talk about "splicing" and "logical lines" in connection with escaped newlines, so I would presume that this is what you're referring to? C comments exist only in the context described by the standard. If it isn't in that context, it isn't properly a C comment, it's a C-like comment. That context includes the translation phases. Translation phase 2 is removal of line continuations. Translation phase 3 includes removal of comments. The translation phases are not required to actually occur in the order specified, but it is required that the end result be the same as if they did occur in that order. Therefore, it doesn't make much sense to me to describe a program as removing C comments, if it's also supposed to preserve some, but not all escaped newlines. I could understand a program that implements translation phase 2 and part of translation phase 3, removing first the escaped newlines, and then removing the comments. It also makes sense to me to define a program that implements only part of translation phase 3, with the built-in assumption that the input has already had all escaped newlines removed (with the corresponding possibility of malfunction if that assumption is incorrect). I don't see a good motivation for a program that does what you describe. > > Haskell has two big advantages for this exercise: pattern matched > > cases and lazy evaluation. [..explanation..] > > Also one not mentioned: 'input <- getContents'. An analogous > functionality in C would read the contents of a file into a > character array, which would make the C program easier. > > Originally, I just wrote stripComments, but when I decided to > > include logical line processing (C's \<newline> "continuation" > > mechanism) it was trivial to put it in. [...] > > Line continuation sequences have to be processed if the original > problem statement is to be met. Line continuations were not mentioned in the original problem description. Handling of line continuations can be considered to have been implied only if you want them to be handled as described by the standard. What you want is different from what the standard specifies; as such, you should have said so explicitly.
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2020-12-08 02:16 +0300 |
| Message-ID | <20201208021620.0845d0f16263a3462964bfd0@gmail.com> |
| In reply to | #157037 |
Tim Rentsch: > It's a nice program, but it doesn't quite do what was > asked for. The problem statement says to remove comments. > This program does remove comments, but it also takes out > line splices to replace multiple physical lines with their > corresponding logical line. Line continuation sequences > outside of comments should be preserved in the output. I had not realised that, and agree with James Kuyper: > C comments exist only in the context described by the > standard. If it isn't in that context, it isn't properly a > C comment, it's a C-like comment. That context includes > the translation phases. Translation phase 2 is removal of > line continuations. Translation phase 3 includes removal > of comments. The translation phases are not required to > actually occur in the order specified, but it is required > that the end result be the same as if they did occur in > that order. Therefore, it doesn't make much sense to me to > describe a program as removing C comments, if it's also > supposed to preserve some, but not all escaped newlines. Such details as line continuations are more low-level than comments. They belong to the physical, "transport" level of the file, where the the distinction between code and comments is not yet available. Removing comments while keeping line continuations is turning the natural order of processing upside down. If you are not convinced, I will consider amending my program tomorrow evening. -- () ascii ribbon campaign -- against html e-mail /\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2020-12-09 02:39 +0300 |
| Message-ID | <20201209023938.b51a2cd8ee446baba347fd14@gmail.com> |
| In reply to | #157061 |
I wrote to Tim:
> If you are not convinced, I will consider amending my
> program tomorrow evening.
Since he has kept the rules, I have modified my program.
It is still inefficient, but hopefully more correct:
/* ------------------------------ No comments -----------------------------V2-*/
/* A program to strip comments from a C file, by Anton Shepelev */
#include<stdio.h>
#include<string.h>
/* Machine states: */
/* TODO: devise a consistent, annotated, but still very brief naming: */
typedef enum t_state
{ S_CD, S_BC, S_CR, S_SR, S_LC,
S_CM1, S_BC0, S_CE, S_SE, } t_state;
/* A state transition: */
/* TODO: buf is used in one entry only => hardcode: */
typedef struct
{ t_state state; /* state */
int c; /* input */
t_state next; /* next state */
char buf; /* buffer input? */
char print; /* print input? */
} t_trans;
/* Transition table: */
/* EOF input denotes the fall-back: */
t_trans xtab[] = {
/* state char next buffer print */
{ S_CD, '/' , S_CM1, 1, 0 },
{ S_CD, '"' , S_SR, 0, 1 },
{ S_CD, '\'', S_CR, 0, 1 },
{ S_CD, EOF , S_CD, 0, 1 },
{ S_CM1, '/' , S_LC, 0, 0 },
{ S_CM1, '*' , S_BC, 0, 0 },
{ S_CM1, EOF , S_CD, 0, 1 },
{ S_LC, '\n', S_CD, 0, 1 },
{ S_LC, EOF , S_LC, 0, 0 },
{ S_BC, '*' , S_BC0, 0, 0 },
{ S_BC, EOF , S_BC, 0, 0 },
{ S_BC0, '/' , S_CD, 0, -1 },
{ S_BC0, '*' , S_BC0, 0, 0 }, /* <== thanks to Bart's test case */
{ S_BC0, EOF , S_BC, 0, 0 },
{ S_SR, '\\', S_SE, 0, 1 },
{ S_SR, '"' , S_CD, 0, 1 },
{ S_SR, EOF , S_SR, 0, 1 },
{ S_SE, EOF, S_SR, 0, 1 },
{ S_CR, '\\', S_CE, 0, 0 },
{ S_CR, '\'', S_CD, 0, 1 },
{ S_CR, EOF, S_CR, 0, 1 },
{ S_CE, EOF, S_CR, 0, 0 }
};
static void flushbuf( char * buf, char print )
{ if( print ) printf( "%s", buf );
buf[0] = '\0';
}
/* Perform a step on the state machine: */
/* OPT: nested array, indexed by 1) .state and 2) .char to avoid the loop: */
/* i.e.: trans = state_tab[state][c] */
void step( t_state *state, int c, char *buf )
{ t_trans *trans;
int i;
i = 0;
while( 1 ) /* transition look up */
{ trans = &xtab[i];
i = i + 1;
if( trans->state != *state ) continue;
if( trans->c != c )
if( trans->c != EOF ) continue;
break;
}
flushbuf( buf, trans->print == 1 );
if( trans->print != 0 )
{ if( trans->print == -1 ) putchar( ' ' );
else putchar( c ); }
if( trans->buf ) buf[1] = c;
*state = trans->next;
}
void main( void )
{ int c, p, stop;
char buf[80]; /* either keep it large enough or use dynamic memory */
char cont;
t_state state;
stop = 0;
cont = 0;
state = S_CD;
buf[0]='\0';
c = EOF;
while( 1 )
{ p = c; c = getc( stdin );
if( p == '\\' && c == '\n' )
{ cont = 1; continue; }
if( cont )
{ cont = 0;
strcat(buf, "\\\n");
continue;
}
if( p != EOF )
{ step( &state, p, buf ); }
if( c == EOF )
{ break; }
}
}
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-08 23:18 -0800 |
| Message-ID | <864kkv78h7.fsf@linuxsc.com> |
| In reply to | #157106 |
Anton Shepelev <anton.txt@gmail.com> writes: > I wrote to Tim: > >> If you are not convinced, I will consider amending my >> program tomorrow evening. > > Since he has kept the rules, I have modified my program. > It is still inefficient, but hopefully more correct: > [...] I got this and have added it to the collection of posted responses.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-08 23:17 -0800 |
| Message-ID | <868sa778jv.fsf@linuxsc.com> |
| In reply to | #157061 |
Anton Shepelev <anton.txt@gmail.com> writes: Sorry for the delay in responding. For some unknown reason my news service wasn't allowing messages to be posted for a day or two. > Tim Rentsch: > >> It's a nice program, but it doesn't quite do what was >> asked for. The problem statement says to remove comments. >> This program does remove comments, but it also takes out >> line splices to replace multiple physical lines with their >> corresponding logical line. Line continuation sequences >> outside of comments should be preserved in the output. > > I had not realised that, and agree with James Kuyper: > >> C comments exist only in the context described by the >> standard. If it isn't in that context, it isn't properly a >> C comment, it's a C-like comment. That context includes >> the translation phases. Translation phase 2 is removal of >> line continuations. Translation phase 3 includes removal >> of comments. The translation phases are not required to >> actually occur in the order specified, but it is required >> that the end result be the same as if they did occur in >> that order. Therefore, it doesn't make much sense to me to >> describe a program as removing C comments, if it's also >> supposed to preserve some, but not all escaped newlines. > > Such details as line continuations are more low-level than > comments. They belong to the physical, "transport" level of > the file, where the the distinction between code and > comments is not yet available. Removing comments while > keeping line continuations is turning the natural order of > processing upside down. If you are not convinced, I will > consider amending my program tomorrow evening. The program being asked for is not a language processing tool. Rather it is a source-to-source translation tool where both the input /and the output/ are expected to be read by people. If looked at from that perspective I think the most sensible choice is to leave in the backslant-newline sequences. Multi-line macros, for example, are easier to read if left as multiple lines rather than as single very long lines. In any case my intention for the exercise was (and is) for comments to be removed but everything outside of comments to be left as is. And, besides being what was intended, dealing with the backslant-newline sequences is what makes the problem interesting; simply stripping out the backslant-newline pairs makes the problem almost trivial.
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2020-12-08 00:27 +0300 |
| Message-ID | <20201208002703.08b47b3fce567f7096b14e59@gmail.com> |
| In reply to | #156943 |
Tim Rentsch:
> If EOF is seen inside a comment, do something sensible but
> it doesn't matter what as long as it's sensible.
Is just stopping the program not sensible, e.g.:
void main( void ) {}
/* commenging...
may output
void main( void ) {}
and call it run?
--
() ascii ribbon campaign -- against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-08 23:20 -0800 |
| Message-ID | <86zh2n5ttm.fsf@linuxsc.com> |
| In reply to | #157046 |
Anton Shepelev <anton.txt@gmail.com> writes:
> Tim Rentsch:
>
>> If EOF is seen inside a comment, do something sensible but
>> it doesn't matter what as long as it's sensible.
>
> Is just stopping the program not sensible, e.g.:
>
> void main( void ) {}
> /* commenging...
>
> may output
>
> void main( void ) {}
>
> and call it run?
Yes that's fine. You might want to issue an error message,
and/or give an error return status, but either way is
perfectly okay.
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2020-12-07 13:44 -0800 |
| Message-ID | <c53ae20d-f1ce-40d1-ab8b-ccc14f642ec1n@googlegroups.com> |
| In reply to | #156943 |
On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote:
> Prompted by some recent discussion regarding 'goto' statements and
> state machines, I would like to propose a programming exercise.
> (It is perhaps a bit too large to be called an exercise, but not so
> difficult that it deserves the label of challenge. On the other
> hand there are some constraints so maybe challenge is apropos. In
> any case somewhere in between those two bounds.)
>
> Short problem statement: a C program to remove comments from C
> source input.
>
> Specifics: Remove both /*...*/ and //... style comments. Don't
> worry about trigraphs. Read from stdin, write to stdout, and
> diagnostics (if any) go to stderr. If EOF is seen inside a
> comment, do something sensible but it doesn't matter what as long
> as it's sensible. Use no 'goto' statements. Limit function
> bodies to no more than 25 lines.
>
> Other: feel free to handle corner cases as you see fit, as long
> as there is some description of what choice was made.
>
> Hopefully it will be a fun exercise. It isn't trivial but it
> shouldn't take too long either.
Rough translation of Ben Bacarisse's Haskell program to C. The logic
could probably be made nicer with a pattern matching construct.
But the way I would do that would require another type for Symbols.
strpcom.c:
//#define DEBUG(...) __VA_ARGS__
#define DEBUG(...)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef union uobject *object;
typedef object fSuspension( object );
typedef object list;
typedef enum tag { INVALID, INTEGER, LIST, SUSPENSION, VOID } tag;
union uobject { tag t;
struct { tag t; int i; } Int;
struct { tag t; object a, b; } List;
struct { tag t; object v; fSuspension *f; } Suspension;
struct { tag t; void *v; } Void;
};
list skip_quote( list o );
list nested_comment( list o );
#define OBJECT(...) new_( (union uobject[]){{ __VA_ARGS__ }} )
object new_( object a ){
object p = calloc( 1, sizeof *p );
return p ? *p = *a, p : 0;
}
object Int( int i ){ return OBJECT( .Int = { INTEGER, i } ); }
list cons( object a, object b ){ return OBJECT( .List = { LIST, a, b } ); }
list one( object a ){ return cons( a, NULL ); }
object car( list o ){ return o && o->t == LIST ? o->List.a : NULL; }
object cdr( list o ){ return o && o->t == LIST ? o->List.b : NULL; }
object Void( void *v ){ return OBJECT( .Void = { VOID, v } ); }
object Suspension( void *v, fSuspension *f ){
return OBJECT( .Suspension = { SUSPENSION, v, f } );
}
int eq( object a, object b ){
return !a && !b ? 1 :
!a || !b ? 0 :
a->t != b->t ? 0 :
!memcmp( a, b, sizeof *a ) ? 1 : 0;
}
object force( object o ){
return !o || o->t != SUSPENSION ? o :
force( o->Suspension.f( o->Suspension.v ) );
}
list take( int i, list o ){
return i == 0 ? NULL :
!o ? NULL :
( *o = *force( o ),
cons( car( o ), take( i-1, cdr( o ) ) ) );
}
list drop( int i, list o ){
return i == 0 ? o :
!o ? NULL :
( *o = *force( o ),
drop( i-1, cdr( o ) ) );
}
static list
force_chars_from_file( object file ){
FILE *f = file->Void.v;
int c = fgetc( f );
return c != EOF ? cons( Int( c ), Suspension( file, force_chars_from_file ) )
: cons( Int( EOF ), NULL );
}
list chars_from_file( FILE *f ){
return f ? Suspension( Void( f ), force_chars_from_file ) : NULL;
}
list logical_lines( list o ){
object a = take( 1, o );
if( eq( car( a ), Int( '\\' ) ) ){
object as = drop( 1, o );
object b = take( 1, as );
if( eq( car( b ), Int( '\n' ) ) ){
return Suspension( drop( 1, as ), logical_lines );
} else {
return cons( a, Suspension( as, logical_lines ) );
}
} else {
return !eq( car( a ), Int( EOF ) )
? cons( car( a ), Suspension( drop( 1, o ), logical_lines ) )
: one( car( a ) );
}
}
list strip_comments( list o ){
object a = take( 1, o );
DEBUG( fprintf( stderr, "a='%c'\n", car( a )->Int.i ); )
if( eq( car( a ), Int( '/' ) ) ){
object as = drop( 1, o );
object b = take( 1, as );
DEBUG( fprintf( stderr, "b='%c'\n", car( b )->Int.i ); )
if( eq( car( b ), Int( '/' ) ) ) {
do {
as = drop( 1, as );
b = take( 1, as );
DEBUG( fprintf( stderr, "b='%c'\n", car( b )->Int.i ); )
} while( !eq( car( b ), Int( '\n' ) ) );
return cons( car( b ), Suspension( drop( 1, as ), strip_comments ) );
} else if( eq( car( b ), Int( '*' ) ) ){
return cons( Int(' '), nested_comment( drop( 1, as ) ) );
} else {
return cons( car( a ), Suspension( as, strip_comments ) );
}
} else {
if( eq( car( a ), Int( '\'' ) ) || eq( car( a ), Int( '"' ) ) ){
return skip_quote( o );
}
return !eq( car( a ), Int( EOF ) )
? cons( car( a ), Suspension( drop( 1, o ), strip_comments ) )
: one( car( a ) );
}
}
list nested_comment( list o ){
object a = take( 1, o );
if( eq( car( a ), Int( '*' ) ) ){
object as = drop( 1, o );
object b = take( 1, as );
if( eq( car( b ), Int( '/' ) ) ){
return drop( 1, as );
} else {
return nested_comment( as );
}
} else {
if( eq( car( a ), Int( EOF ) ) ){
fprintf( stderr, "Unterminated literal\n" );
exit( 1 );
}
return nested_comment( drop( 1, o ) );
}
}
list skip_quote( list o ){
object q = car( o );
o = cdr( o );
object a = take( 1, o );
if( eq( car( a ), Int( '\\' ) ) ){
return cons( car( a ),
cons( car( drop( 1, o ) ),
skip_quote( cons( q, drop( 2, o ) ) ) ) );
} else if( eq( car( a ), q ) ){
return cons( car( a ),
strip_comments( drop( 1, o ) ) );
}
return cons( car( a ),
skip_quote( cons( q, drop( 1, o ) ) ) );
}
void print( list o ){
switch( o ? o->t : 0 ){
default: break;
case INTEGER: if( o->Int.i != EOF ) fputc( o->Int.i, stdout ); break;
case SUSPENSION:
case LIST: print( car( take( 1, o ) ) );
print( drop( 1, o ) ); break;
}
}
int main(){
list input = chars_from_file( stdin );
print( strip_comments( logical_lines( input ) ) );
}
$ cat test
strip //comments
line \
continue
// comment \
continue
/* nested /* comment
*/
"/*quoted*/"
eof
$ ./strpcom < test
strip
line continue
"/*quoted*/"
eof
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2020-12-07 14:01 -0800 |
| Message-ID | <82057ad6-1534-42b0-9563-cd364a638323n@googlegroups.com> |
| In reply to | #157049 |
On Monday, December 7, 2020 at 3:44:53 PM UTC-6, luser droog wrote: > On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote: > > Short problem statement: a C program to remove comments from C > > source input. > Rough translation of Ben Bacarisse's Haskell program to C. The logic > could probably be made nicer with a pattern matching construct. > But the way I would do that would require another type for Symbols. > > strpcom.c: > <snip> Probably needs to be used with the Boehm gc. The code leaks memory like a firehose. > > $ cat test > strip //comments > line \ > continue > // comment \ > continue > /* nested /* comment > */ > "/*quoted*/" > eof > $ ./strpcom < test > strip > line continue > > > "/*quoted*/" > eof
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-12-07 22:16 +0000 |
| Message-ID | <875z5dntx1.fsf@bsb.me.uk> |
| In reply to | #157049 |
luser droog <luser.droog@gmail.com> writes: > On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote: <cut> >> Short problem statement: a C program to remove comments from C >> source input. <cut> > Rough translation of Ben Bacarisse's Haskell program to C. Ingenious. Sorry I led you astray by misinterpreting the specification! Before I learned about that I was considering something a bit like this, but I was hoping for less "machinery". Not a criticism -- I'm not at all sure one can get away with less. One thing pops into my head though. Do you need to separate car/cdr from take? At first glance, I'd be tempted to make car and cdr force any suspension node to a list node. I think it would tidy up some of code and I don't think you lose any laziness. Thoughts? <cut code> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2020-12-07 15:10 -0800 |
| Message-ID | <76be1bd5-6aea-4d87-8d27-53b0fc625d83n@googlegroups.com> |
| In reply to | #157053 |
On Monday, December 7, 2020 at 4:16:59 PM UTC-6, Ben Bacarisse wrote: > luser droog <luser...@gmail.com> writes: > > > On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote: > <cut> > >> Short problem statement: a C program to remove comments from C > >> source input. > <cut> > > Rough translation of Ben Bacarisse's Haskell program to C. > Ingenious. Sorry I led you astray by misinterpreting the specification! > > Before I learned about that I was considering something a bit like this, > but I was hoping for less "machinery". Not a criticism -- I'm not at > all sure one can get away with less. > > One thing pops into my head though. Do you need to separate car/cdr > from take? At first glance, I'd be tempted to make car and cdr force > any suspension node to a list node. I think it would tidy up some of > code and I don't think you lose any laziness. Thoughts? > Yes. Good idea. It looks like car and take are always used together, or rather, whenever there's a take() there's inevitably a car() to make use of the result. So I could factor out a lot of car()s by making a combined first() function (better name?). I'm thinking about how I might add pattern matching as simply as possible. In the parser combinator code, I have a `list match( list pats, list a )` function but it needs two kinds of Symbols (a "matching" symbol and a "variable capturing" symbol) and an Operator type to pack actions compactly into the patterns. (https://github.com/luser-dr00g/pcomb/blob/master/pc9fp.c#L246) Plus, it multplies the naming problem because each little clause needs its function since there aren't a lambdas. And then there's the garbage leaking problem... Maybe a tiny region allocator algo, and a copying collector to get a clean list in a new self contained region? A mark/sweep collector would need 80-100 lines I think.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-12-08 01:07 +0000 |
| Message-ID | <87v9ddksv1.fsf@bsb.me.uk> |
| In reply to | #157060 |
luser droog <luser.droog@gmail.com> writes: > On Monday, December 7, 2020 at 4:16:59 PM UTC-6, Ben Bacarisse wrote: >> luser droog <luser...@gmail.com> writes: >> >> > On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote: >> <cut> >> >> Short problem statement: a C program to remove comments from C >> >> source input. >> <cut> >> > Rough translation of Ben Bacarisse's Haskell program to C. >> Ingenious. Sorry I led you astray by misinterpreting the specification! >> >> Before I learned about that I was considering something a bit like this, >> but I was hoping for less "machinery". Not a criticism -- I'm not at >> all sure one can get away with less. >> >> One thing pops into my head though. Do you need to separate car/cdr >> from take? At first glance, I'd be tempted to make car and cdr force >> any suspension node to a list node. I think it would tidy up some of >> code and I don't think you lose any laziness. Thoughts? >> > > Yes. Good idea. It looks like car and take are always used together, or > rather, whenever there's a take() there's inevitably a car() to make use > of the result. So I could factor out a lot of car()s by making a combined > first() function (better name?). Haskell uses head and tail (but the tail is always a list, never an atom). The point I was making is the neither car nor cdr make sense if the argument has not been forced to a list already, so you might as well ensure that's happened in the functions themselves. > I'm thinking about how I might add pattern matching as simply as possible. > In the parser combinator code, I have a `list match( list pats, list a )` > function but it needs two kinds of Symbols (a "matching" symbol and > a "variable capturing" symbol) and an Operator type to pack actions > compactly into the patterns. > (https://github.com/luser-dr00g/pcomb/blob/master/pc9fp.c#L246) > Plus, it multplies the naming problem because each little clause needs its > function since there aren't a lambdas. > > And then there's the garbage leaking problem... Maybe a tiny region > allocator algo, and a copying collector to get a clean list in a new self > contained region? A mark/sweep collector would need 80-100 lines I > think. To paraphrase a well-know remark: you always end up implementing Lisp. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-12-08 00:34 +0000 |
| Message-ID | <RSzzH.473126$LMma.385727@fx47.ams4> |
| In reply to | #157053 |
On 07/12/2020 22:16, Ben Bacarisse wrote:
> luser droog <luser.droog@gmail.com> writes:
>
>> On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote:
> <cut>
>>> Short problem statement: a C program to remove comments from C
>>> source input.
> <cut>
>> Rough translation of Ben Bacarisse's Haskell program to C.
>
> Ingenious. Sorry I led you astray by misinterpreting the specification!
>
> Before I learned about that I was considering something a bit like this,
> but I was hoping for less "machinery". Not a criticism -- I'm not at
> all sure one can get away with less.
>
> One thing pops into my head though. Do you need to separate car/cdr
> from take? At first glance, I'd be tempted to make car and cdr force
> any suspension node to a list node. I think it would tidy up some of
> code and I don't think you lose any laziness. Thoughts?
This is my C version of your Haskell code (via a couple of my langages).
It's a bit simpler than that Lispy one, sorry.
(I have a habit of simplying things which means the result may not be so
interesting. However both static versions worked pretty much first time.)
This one managed to convert a couple of small programs that then compile
to the same executable. But being highly recursive, it still has a
problem with nesting depth (luser's version did too).
AFAICT this version is 'lazy'.
(Code to deal with //abc\ comments has been commented out, which seems
appropriate, as it had a bug.)
-------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
int peekchar;
void stripcomments(void);
void skipquote(int);
int nextchar(void) {
int c=peekchar;
peekchar=getchar();
if (peekchar==EOF) peekchar=0;
return c;
}
void dropline(void) {
int lastc,c;
do {
// lastc=c;
c=nextchar();
// } while (lastc!='\\' && c!=13 && c!=10);
} while (c!=13 && c!=10);
putchar('\n');
}
void skipblockcomment(void) {
int c=nextchar();
if (c=='*' && peekchar=='/') {
nextchar();
return;
}
if (c==0) {puts("Bad comment"); exit(1);}
skipblockcomment();
}
void skipquote(int q) {
int c=nextchar();
putchar(c);
if (c=='\\') {
putchar(nextchar());
skipquote(q);
} else if (c==q) {
stripcomments();
} else {
skipquote(q);
}
}
void stripcomments(void) {
int c=nextchar();
if (c==0) return;
if (c=='/' && peekchar=='/' ) {
nextchar();
putchar('\n');
dropline();
} else if (c=='/' && peekchar=='*' ) {
nextchar();
putchar(' ');
skipblockcomment();
} else {
putchar(c);
if (c=='"' || c=='\'') {
skipquote(c);
return;
}
}
stripcomments();
}
int main(void) {
nextchar();
stripcomments();
}
-------------------------------------------------------
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2020-12-08 18:17 -0800 |
| Message-ID | <2e2013d6-ebb1-4307-b91a-cba5509d2aa6n@googlegroups.com> |
| In reply to | #157049 |
On Monday, December 7, 2020 at 3:44:53 PM UTC-6, luser droog wrote:
> On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote:
> > Prompted by some recent discussion regarding 'goto' statements and
> > state machines, I would like to propose a programming exercise.
> > (It is perhaps a bit too large to be called an exercise, but not so
> > difficult that it deserves the label of challenge. On the other
> > hand there are some constraints so maybe challenge is apropos. In
> > any case somewhere in between those two bounds.)
> >
> > Short problem statement: a C program to remove comments from C
> > source input.
> >
> > Specifics: Remove both /*...*/ and //... style comments. Don't
> > worry about trigraphs. Read from stdin, write to stdout, and
> > diagnostics (if any) go to stderr. If EOF is seen inside a
> > comment, do something sensible but it doesn't matter what as long
> > as it's sensible. Use no 'goto' statements. Limit function
> > bodies to no more than 25 lines.
> >
> > Other: feel free to handle corner cases as you see fit, as long
> > as there is some description of what choice was made.
> >
> > Hopefully it will be a fun exercise. It isn't trivial but it
> > shouldn't take too long either.
>
> Rough translation of Ben Bacarisse's Haskell program to C. The logic
> could probably be made nicer with a pattern matching construct.
> But the way I would do that would require another type for Symbols.
>
Version 2. I add a match() function that helped simplify the big functions,
but also added to the number of big functions.
This version ignores line continuations except while slurping a single
line comment. But that means it can't see any comment markers if they
are hidden behind line continuations.
strpcom-v2.c:
//#define DEBUG(...) __VA_ARGS__
#define DEBUG(...)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef union uobject *object;
typedef object fSuspension( object );
typedef object list;
typedef enum tag { INVALID, INTEGER, LIST, SUSPENSION, VOID } tag;
union uobject { tag t;
struct { tag t; int i; } Int;
struct { tag t; object a, b; } List;
struct { tag t; object v; fSuspension *f; } Suspension;
struct { tag t; void *v; } Void;
};
list skip_quote( list o );
list nested_comment( list o );
void print( list o );
object add_global_root( object o ){ return o; }
object alloc(){
return calloc( 1, sizeof(object) );
}
#define OBJECT(...) new_( (union uobject[]){{ __VA_ARGS__ }} )
object new_( object a ){
object p = alloc();
return p ? *p = *a, p : 0;
}
object Int( int i ){ return OBJECT( .Int = { INTEGER, i } ); }
list cons( object a, object b ){ return OBJECT( .List = { LIST, a, b } ); }
list one( object a ){ return cons( a, NULL ); }
object car( list o ){ return o && o->t == LIST ? o->List.a : NULL; }
object cdr( list o ){ return o && o->t == LIST ? o->List.b : NULL; }
object Void( void *v ){ return OBJECT( .Void = { VOID, v } ); }
object Suspension( void *v, fSuspension *f ){
return OBJECT( .Suspension = { SUSPENSION, v, f } );
}
int eq( object a, object b ){
return !a && !b ? 1 :
!a || !b ? 0 :
a->t != b->t ? 0 :
!memcmp( a, b, sizeof *a );
}
int eqint( object a, int i ){
union uobject b = { .Int = { INTEGER, i } };
return eq( a, &b );
}
object force( object o ){
return !o || o->t != SUSPENSION ? o :
force( o->Suspension.f( o->Suspension.v ) );
}
list take( int i, list o ){
return i == 0 ? NULL :
!o ? NULL :
( *o = *force( o ),
cons( car( o ), take( i-1, cdr( o ) ) ) );
}
list drop( int i, list o ){
return i == 0 ? o :
!o ? NULL :
( *o = *force( o ),
drop( i-1, cdr( o ) ) );
}
object first( list o ){ return car( take( 1, o ) ); }
object rest( list o ){ return drop( 1, o ); }
int match( object pat, object it, object *matched, object *tail ){
if( !pat ){
*tail = it;
return 1;
}
if( (it ? it->t : 0) == SUSPENSION ) *it = *force( it );
if( pat->t != (it ? it->t : 0) ) return 0;
switch( pat->t ){
default: return 0;
case LIST: {
object sink;
if( match( first( pat ), first( it ), & sink, tail ) ){
*matched = it;
return match( rest( pat ), rest( it ), & sink, tail );
}
} break;
case INTEGER:
if( eq( pat, it ) ){
*matched = it;
return 1;
}
}
return 0;
}
static list
force_chars_from_file( object file ){
FILE *f = file->Void.v;
int c = fgetc( f );
return c != EOF ? cons( Int( c ), Suspension( file, force_chars_from_file ) )
: cons( Int( EOF ), NULL );
}
list chars_from_file( FILE *f ){
return f ? Suspension( Void( f ), force_chars_from_file ) : NULL;
}
list logical_lines( list o ){
DEBUG( fprintf( stderr, "[%c%c]", first( o )->Int.i, first( rest( o ) )->Int.i ); )
static list pat;
if( !pat ) pat = add_global_root( cons( Int( '\\' ), one( Int( '\n' ) ) ) );
object matched, tail;
if( match( pat, o, &matched, &tail ) ){
return Suspension( tail, logical_lines );
} else {
object a = first( o );
return eqint( a, EOF ) ? o : cons( a, Suspension( rest( o ), logical_lines ) );
}
}
list strip_comments( list o ){
DEBUG( fprintf( stderr, "<%c%c>", first( o )->Int.i, first( rest( o ) )->Int.i ); )
static list single, multi;
if( !single ) single = add_global_root( cons( Int( '/' ), one( Int( '/' ) ) ) );
if( !multi ) multi = add_global_root( cons( Int( '/' ), one( Int( '*' ) ) ) );
object matched, tail;
if( match( single, o, &matched, &tail ) ){
do {
tail = rest( tail );
matched = first( tail );
if( eqint( matched, '\\' ) ) tail = rest( tail ); // eat \NL
} while( !eqint( matched, '\n' ) );
return Suspension( tail, strip_comments );
} else if( match( multi, o, &matched, &tail ) ){
return cons( Int( ' ' ), strip_comments( nested_comment( rest( tail ) ) ) );
}
object a = first( o );
if( eqint( a, '\'' ) || eqint( a, '"' ) ) return cons( a, skip_quote( o ) );
return eqint( a, EOF ) ? o : cons( a, Suspension( rest( o ), strip_comments ) );
}
list nested_comment( list o ){
DEBUG( fprintf( stderr, "(%c%c)", first( o )->Int.i, first( rest( o ) )->Int.i ); )
static list end;
if( !end ) end = add_global_root( cons( Int( '*' ), one( Int( '/' ) ) ) );
object matched, tail;
if( match( end, o, &matched, &tail ) ) return tail;
if( eqint( car( o ), EOF ) ) fprintf( stderr, "Unterminated comment\n"), exit( 1 );
return nested_comment( rest( o ) );
}
// quote character q is "curried" onto the front of the list
list skip_quote( list o ){
object q = car( o );
o = cdr( o );
object a = first( o );
if( eqint( a, '\\' ) ){
return cons( a, cons( first( rest( o ) ), skip_quote( cons( q, drop( 2, o ) ) ) ) );
} else if( eq( a, q ) ){
return cons( a, strip_comments( rest( o ) ) );
}
if( eqint( a, EOF ) ) fprintf( stderr, "Unterminated literal\n"), exit( 1 );
return cons( a, skip_quote( cons( q, rest( o ) ) ) );
}
void print( list o ){
switch( o ? o->t : 0 ){
default: break;
case INTEGER: if( o->Int.i != EOF ) fputc( o->Int.i, stdout ); break;
case SUSPENSION:
case LIST: print( first( o ) );
print( rest( o ) ); break;
}
}
int main(){
list input = chars_from_file( stdin );
print( strip_comments( input ) );
//print( strip_comments( logical_lines( input ) ) );
}
$ make strpcom-v2
cc -std=c99 -g -Wall -Wpedantic -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-switch -Wreturn-type -Wunused-variable strpcom-v2.c -o strpcom-v2
$ cat test
strip //comments
line \
continue
// comment \
continue
/* nested /* comment
*/
"/*quoted*/"
""
"\""
"\\"
"\\\""
"foo\
bar"
/\
\
\
* comment *\
\
\
/
a = b /\
\
\
\
\
c;
// This is a multi-line \
single line comment
"abc\\
""
eof
$ ./strpcom-v2 < test
strip
line \
continue
"/*quoted*/"
""
"\""
"\\"
"\\\""
"foo\
bar"
/\
\
\
* comment *\
\
\
/
a = b /\
\
\
\
\
c;
Unterminated literal
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2020-12-09 00:56 -0800 |
| Message-ID | <590c3899-7fe8-4ef7-83ee-a96165fcab20n@googlegroups.com> |
| In reply to | #157110 |
On Tuesday, December 8, 2020 at 8:18:11 PM UTC-6, luser droog wrote:
> On Monday, December 7, 2020 at 3:44:53 PM UTC-6, luser droog wrote:
> > On Saturday, December 5, 2020 at 10:25:36 AM UTC-6, Tim Rentsch wrote:
> > > Prompted by some recent discussion regarding 'goto' statements and
> > > state machines, I would like to propose a programming exercise.
> > > (It is perhaps a bit too large to be called an exercise, but not so
> > > difficult that it deserves the label of challenge. On the other
> > > hand there are some constraints so maybe challenge is apropos. In
> > > any case somewhere in between those two bounds.)
> > >
> > > Short problem statement: a C program to remove comments from C
> > > source input.
> > >
> > > Specifics: Remove both /*...*/ and //... style comments. Don't
> > > worry about trigraphs. Read from stdin, write to stdout, and
> > > diagnostics (if any) go to stderr. If EOF is seen inside a
> > > comment, do something sensible but it doesn't matter what as long
> > > as it's sensible. Use no 'goto' statements. Limit function
> > > bodies to no more than 25 lines.
> > >
> > > Other: feel free to handle corner cases as you see fit, as long
> > > as there is some description of what choice was made.
> > >
> > > Hopefully it will be a fun exercise. It isn't trivial but it
> > > shouldn't take too long either.
> >
> > Rough translation of Ben Bacarisse's Haskell program to C. The logic
> > could probably be made nicer with a pattern matching construct.
> > But the way I would do that would require another type for Symbols.
> >
>
> Version 2. I add a match() function that helped simplify the big functions,
> but also added to the number of big functions.
>
Version 3. I think it actually fulfills the problem statement now. It removes
line continuations, but counts them and stashes the number in the node
immediately following. Then another pass at the end uses the counts to
restore any that survived comment removal. And I added a garbage collector.
strpcom-v3.c:
//#define DEBUG(...) __VA_ARGS__
#define DEBUG(...)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef union uobject *object;
typedef object fSuspension( object );
typedef object list;
typedef enum tag { INVALID, INTEGER, LIST, SUSPENSION, VOID } tag;
union uobject { tag t;
struct { tag t; int i, continues; } Int;
struct { tag t; object a, b; } List;
struct { tag t; object v; fSuspension *f; } Suspension;
struct { tag t; void *v; } Void;
};
typedef struct record {
int mark;
struct record *prev;
union uobject o;
} record;
list cons( object a, object b );
list skip_quote( list o );
list nested_comment( list o );
void print( list o );
record *allocation_list;
object global_roots;
object add_global_root( object o ){
global_roots = cons( o, global_roots ); return o;
}
record *alloc(){
return calloc( 1, sizeof(record) );
}
void mark( object ob ){
if( !ob ) return;
record *r = ((void*)( (char*)ob - offsetof( record, o ) ) );
if( r->mark ) return;
r->mark = 1;
switch( ob ? ob->t : 0 ){
case LIST: mark( ob->List.a ); mark( ob->List.b ); break;
case SUSPENSION: mark( ob->Suspension.v ); break;
}
}
int sweep( record **ptr ){
int count = 0;
while( *ptr ){
if( (*ptr)->mark ){
(*ptr)->mark = 0;
ptr = &(*ptr)->prev;
} else {
record *z = *ptr;
*ptr = (*ptr)->prev;
free( z );
++count;
}
}
return count;
}
int collect( object local_roots ){
mark( local_roots );
mark( global_roots );
return sweep( &allocation_list );
}
#define OBJECT(...) new_( (union uobject[]){{ __VA_ARGS__ }} )
object new_( object a ){
record *r = alloc();
object p = (union uobject[]){0};
if( r ){
r->prev = allocation_list;
allocation_list = r;
p = (void*)( ((char*)r) + offsetof( record, o ) );
}
return *p = *a, p;
}
object Int( int i ){
return OBJECT( .Int = { INTEGER, i } );
}
list cons( object a, object b ){
return OBJECT( .List = { LIST, a, b } );
}
list one( object a ){
return cons( a, NULL );
}
object Void( void *v ){
return OBJECT( .Void = { VOID, v } );
}
object Suspension( void *v, fSuspension *f ){
return OBJECT( .Suspension = { SUSPENSION, v, f } );
}
int eq( object a, object b ){
return !a && !b ? 1 :
!a || !b ? 0 :
a->t != b->t ? 0 :
a->t == INTEGER ? a->Int.i == b->Int.i
: !memcmp( a, b, sizeof *a );
}
int eqint( object a, int i ){
union uobject b = { .Int = { INTEGER, i } };
return eq( a, &b );
}
object force( object o ){
return !o || o->t != SUSPENSION
? o
: force( o->Suspension.f( o->Suspension.v ) );
}
object car( list o ){
if( o && o->t == SUSPENSION ) *o = *force( o );
return o && o->t == LIST ? o->List.a : NULL;
}
object cdr( list o ){
if( o && o->t == SUSPENSION ) *o = *force( o );
return o && o->t == LIST ? o->List.b : NULL;
}
int match( object pat, object it, object *matched, object *tail ){
if( !pat ){
*tail = it;
return 1;
}
if( (it ? it->t : 0) == SUSPENSION ) *it = *force( it );
if( pat->t != (it ? it->t : 0) ) return 0;
switch( pat->t ){
default: return 0;
case LIST: {
object sink;
if( match( car( pat ), car( it ), & sink, tail ) ){
*matched = it;
return match( cdr( pat ), cdr( it ), & sink, tail );
}
} break;
case INTEGER:
if( eq( pat, it ) ){
*matched = it;
return 1;
}
}
return 0;
}
static list
force_chars_from_file( object file ){
FILE *f = file->Void.v;
int c = fgetc( f );
return c != EOF
? cons( Int( c ), Suspension( file, force_chars_from_file ) )
: cons( Int( EOF ), NULL );
}
list chars_from_file( FILE *f ){
return f ? Suspension( Void( f ), force_chars_from_file ) : NULL;
}
list logical_lines( list o ){
static list pat;
if( !pat )
pat = add_global_root( cons( Int( '\\' ), one( Int( '\n' ) ) ) );
object matched, tail;
DEBUG( if( car(o)->Int.i!=EOF )
fprintf( stderr, "[%c%c]", car(o)->Int.i, car(cdr(o))->Int.i ); )
if( match( pat, o, &matched, &tail ) ){
DEBUG( fprintf( stderr, "@" ); )
car( tail )->Int.continues = car( o )->Int.continues + 1;
return Suspension( tail, logical_lines );
} else {
object a = car( o );
return eqint( a, EOF )
? o
: cons( a, Suspension( cdr( o ), logical_lines ) );
}
}
list restore_continues( list o ){
if( !o ) return NULL;
object a = car( o );
if( eqint( a, EOF ) ) return o;
object z = cdr( o );
object r = cons( a, Suspension( z, restore_continues ) );
while( a->Int.continues ){
r = cons( Int( '\\' ), cons( Int( '\n' ), r ) );
--a->Int.continues;
}
return r;
}
list strip_comments( list o ){
static list single, multi;
if( !single )
single = add_global_root( cons( Int( '/' ), one( Int( '/' ) ) ) );
if( !multi )
multi = add_global_root( cons( Int( '/' ), one( Int( '*' ) ) ) );
object matched, tail;
DEBUG( if(car(o)->Int.i!=EOF)
fprintf(stderr,"<%c%c>", car(o)->Int.i, car(cdr(o))->Int.i); )
if( match( single, o, &matched, &tail ) ){
DEBUG( fprintf( stderr, "@" ); )
do {
tail = cdr( tail );
matched = car( tail );
//if( eqint( matched, '\\' ) ) tail = cdr( tail ); // eat \NL
} while( !eqint( matched, '\n' ) );
return Suspension( tail, strip_comments );
} else if( match( multi, o, &matched, &tail ) ){
DEBUG( fprintf( stderr, "@" ); )
return cons( Int( ' ' ),
strip_comments( nested_comment( cdr( tail ) ) ) );
}
object a = car( o );
if( eqint( a, '\'' ) || eqint( a, '"' ) )
return cons( a, skip_quote( o ) );
return eqint( a, EOF )
? o
: cons( a, Suspension( cdr( o ), strip_comments ) );
}
list nested_comment( list o ){
DEBUG( fprintf( stderr, "(%c%c)",
car( o )->Int.i, car( cdr( o ) )->Int.i ); )
static list end;
if( !end )
end = add_global_root( cons( Int( '*' ), one( Int( '/' ) ) ) );
object matched, tail;
if( match( end, o, &matched, &tail ) )
return tail;
if( eqint( car( o ), EOF ) )
fprintf( stderr, "Unterminated comment\n"),
exit( 1 );
return nested_comment( cdr( o ) );
}
// quote character q is "curried" onto the front of the list
list skip_quote( list o ){
object q = car( o );
o = cdr( o );
object a = car( o );
if( eqint( a, '\\' ) ){
return cons( a,
cons( car( cdr( o ) ),
skip_quote( cons( q, cdr( cdr( o ) ) ) ) ) );
} else if( eq( a, q ) ){
return cons( a,
strip_comments( cdr( o ) ) );
}
if( eqint( a, EOF ) )
fprintf( stderr, "Unterminated literal\n"),
exit( 1 );
return cons( a,
skip_quote( cons( q, cdr( o ) ) ) );
}
void print( list o ){
switch( o ? o->t : 0 ){
default: break;
case INTEGER: if( o->Int.i != EOF )
fputc( o->Int.i, stdout );
break;
case SUSPENSION:
case LIST: print( car( o ) );
print( cdr( o ) );
break;
}
}
int main(){
list input = add_global_root( chars_from_file( stdin ) );
DEBUG( print( input ); )
list logical = logical_lines( input );
DEBUG( print( logical ); )
list stripped = strip_comments( logical );
DEBUG( print( stripped ); )
list restored = restore_continues( stripped );
print( restored );
fprintf( stderr, "@%d\n", collect( NULL ) );
}
[Note: the file is actually -v4 on my disk bc -v3 didn't work out so well,
but I wish to submit the above as -v3]
$ make strpcom-v4
cc -std=c99 -g -Wall -Wpedantic -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-switch -Wreturn-type -Wunused-variable strpcom-v4.c -o strpcom-v4
$ cat test
strip //comments
line \
continue
// comment \
continue
/* nested /* comment
*/
"/*quoted*/"
""
"\""
"\\"
"\\\""
"foo\
bar"
/\
\
\
* comment *\
\
\
/
a = b /\
\
\
\
\
c;
// This is a multi-line \
single line comment
"abc\\
""
eof
$ ./strpcom-v4 < test
strip
line \
continue
"/*quoted*/"
""
"\""
"\\"
"\\\""
"foo\
bar"
a = b /\
\
\
\
\
c;
"abc\\
""
eof
@1084
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-09 02:30 -0800 |
| Message-ID | <86a6un5l11.fsf@linuxsc.com> |
| In reply to | #157131 |
luser droog <luser.droog@gmail.com> writes: [...] > Version 3. I think it actually fulfills the problem statement now. It removes > line continuations, but counts them and stashes the number in the node > immediately following. Then another pass at the end uses the counts to > restore any that survived comment removal. And I added a garbage collector. > [...] Problem 1: no #include <stddef.h> droog-3.c: In function 'mark': droog-3.c:43:37: error: implicit declaration of function 'offsetof' [-Wimplicit-function-declaration] Problem 2: after adding #include <stddef.h> - suspicious code droog-3.c: In function 'new_': droog-3.c:82:11: warning: function may return address of local variable [-Wreturn-local-addr] Problem 3: segmentation fault
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2020-12-09 15:14 -0800 |
| Message-ID | <77f507a2-70b5-4143-b4aa-babc4f2a17abn@googlegroups.com> |
| In reply to | #157138 |
On Wednesday, December 9, 2020 at 4:30:51 AM UTC-6, Tim Rentsch wrote:
> luser droog <luser...@gmail.com> writes:
>
> [...]
> > Version 3. I think it actually fulfills the problem statement now. It removes
> > line continuations, but counts them and stashes the number in the node
> > immediately following. Then another pass at the end uses the counts to
> > restore any that survived comment removal. And I added a garbage collector.
> > [...]
>
> Problem 1: no #include <stddef.h>
>
> droog-3.c: In function 'mark':
> droog-3.c:43:37: error: implicit declaration of function 'offsetof' [-Wimplicit-function-declaration]
>
> Problem 2: after adding #include <stddef.h> - suspicious code
>
> droog-3.c: In function 'new_':
> droog-3.c:82:11: warning: function may return address of local variable [-Wreturn-local-addr]
>
> Problem 3: segmentation fault
Well, dang. Yep around line 82 does look funny. I couldn't reproduce the segfault.
Here's my Version 4. I removed the lazy evaluation but kept the garbage collector.
Saved about 50 lines and it produces less garbage! I've tested with my tests and with
krx123tp.c on cygwin and red hat.
//strpcom-v5.c:
//$ make strpcom-v5 CFLAGS='-std=c99 -Wall -pedantic -Wextra -Wno-switch'
//#define DEBUG(...) __VA_ARGS__
#define DEBUG(...)
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef union uobject *object;
typedef object list;
typedef enum tag { INVALID, INTEGER, LIST } tag;
union uobject { tag t;
struct { tag t; int i, continues; } Int;
struct { tag t; object a, b; } List;
};
typedef struct record {
int mark;
struct record *prev;
union uobject o;
} record;
list cons( object a, object b );
list skip_quote( object q, list o );
list nested_comment( list o );
void print( list o );
record *allocation_list;
object global_roots;
object add_global_root( object o ){
global_roots = cons( o, global_roots ); return o;
}
record *alloc(){
return calloc( 1, sizeof(record) );
}
void mark( object ob ){
if( !ob ) return;
record *r = ((void*)( (char*)ob - offsetof( record, o ) ) );
if( r->mark ) return;
r->mark = 1;
switch( ob ? ob->t : 0 ){
case LIST: mark( ob->List.a ); mark( ob->List.b ); break;
}
}
int sweep( record **ptr ){
int count = 0;
while( *ptr ){
if( (*ptr)->mark ){
(*ptr)->mark = 0;
ptr = &(*ptr)->prev;
} else {
record *z = *ptr;
*ptr = (*ptr)->prev;
free( z );
++count;
}
}
return count;
}
int collect( object local_roots ){
mark( local_roots );
mark( global_roots );
return sweep( &allocation_list );
}
#define OBJECT(...) new_( (union uobject[]){{ __VA_ARGS__ }} )
object new_( object a ){
record *r = alloc();
object p = NULL;
if( r ){
r->prev = allocation_list;
allocation_list = r;
p = (void*)( ((char*)r) + offsetof( record, o ) );
*p = *a;
}
return p;
}
object Int( int i ){ return OBJECT( .Int = { INTEGER, i } ); }
list cons( object a, object b ){ return OBJECT( .List = { LIST, a, b } ); }
list one( object a ){ return cons( a, NULL ); }
object car( list o ){
return o && o->t == LIST ? o->List.a : NULL;
}
object cdr( list o ){
return o && o->t == LIST ? o->List.b : NULL;
}
int eq( object a, object b ){
return !a && !b ? 1 :
!a || !b ? 0 :
a->t != b->t ? 0 :
a->t == INTEGER ? a->Int.i == b->Int.i
: !memcmp( a, b, sizeof *a );
}
int eqint( object a, int i ){
union uobject b = { .Int = { INTEGER, i } };
return eq( a, &b );
}
int match( object pat, object it, object *matched, object *tail ){
if( !pat ){
return *tail = it, 1;
}
if( pat->t != (it ? it->t : 0) ) return 0;
switch( pat->t ){
case LIST:
{
object sink;
if( match( car( pat ), car( it ), & sink, tail ) ){
return *matched = it, match( cdr( pat ), cdr( it ), & sink, tail );
}
} break;
case INTEGER:
if( eq( pat, it ) ){
return *matched = it, 1;
}
}
return 0;
}
list chars_from_file( FILE *f ){
int c = fgetc( f );
return c != EOF ? cons( Int( c ), chars_from_file( f ) ) : one( Int( c ) );
}
list logical_lines( list o ){
static list pat;
if( !pat ) pat = add_global_root( cons( Int( '\\' ), one( Int( '\n' ) ) ) );
object matched, tail;
DEBUG( if( car(o)->Int.i!=EOF )
fprintf( stderr, "[%c%c]", car(o)->Int.i, car(cdr(o))->Int.i ); )
if( match( pat, o, &matched, &tail ) ){
DEBUG( fprintf( stderr, "@" ); )
car( tail )->Int.continues = car( o )->Int.continues + 1;
return logical_lines( tail );
} else {
object a = car( o );
return eqint( a, EOF ) ? o : cons( a, logical_lines( cdr( o ) ) );
}
}
list restore_continues( list o ){
if( !o ) return NULL;
object a = car( o );
if( eqint( a, EOF ) ) return o;
object z = cdr( o );
object r = cons( a, restore_continues( z ) );
while( a->Int.continues ){
r = cons( Int( '\\' ), cons( Int( '\n' ), r ) );
--a->Int.continues;
}
return r;
}
list strip_comments( list o ){
static list single, multi;
if( !single ) single = add_global_root( cons( Int('/'), one(Int('/')) ) );
if( !multi ) multi = add_global_root( cons( Int('/'), one(Int('*')) ) );
object matched, tail;
DEBUG( if(car(o)->Int.i!=EOF)
fprintf(stderr,"<%c%c>", car(o)->Int.i, car(cdr(o))->Int.i); )
if( match( single, o, &matched, &tail ) ){
DEBUG( fprintf( stderr, "@" ); )
do {
tail = cdr( tail );
matched = car( tail );
} while( !eqint( matched, '\n' ) );
return strip_comments( tail );
} else if( match( multi, o, &matched, &tail ) ){
DEBUG( fprintf( stderr, "@" ); )
return cons( Int( ' ' ),
strip_comments( nested_comment( cdr( tail ) ) ) );
}
object a = car( o );
if( eqint( a, '\'' ) || eqint( a, '"' ) )
return cons( a, skip_quote( a, cdr( o ) ) );
return eqint( a, EOF ) ? o
: cons( a, strip_comments( cdr( o ) ) );
}
list nested_comment( list o ){
DEBUG(fprintf( stderr, "(%c%c)", car( o )->Int.i, car( cdr( o ) )->Int.i );)
static list end;
if( !end ) end = add_global_root( cons( Int( '*' ), one( Int( '/' ) ) ) );
object matched, tail;
if( match( end, o, &matched, &tail ) )
return tail;
if( eqint( car( o ), EOF ) )
fprintf( stderr, "Unterminated comment\n"),
exit( 1 );
return nested_comment( cdr( o ) );
}
list skip_quote( object q, list o ){
object a = car( o );
if( eqint( a, '\\' ) ){
return cons( a, cons( car( cdr( o ) ),
skip_quote( q, cdr( cdr( o ) ) ) ) );
} else if( eq( a, q ) ){
return cons( a, strip_comments( cdr( o ) ) );
}
if( eqint( a, EOF ) )
fprintf( stderr, "Unterminated literal\n"),
exit( 1 );
return cons( a, skip_quote( q, cdr( o ) ) );
}
void print( list o ){
switch( o ? o->t : 0 ){
case INTEGER: if( o->Int.i != EOF ) fputc( o->Int.i, stdout );
break;
case LIST: print( car( o ) );
print( cdr( o ) ); break;
}
}
int main( int argc, char **argv ){
list input = chars_from_file( argc > 1 ? fopen( argv[1], "r" ) : stdin );
DEBUG( printf( "input:\n"); print( input ); )
list logical = logical_lines( input );
DEBUG( printf( "logical:\n"); print( logical ); )
list stripped = strip_comments( logical );
DEBUG( printf( "stripped:\n"); print( stripped ); )
list restored = restore_continues( stripped );
DEBUG( printf( "restored:\n"); )
print( restored );
DEBUG( printf( "@%d\n", collect( restored ) ); )
}
[toc] | [prev] | [next] | [standalone]
Page 6 of 20 — ← Prev page 1 … 4 5 [6] 7 8 … 20 Next page →
Back to top | Article view | comp.lang.c
csiph-web