-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathdetab.c
96 lines (84 loc) · 2.43 KB
/
detab.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
* Exercise 5-11. Modify the program and detab (written in exercises in Chapter
* 1) to accept a list of tab stops as arguments. Use the default tab setting
* if there are no arguments.
*
* By Faisal Saadatmand
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 1000 /* max length of input/output line */
#define MAXTABS 100 /* max number of tab stop positions */
#define N 4 /* default tabstops (every n columns) */
/* functions */
int getLine(char *, int);
int setTabList(int, char **, int *);
int ToTabStop(int, int *, int);
void detab(char *, char *, int *, int);
/* getLine function: read a line into s, return length */
int getLine(char *s, int lim)
{
int c;
char *len;
len = s;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
*s++ = c;
if (c == '\n')
*s++ = c;
*s = '\0';
return strlen(len);
}
/* setTabStops: extracts topstops positions from command line arguments and
* store them in tabList. Return size of tabList, 0 if no tabstop list was
* provided, or -1 if arg is an invalid tabstop value. */
int setTabList(int count, char **arg, int *tabList)
{
int i;
for (i = 0; --count > 0; ++i)
if (!(tabList[i] = atoi(*++arg)) || tabList[i] < 0) {
printf("Invalid tabstop: %s\n", *arg);
return -1;
}
return i; /* i is 0 if no tablist */
}
/* toNextTab: return the number of blanks to the next tab stop position. */
int ToTabStop(int column, int *tabList, int tlSize)
{
if (!tlSize)
return N - (column % N);
/* if list exists, find nearest tab stop position in it */
while (tlSize != 0 && column >= *tabList) {
++tabList;
--tlSize;
}
return *tabList - column;
}
/* detab function: replaces tabs with the proper number of blanks */
void detab(char *in, char *out, int *tabList, int tlSize)
{
int i; /* index for read line */
int j; /* index for modified (written) line */
int nblanks; /* number of required blanks */
for (i = j = 0; in[i] != '\0'; ++i)
if (in[i] == '\t') {
nblanks = ToTabStop(j, tabList, tlSize);
while (nblanks-- > 0)
out[j++] = ' ';
} else
out[j++] = in[i];
out[j] = '\0';
}
int main(int argc, char *argv[])
{
char in[MAXLEN]; /* currently read line */
char out[MAXLEN]; /* modified line */
int tabList[MAXTABS]; /* a list of tab stop positions */
int tlSize; /* size of tablist */
if ((tlSize = setTabList(argc, argv, tabList)) >= 0)
while (getLine(in, MAXLEN) > 0) {
detab(in, out, tabList, tlSize);
printf("%s", out);
}
return 0;
}