View | Details | Raw Unified | Return to bug 78562
Collapse All | Expand All

(-)join.c (-19 / +35 lines)
Lines 105-111 Link Here
105
static wchar_t default_tabchar[] = L" \t";
105
static wchar_t default_tabchar[] = L" \t";
106
wchar_t *tabchar = default_tabchar;/* delimiter characters (-t) */
106
wchar_t *tabchar = default_tabchar;/* delimiter characters (-t) */
107
107
108
int  cmp(LINE *, u_long, LINE *, u_long);
108
int  cmp(LINE *, u_long, LINE *, u_long, int);
109
int  cmpnum(long long, long long);
109
void fieldarg(char *);
110
void fieldarg(char *);
110
void joinlines(INPUT *, INPUT *);
111
void joinlines(INPUT *, INPUT *);
111
int  mbscoll(const char *, const char *);
112
int  mbscoll(const char *, const char *);
Lines 114-120 Link Here
114
void outfield(LINE *, u_long, int);
115
void outfield(LINE *, u_long, int);
115
void outoneline(INPUT *, LINE *);
116
void outoneline(INPUT *, LINE *);
116
void outtwoline(INPUT *, LINE *, INPUT *, LINE *);
117
void outtwoline(INPUT *, LINE *, INPUT *, LINE *);
117
void slurp(INPUT *);
118
void slurp(INPUT *, int);
118
wchar_t *towcs(const char *);
119
wchar_t *towcs(const char *);
119
void usage(void);
120
void usage(void);
120
121
Lines 122-128 Link Here
122
main(int argc, char *argv[])
123
main(int argc, char *argv[])
123
{
124
{
124
	INPUT *F1, *F2;
125
	INPUT *F1, *F2;
125
	int aflag, ch, cval, vflag;
126
	int aflag, ch, cval, nflag, vflag;
126
	char *end;
127
	char *end;
127
128
128
	setlocale(LC_ALL, "");
129
	setlocale(LC_ALL, "");
Lines 130-138 Link Here
130
	F1 = &input1;
131
	F1 = &input1;
131
	F2 = &input2;
132
	F2 = &input2;
132
133
133
	aflag = vflag = 0;
134
	aflag = nflag = vflag = 0;
134
	obsolete(argv);
135
	obsolete(argv);
135
	while ((ch = getopt(argc, argv, "\01a:e:j:1:2:o:t:v:")) != -1) {
136
	while ((ch = getopt(argc, argv, "\01na:e:j:1:2:o:t:v:")) != -1) {
136
		switch (ch) {
137
		switch (ch) {
137
		case '\01':		/* See comment in obsolete(). */
138
		case '\01':		/* See comment in obsolete(). */
138
			aflag = 1;
139
			aflag = 1;
Lines 180-185 Link Here
180
			--F1->joinf;
181
			--F1->joinf;
181
			--F2->joinf;
182
			--F2->joinf;
182
			break;
183
			break;
184
		case 'n':
185
			nflag = 1;
186
			break;
183
		case 'o':
187
		case 'o':
184
			fieldarg(optarg);
188
			fieldarg(optarg);
185
			break;
189
			break;
Lines 234-259 Link Here
234
	if (F1->fp == stdin && F2->fp == stdin)
238
	if (F1->fp == stdin && F2->fp == stdin)
235
		errx(1, "only one input file may be stdin");
239
		errx(1, "only one input file may be stdin");
236
240
237
	slurp(F1);
241
	slurp(F1, nflag);
238
	slurp(F2);
242
	slurp(F2, nflag);
239
	while (F1->setcnt && F2->setcnt) {
243
	while (F1->setcnt && F2->setcnt) {
240
		cval = cmp(F1->set, F1->joinf, F2->set, F2->joinf);
244
		cval = cmp(F1->set, F1->joinf, F2->set, F2->joinf, nflag);
241
		if (cval == 0) {
245
		if (cval == 0) {
242
			/* Oh joy, oh rapture, oh beauty divine! */
246
			/* Oh joy, oh rapture, oh beauty divine! */
243
			if (joinout)
247
			if (joinout)
244
				joinlines(F1, F2);
248
				joinlines(F1, F2);
245
			slurp(F1);
249
			slurp(F1, nflag);
246
			slurp(F2);
250
			slurp(F2, nflag);
247
		} else if (cval < 0) {
251
		} else if (cval < 0) {
248
			/* File 1 takes the lead... */
252
			/* File 1 takes the lead... */
249
			if (F1->unpair)
253
			if (F1->unpair)
250
				joinlines(F1, NULL);
254
				joinlines(F1, NULL);
251
			slurp(F1);
255
			slurp(F1, nflag);
252
		} else {
256
		} else {
253
			/* File 2 takes the lead... */
257
			/* File 2 takes the lead... */
254
			if (F2->unpair)
258
			if (F2->unpair)
255
				joinlines(F2, NULL);
259
				joinlines(F2, NULL);
256
			slurp(F2);
260
			slurp(F2, nflag);
257
		}
261
		}
258
	}
262
	}
259
263
Lines 264-281 Link Here
264
	if (F1->unpair)
268
	if (F1->unpair)
265
		while (F1->setcnt) {
269
		while (F1->setcnt) {
266
			joinlines(F1, NULL);
270
			joinlines(F1, NULL);
267
			slurp(F1);
271
			slurp(F1, nflag);
268
		}
272
		}
269
	if (F2->unpair)
273
	if (F2->unpair)
270
		while (F2->setcnt) {
274
		while (F2->setcnt) {
271
			joinlines(F2, NULL);
275
			joinlines(F2, NULL);
272
			slurp(F2);
276
			slurp(F2, nflag);
273
		}
277
		}
274
	exit(0);
278
	exit(0);
275
}
279
}
276
280
277
void
281
void
278
slurp(INPUT *F)
282
slurp(INPUT *F, int nflag)
279
{
283
{
280
	LINE *lp, *lastlp, tmp;
284
	LINE *lp, *lastlp, tmp;
281
	size_t len;
285
	size_t len;
Lines 355-361 Link Here
355
		}
359
		}
356
360
357
		/* See if the join field value has changed. */
361
		/* See if the join field value has changed. */
358
		if (lastlp != NULL && cmp(lp, F->joinf, lastlp, F->joinf)) {
362
		if (lastlp != NULL && cmp(lp, F->joinf, lastlp, F->joinf, nflag)) {
359
			F->pushbool = 1;
363
			F->pushbool = 1;
360
			F->pushback = F->setcnt;
364
			F->pushback = F->setcnt;
361
			break;
365
			break;
Lines 393-405 Link Here
393
}
397
}
394
398
395
int
399
int
396
cmp(LINE *lp1, u_long fieldno1, LINE *lp2, u_long fieldno2)
400
cmpnum(long long a, long long b)
401
{
402
	if (a < b)
403
		return (-1);
404
	else if (a == b)
405
		return 0;
406
	else
407
		return 1; 
408
}
409
410
int
411
cmp(LINE *lp1, u_long fieldno1, LINE *lp2, u_long fieldno2, int nflag)
397
{
412
{
398
	if (lp1->fieldcnt <= fieldno1)
413
	if (lp1->fieldcnt <= fieldno1)
399
		return (lp2->fieldcnt <= fieldno2 ? 0 : 1);
414
		return (lp2->fieldcnt <= fieldno2 ? 0 : 1);
400
	if (lp2->fieldcnt <= fieldno2)
415
	if (lp2->fieldcnt <= fieldno2)
401
		return (-1);
416
		return (-1);
402
	return (mbscoll(lp1->fields[fieldno1], lp2->fields[fieldno2]));
417
	return (nflag ? cmpnum(atoll(lp1->fields[fieldno1]), atoll(lp2->fields[fieldno2])):
418
	    mbscoll(lp1->fields[fieldno1], lp2->fields[fieldno2]));
403
}
419
}
404
420
405
int
421
int
Lines 664-669 Link Here
664
	(void)fprintf(stderr, "%s %s\n%s\n",
680
	(void)fprintf(stderr, "%s %s\n%s\n",
665
	    "usage: join [-a fileno | -v fileno ] [-e string] [-1 field]",
681
	    "usage: join [-a fileno | -v fileno ] [-e string] [-1 field]",
666
	    "[-2 field]",
682
	    "[-2 field]",
667
		"            [-o list] [-t char] file1 file2");
683
		"            [-o list] [-n] [-t char] file1 file2");
668
	exit(1);
684
	exit(1);
669
}
685
}
(-)join.1 (+15 lines)
Lines 50-55 Link Here
50
.Op Fl o Ar list
50
.Op Fl o Ar list
51
.Bk -words
51
.Bk -words
52
.Ek
52
.Ek
53
.Op Fl n
53
.Op Fl t Ar char
54
.Op Fl t Ar char
54
.Op Fl \&1 Ar field
55
.Op Fl \&1 Ar field
55
.Op Fl \&2 Ar field
56
.Op Fl \&2 Ar field
Lines 93-98 Link Here
93
.It Fl e Ar string
94
.It Fl e Ar string
94
Replace empty output fields with
95
Replace empty output fields with
95
.Ar string .
96
.Ar string .
97
.It Fl n
98
Assume numerically sorted input files.
96
.It Fl o Ar list
99
.It Fl o Ar list
97
The
100
The
98
.Fl o
101
.Fl o
Lines 158-163 Link Here
158
without the
161
without the
159
.Fl b
162
.Fl b
160
option.
163
option.
164
When the option
165
.Fl n
166
is used, the files to be joined should be ordered as with
167
.Xr sort 1
168
with
169
.Fl n
170
option.
161
.Pp
171
.Pp
162
If one of the arguments
172
If one of the arguments
163
.Ar file1
173
.Ar file1
Lines 211-216 Link Here
211
.Nm
221
.Nm
212
command conforms to
222
command conforms to
213
.St -p1003.1-2001 .
223
.St -p1003.1-2001 .
224
The
225
.Fl n
226
option is a non-standard
227
.Fx
228
extension.
214
.Sh SEE ALSO
229
.Sh SEE ALSO
215
.Xr awk 1 ,
230
.Xr awk 1 ,
216
.Xr comm 1 ,
231
.Xr comm 1 ,

Return to bug 78562