aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzlg <zlg@zlg.space>2013-10-13 03:24:07 -0500
committerzlg <zlg@zlg.space>2013-10-13 03:24:07 -0500
commit8d64674314e55a1c2fa044cf9552886a4e852ec9 (patch)
treeb09d99fa872d5c438c54fff4e98c0224f5de6eb9
parentSolve Exercise 5-11: `entab` and `detab` remixed! (diff)
downloadknr-8d64674314e55a1c2fa044cf9552886a4e852ec9.tar.gz
knr-8d64674314e55a1c2fa044cf9552886a4e852ec9.tar.bz2
knr-8d64674314e55a1c2fa044cf9552886a4e852ec9.tar.xz
knr-8d64674314e55a1c2fa044cf9552886a4e852ec9.zip
Solve Exercise 5-12: flexible `detab` and `entab`
-rw-r--r--ch5/5-12_detab-spec.c75
-rw-r--r--ch5/5-12_entab-spec.c82
2 files changed, 157 insertions, 0 deletions
diff --git a/ch5/5-12_detab-spec.c b/ch5/5-12_detab-spec.c
new file mode 100644
index 0000000..ba22619
--- /dev/null
+++ b/ch5/5-12_detab-spec.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <ctype.h>
+
+/* The C Programming Language: 2nd Edition
+ *
+ * Exercise 5-12: Extend `entab` and `detab` to accept the shorthand
+ * `entab -m +n` to mean tab stops every n columns, starting at column m.
+ * Choose convenient (for the user) default behavior.
+ */
+
+#define DEFAULTTAB 8
+
+int main(int argc, char *argv[]) {
+ int column, c;
+ int tabstart = (-1);
+ int tabevery = (-1);
+ char arg[4];
+ column = 0;
+
+ if (argc > 1) {
+ int i = 1;
+ int j = 0;
+ while (--argc > 0) {
+ c = argv[i][j++];
+ if (c == '-' || c == '+') {
+ while (isdigit(argv[i][j])) {
+ arg[j - 1] = argv[i][j];
+ j++;
+ }
+ arg[3] = '\0';
+ if (c == '-') {
+ tabstart = atoi(arg);
+ } else {
+ tabevery = atoi(arg);
+ }
+ j = 0;
+ } else {
+ printf("detab: unrecognized argument %s\n", *argv);
+ }
+ i++;
+ }
+ }
+ /* Clean up the mess if either argument hasn't been set to something sane */
+ if (tabstart == -1) {
+ tabstart = 0;
+ }
+ if (tabevery == -1) {
+ tabevery = DEFAULTTAB;
+ }
+
+ while ((c = getchar()) != EOF) {
+ column++;
+
+ if (c == '\t') {
+ /* No point in processing our tabs until we're after the offset */
+ if (column > tabstart) {
+ putchar(' ');
+ while ((column - tabstart) % tabevery != 0) {
+ putchar(' ');
+ column++;
+ }
+ } else {
+ putchar(' ');
+ }
+ } else {
+ /* reset the counts on a newline */
+ if (c == '\n') {
+ column = 0;
+ }
+ putchar(c);
+ }
+ }
+
+ return 0;
+}
diff --git a/ch5/5-12_entab-spec.c b/ch5/5-12_entab-spec.c
new file mode 100644
index 0000000..c1f3f6b
--- /dev/null
+++ b/ch5/5-12_entab-spec.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+/* The C Programming Language: 2nd Edition
+ *
+ * Exercise 5-12: Extend `entab` and `detab` to accept the shorthand
+ * `entab -m +n` to mean tab stops every n columns, starting at column m.
+ * Choose convenient (for the user) default behavior.
+ */
+
+#define DEFAULTTAB 8
+
+int main(int argc, char *argv[]) {
+ int column, c, spaces;
+ int tabstart = (-1);
+ int tabevery = (-1);
+ char arg[4];
+ spaces = column = 0;
+
+ if (argc > 1) {
+ int i = 1;
+ int j = 0;
+ while (--argc > 0) {
+ c = argv[i][j++];
+ if (c == '-' || c == '+') {
+ while (isdigit(argv[i][j])) {
+ arg[j - 1] = argv[i][j];
+ j++;
+ }
+ arg[3] = '\0';
+ if (c == '-') {
+ tabstart = atoi(arg);
+ } else {
+ tabevery = atoi(arg);
+ }
+ j = 0;
+ } else {
+ printf("entab: unrecognized argument %s\n", *argv);
+ }
+ i++;
+ }
+ }
+ /* Clean up the mess if either argument hasn't been set to something sane */
+ if (tabstart == -1) {
+ tabstart = 0;
+ }
+ if (tabevery == -1) {
+ tabevery = DEFAULTTAB;
+ }
+
+ while ((c = getchar()) != EOF) {
+ column++;
+
+ if (c == ' ') {
+ /* No point in starting our tabs until we're after the offset */
+ if (column > tabstart) {
+ spaces++;
+ if ((column - tabstart) % tabevery == 0) {
+ if (spaces > 1) {
+ putchar('\t');
+ spaces = 0;
+ }
+ }
+ }
+ } else {
+ /* output all extra spaces first */
+ while (spaces > 0) {
+ putchar(' ');
+ spaces--;
+ }
+ /* reset the counts and argument position on a newline */
+ if (c == '\n') {
+ column = 0;
+ spaces = 0;
+ }
+ putchar(c);
+ }
+ }
+
+ return 0;
+}