da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1992-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * join
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner"[-?\n@(#)$Id: join (AT&T Research) 2009-12-10 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?join - relational database operator]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bjoin\b performs an \aequality join\a on the files \afile1\a "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "and \afile2\a and writes the resulting joined files to standard "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "output. By default, a field is delimited by one or more spaces "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "and tabs with leading spaces and/or tabs ignored. The \b-t\b option "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "can be used to change the field delimiter.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The \ajoin field\a is a field in each file on which files are compared. "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "By default \bjoin\b writes one line in the output for each pair "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "of lines in \afiles1\a and \afiles2\a that have identical join "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "fields. The default output line consists of the join field, "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "then the remaining fields from \afile1\a, then the remaining "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "fields from \afile2\a, but this can be changed with the \b-o\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "option. The \b-a\b option can be used to add unmatched lines "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "to the output. The \b-v\b option can be used to output only "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "unmatched lines.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The files \afile1\a and \afile2\a must be ordered in the collating "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "sequence of \bsort -b\b on the fields on which they are to be "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "joined otherwise the results are unspecified.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?If either \afile1\a or \afile2\a is \b-\b, \bjoin\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "uses standard input starting at the current location.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[e:empty]:[string?Replace empty output fields in the list selected with"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \b-o\b with \astring\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[o:output]:[list?Construct the output line to comprise the fields specified "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "in a blank or comma separated list \alist\a. Each element in "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\alist\a consists of a file number (either 1 or 2), a period, "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "and a field number or \b0\b representing the join field. "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "As an obsolete feature multiple occurrences of \b-o\b can "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "be specified.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[t:separator|tabs]:[delim?Use \adelim\a as the field separator for both input"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" and output.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[1:j1]#[field?Join on field \afield\a of \afile1\a. Fields start at 1.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[2:j2]#[field?Join on field \afield\a of \afile2\a. Fields start at 1.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[j:join]#[field?Equivalent to \b-1\b \afield\a \b-2\b \afield\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[a:unpairable]#[fileno?Write a line for each unpairable line in file"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \afileno\a, where \afileno\a is either 1 or 2, in addition to the"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" normal output. If \b-a\b options appear for both 1 and 2, then "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "all unpairable lines will be output.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[v:suppress]#[fileno?Write a line for each unpairable line in file"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \afileno\a, where \afileno\a is either 1 or 2, instead of the normal "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "output. If \b-v\b options appear for both 1 and 2, then "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "all unpairable lines will be output.] ]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[i:ignorecase?Ignore case in field comparisons.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[B!:mmap?Enable memory mapped reads instead of buffered.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The following obsolete option forms are also recognized: \b-j\b \afield\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" is equivalent to \b-1\b \afield\a \b-2\b \afield\a, \b-j1\b \afield\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" is equivalent to \b-1\b \afield\a, and \b-j2\b \afield\a is"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" equivalent to \b-2\b \afield\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\nfile1 file2\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXIT STATUS?]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+0?Both files processed successfully.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+>0?An error occurred.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bcut\b(1), \bcomm\b(1), \bpaste\b(1), \bsort\b(1), \buniq\b(1)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cmd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sfdisc.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#if _hdr_wchar && _hdr_wctype && _lib_iswctype
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#include <wchar.h>
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#include <wctype.h>
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#include <ctype.h>
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#ifndef iswspace
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#define iswspace(x) isspace(x)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#endif
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#endif
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_FILE1 001
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_FILE2 002
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_COMMON 004
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_ALL (C_FILE1|C_FILE2|C_COMMON)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NFIELD 10
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define JOINFIELD 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define S_DELIM 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define S_SPACE 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define S_NL 3
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#define S_WIDE 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknertypedef struct Field_s
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char* beg;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char* end;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner} Field_t;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknertypedef struct File_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* recptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int reclen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int field;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nfields;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int maxfields;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int spaces;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int hit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int discard;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner Field_t* fields;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} File_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknertypedef struct Join_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char state[1<<CHAR_BIT];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* outfile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* outlist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int outmode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ooutmode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* nullfield;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char* delimstr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int delim;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner int delimlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int buffered;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ignorecase;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner int mb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* same;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int samesize;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void* context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin File_t file[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Join_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone(register Join_t* jp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp->file[0].iop && jp->file[0].iop != sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(jp->file[0].iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp->file[1].iop && jp->file[1].iop != sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(jp->file[1].iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp->outlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(jp->outlist);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->file[0].fields)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner free(jp->file[0].fields);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->file[1].fields)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner free(jp->file[1].fields);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp->same)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(jp->same);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Join_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininit(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Join_t* jp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner setlocale(LC_ALL, "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp = newof(0, Join_t, 1, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->mb = mbwide())
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (i = 0x80; i <= 0xff; i++)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner jp->state[i] = S_WIDE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->state[' '] = jp->state['\t'] = S_SPACE;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner jp->state['\n'] = S_NL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->delim = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->nullfield = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!(jp->file[0].fields = newof(0, Field_t, NFIELD + 1, 0)) ||
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner !(jp->file[1].fields = newof(0, Field_t, NFIELD + 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[0].maxfields = NFIELD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[1].maxfields = NFIELD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outmode = C_COMMON;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return jp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetolist(Join_t* jp, const char* first, char** arglist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* cp = first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char** argv = arglist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* outptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* outmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nfield = NFIELD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outptr = jp->outlist = newof(0, int, NFIELD + 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outmax = outptr + NFIELD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c==' ' || c=='\t' || c==',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = (char*)--cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp=='0' && ((c=cp[1])==0 || c==' ' || c=='\t' || c==','))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = JOINFIELD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp[1]!='.' || (*cp!='1' && *cp!='2') || (c=strtol(cp+2,&str,10)) <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2,"%s: invalid field list",first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c <<=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp=='2')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (outptr >= outmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outlist = newof(jp->outlist, int, 2 * nfield + 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outptr = jp->outlist + nfield;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nfield *= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outmax = jp->outlist + nfield;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *outptr++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* need to accept obsolescent command syntax */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp= *argv) || cp[1]!='.' || (*cp!='1' && *cp!='2'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp=='0' && cp[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = JOINFIELD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = (char*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = strtol(cp+2, &str,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*str || --c<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c <<= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp=='2')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (outptr >= outmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outlist = newof(jp->outlist, int, 2 * nfield + 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outptr = jp->outlist + nfield;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nfield *= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outmax = jp->outlist + nfield;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *outptr++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *outptr = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return argv-arglist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read in a record from file <index> and split into fields
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetrec(Join_t* jp, int index, int discard)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* sp = jp->state;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register File_t* fp = &jp->file[index];
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register Field_t* field = fp->fields;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register Field_t* fieldmax = field + fp->maxfields;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register int n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (sh_checksig(jp->context))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (discard && fp->discard)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfraise(fp->iop, SFSK_DISCARD, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->spaces = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->hit = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp = sfgetr(fp->iop, '\n', 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outmode &= ~(1<<index);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->recptr = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->reclen = sfvalue(fp->iop);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->delim == '\n') /* handle new-line delimiter specially */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field->beg = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += fp->reclen;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field->end = cp - 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner do /* separate into fields */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (field >= fieldmax)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner n = 2 * fp->maxfields;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fp->fields = newof(fp->fields, Field_t, n + 1, 0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field = fp->fields + fp->maxfields;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fp->maxfields = n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fieldmax = fp->fields + n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field->beg = cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->delim == -1)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner switch (sp[*(unsigned char*)cp])
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_SPACE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_WIDE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner tp = cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (iswspace(mbchar(tp)))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = tp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner /*FALLTHROUGH*/
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner default:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner goto next;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fp->spaces = 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (;;)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner switch (sp[*(unsigned char*)cp++])
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_SPACE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_WIDE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner tp = cp - 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (iswspace(mbchar(tp)))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = tp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (sp[*(unsigned char*)cp++]==S_SPACE);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp--;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner next:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (;;)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner tp = cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner switch (n = sp[*(unsigned char*)cp++])
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case 0:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_WIDE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp--;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner n = mbchar(cp);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (n == jp->delim)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner n = S_DELIM;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->delim == -1 && iswspace(n))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner n = S_SPACE;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field->end = tp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (!(n = sp[*(unsigned char*)cp++]));
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field->end = cp - 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner field++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner } while (n != S_NL);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fp->nfields = field - fp->fields;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((n = fp->field) < fp->nfields)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = fp->fields[n].beg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* eliminate leading spaces */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->spaces)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (;;)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner switch (sp[*(unsigned char*)cp++])
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_SPACE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_WIDE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner tp = cp - 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (iswspace(mbchar(tp)))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = tp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (sp[*(unsigned char*)cp++]==S_SPACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fp->fieldlen = fp->fields[n].end - cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (unsigned char*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->fieldlen = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (unsigned char*)"";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerstatic unsigned char*
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner_trace_getrec(Join_t* jp, int index, int discard)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner unsigned char* r;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner r = getrec(jp, index, discard);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return r;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner}
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#define getrec _trace_getrec
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned char* u1,u2,u3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define getrec(p,n,d) (u1 = getrec(p, n, d), sfprintf(sfstdout, "[G%d#%d@%I*d:%-.8s]", __LINE__, n, sizeof(Sfoff_t), sftell(p->file[n].iop), u1), u1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print field <n> from file <index>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoutfield(Join_t* jp, int index, register int n, int last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register File_t* fp = &jp->file[index];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cpmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t* iop = jp->outfile;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < fp->nfields)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = fp->fields[n].beg;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cpmax = fp->fields[n].end + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((n = jp->delim) == -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (cp && fp->spaces)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register unsigned char* sp = jp->state;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*eliminate leading spaces */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (;;)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner switch (sp[*(unsigned char*)cp++])
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_SPACE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case S_WIDE:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner tp = cp - 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (iswspace(mbchar(tp)))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = tp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (sp[*(unsigned char*)cp++]==S_SPACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (jp->delimstr)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner n = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner size = cpmax - cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (n == -1)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (size<=1)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->nullfield && sfputr(iop, jp->nullfield, -1) < 0)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (sfwrite(iop, cp, size) < 0)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (sfwrite(iop, jp->delimstr, jp->delimlen) < 0)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (size <= 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!jp->nullfield)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sfputc(iop, n);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (sfputr(iop, jp->nullfield, n) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = cp[size-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[size-1] = n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (sfwrite(iop, cp, size) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[size-1] = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int i1,i2,i3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define outfield(p,i,n,f) (sfprintf(sfstdout, "[F%d#%d:%d,%d]", __LINE__, i1=i, i2=n, i3=f), outfield(p, i1, i2, i3))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoutrec(register Join_t* jp, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register File_t* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mode < 0 && jp->file[0].hit++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mode > 0 && jp->file[1].hit++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (out = jp->outlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n = *out++) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == JOINFIELD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = mode >= 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = jp->file[i].field;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = n & 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = (mode<0 && i || mode>0 && !i) ?
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[i].nfields :
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n >> 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (outfield(jp, i, j, *out < 0) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = jp->file[0].nfields;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mode >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k += jp->file[1].nfields - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i=0; i<2; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = &jp->file[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mode>0 && i==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k -= (fp->nfields - 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = fp->field;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mode||i==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* output join field first */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (outfield(jp,i,n,!--k) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!k)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (j=0; j<n; j++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (outfield(jp,i,j,!--k) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!k)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = n + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;j<fp->nfields; j++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (j!=n && outfield(jp,i,j,!--k) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!k)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define outrec(p,n) (sfprintf(sfstdout, "[R#%d,%d,%lld,%lld:%-.*s{%d}:%-.*s{%d}]", __LINE__, i1=n, lo, hi, jp->file[0].fieldlen, cp1, jp->file[0].hit, jp->file[1].fieldlen, cp2, jp->file[1].hit), outrec(p, i1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinjoin(Join_t* jp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* cp1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* cp2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int cmp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int same;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int o2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t lo = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t hi = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((cp1 = getrec(jp, 0, 0)) && (cp2 = getrec(jp, 1, 0)) || (cp2 = 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = jp->file[0].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = jp->file[1].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin same = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = n1 < n2 ? n1 : n2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!n && !(cmp = n1 < n2 ? -1 : (n1 > n2)) || n && !(cmp = (int)*cp1 - (int)*cp2) && !(cmp = jp->ignorecase ? strncasecmp((char*)cp1, (char*)cp2, n) : memcmp(cp1, cp2, n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmp = n1 - n2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstdout, "[C#%d:%d(%c-%c),%d,%lld,%lld%s]", __LINE__, cmp, *cp1, *cp2, same, lo, hi, (jp->outmode & C_COMMON) ? ",COMMON" : "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cmp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!n && !(cmp = n1 < n2 ? -1 : (n1 > n2)) || n && !(cmp = (int)*cp1 - (int)*cp2) && !(cmp = jp->ignorecase ? strncasecmp((char*)cp1, (char*)cp2, n) : memcmp(cp1, cp2, n)) && !(cmp = n1 - n2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(jp->outmode & C_COMMON))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp1 = getrec(jp, 0, 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = jp->file[0].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin same = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((jp->ooutmode & (C_FILE1|C_FILE2)) != C_FILE2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfseek(jp->file[0].iop, (Sfoff_t)-jp->file[0].reclen, SEEK_CUR) < 0 || !(cp1 = getrec(jp, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|2, "%s: seek error", jp->file[0].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (outrec(jp, 0) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (lo < 0 && (jp->outmode & C_COMMON))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((lo = sfseek(jp->file[1].iop, (Sfoff_t)0, SEEK_CUR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|2, "%s: seek error", jp->file[1].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lo -= jp->file[1].reclen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp2 = getrec(jp, 1, lo < 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = jp->file[1].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstdout, "[2#%d:0,%lld,%lld]", __LINE__, lo, hi);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (cmp > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (same)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin same = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n2 > jp->samesize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->samesize = roundof(n2, 16);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(jp->same = newof(jp->same, char, jp->samesize, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|2, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(jp->same, cp2, o2 = n2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp2 = getrec(jp, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = jp->file[1].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n2 == o2 && *cp2 == *jp->same && !memcmp(cp2, jp->same, n2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (hi >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfseek(jp->file[1].iop, hi, SEEK_SET) != hi)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|2, "%s: seek error", jp->file[1].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hi = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((jp->outmode & C_FILE2) && outrec(jp, 1) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lo = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp2 = getrec(jp, 1, 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = jp->file[1].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstdout, "[2#%d:0,%lld,%lld]", __LINE__, lo, hi);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (same)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin same = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp1 = getrec(jp, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = jp->file[0].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (lo >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((hi = sfseek(jp->file[1].iop, (Sfoff_t)0, SEEK_CUR)) < 0 ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (hi -= jp->file[1].reclen) < 0 ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(jp->file[1].iop, lo, SEEK_SET) != lo ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin !(cp2 = getrec(jp, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|2, "%s: seek error", jp->file[1].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = jp->file[1].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lo = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp->file[1].discard)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(jp->file[1].iop, (Sfoff_t)-1, SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!cp2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((jp->outmode & C_FILE1) && outrec(jp, -1) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp1 = getrec(jp, 0, 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = jp->file[0].fieldlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstdout, "[X#%d:?,%p,%p,%d%,%d,%d%s]", __LINE__, cp1, cp2, cmp, lo, hi, (jp->outmode & C_COMMON) ? ",COMMON" : "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (hi >= 0 &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(jp->file[1].iop, (Sfoff_t)0, SEEK_CUR) < hi &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(jp->file[1].iop, hi, SEEK_SET) != hi)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_SYSTEM|2, "%s: seek error", jp->file[1].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstdout, "[O#%d:%02o:%02o]", __LINE__, jp->ooutmode, jp->outmode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp1 = (!cp1 && cmp && hi < 0 && !jp->file[1].hit && ((jp->ooutmode ^ C_ALL) <= 1 || jp->outmode == 2)) ? cp2 : getrec(jp, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmp = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmp = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstdout, "[X#%d:%d,%p,%p,%d,%02o,%02o%s]", __LINE__, n, cp1, cp2, cmp, jp->ooutmode, jp->outmode, (jp->outmode & C_COMMON) ? ",COMMON" : "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cp1 || !(jp->outmode & (1<<n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp1 && jp->file[n].iop == sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(sfstdin, (Sfoff_t)0, SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (outrec(jp, cmp) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!getrec(jp, n, 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (outrec(jp, cmp) >= 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinb_join(int argc, char** argv, void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Join_t* jp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(jp = init()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1),"out of space");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin jp->context = context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (n = optget(argv, usage))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'j':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for obsolete "-j1 field" and "-j2 field"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.offset == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = argv[opt_info.index - 1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = strlen(cp) - 1; n > 0 && cp[n] != 'j'; n--);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = cp[n] == 'j';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.num!=1 && opt_info.num!=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2,"-jfileno field: fileno must be 1 or 2");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = '0' + opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp = argv[opt_info.index]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.num = strtol(cp, &e, 10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[0].field = (int)(opt_info.num-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = '2';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '1':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '2':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.num <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2,"field number must positive");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[n-'1'].field = (int)(opt_info.num-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outmode &= ~C_COMMON;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.num!=1 && opt_info.num!=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2,"%s: file number must be 1 or 2", opt_info.name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outmode |= 1<<(opt_info.num-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->nullfield = opt_info.arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* need to accept obsolescent command syntax */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = getolist(jp, opt_info.arg, argv+opt_info.index);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 't':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->state[' '] = jp->state['\t'] = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (jp->mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = opt_info.arg;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner jp->delim = mbchar(cp);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((n = cp - opt_info.arg) > 1)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner jp->delimlen = n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner jp->delimstr = opt_info.arg;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner n = *(unsigned char*)opt_info.arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->state[n] = S_DELIM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->delim = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->ignorecase = !opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->buffered = !opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -= opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.errors || argc!=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2),"%s", optusage(NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->ooutmode = jp->outmode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[0].name = cp = *argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(cp,"-"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfseek(sfstdin,(Sfoff_t)0,SEEK_CUR) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfdcseekable(sfstdin))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_warn(0),"%s: seek may fail",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[0].discard = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[0].iop = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(jp->file[0].iop = sfopen(NiL, cp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1),"%s: cannot open",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[1].name = cp = *argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(cp,"-"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfseek(sfstdin,(Sfoff_t)0,SEEK_CUR) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfdcseekable(sfstdin))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_warn(0),"%s: seek may fail",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[1].discard = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->file[1].iop = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(jp->file[1].iop = sfopen(NiL, cp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1),"%s: cannot open",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (jp->buffered)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetbuf(jp->file[0].iop, jp->file[0].iop, SF_UNBOUND);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfsetbuf(jp->file[1].iop, jp->file[1].iop, SF_UNBOUND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->outfile = sfstdout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!jp->outlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jp->nullfield = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (join(jp) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1),"write error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (jp->file[0].iop==sfstdin || jp->file[1].iop==sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(sfstdin,(Sfoff_t)0,SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done(jp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return error_info.errors;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}