00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00037
00038
00039
00040
00041
00042
00043
00044 #include "plabla.h"
00045
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 #include <string.h>
00049 #include <errno.h>
00050 #include PLABLA_INCLUDE_IO_UNISTD
00051
00052 #include "log.h"
00053 #include "format.h"
00054 #include "hlrmisc.h"
00055 #include "linestream.h"
00056
00057
00058 static char *nextLineFile (LineStream this1);
00059 static char *nextLinePipe (LineStream this1);
00060 static char *nextLineBuffer (LineStream this1);
00061 static void register_nextLine (LineStream this1,char *(*f)(LineStream this1));
00062
00063
00069 LineStream ls_createFromFile (char *fn)
00070 {
00071 LineStream this1;
00072
00073 if (!fn)
00074 die ("ls_createFromFile: no file name given");
00075 this1 = (LineStream) hlr_malloc (sizeof (struct _lineStreamStruct_));
00076 this1->line = NULL;
00077 this1->count = 0;
00078 this1->status = 0;
00079 if (strcmp (fn,"-") == 0)
00080 this1->fp = stdin;
00081 else
00082 this1->fp = fopen (fn,"r");
00083 if (!this1->fp) {
00084 warnAdd("ls_createFromFile",
00085 stringPrintBuf("'%s': %s", fn, strerror(errno))) ;
00086 hlr_free (this1);
00087 return NULL;
00088 }
00089 register_nextLine (this1,nextLineFile);
00090 this1->buffer = NULL ;
00091 return this1;
00092 }
00093
00094
00095
00103 static char *nextLineFile (LineStream this1)
00104 {
00105 int ll;
00106
00107 if (!this1)
00108 die ("nextLineFile: NULL LineStream");
00109 if (!(ll = getLine (this1->fp,&this1->line,&this1->lineLen))) {
00110 fclose (this1->fp);
00111 this1->fp = NULL;
00112 hlr_free (this1->line);
00113 return NULL;
00114 }
00115 if (ll > 1 && this1->line[ll-2] == '\r')
00116 this1->line[ll-2] = '\0';
00117 else if (ll > 0 && this1->line[ll-1] == '\n')
00118 this1->line[ll-1] = '\0';
00119 this1->count++;
00120 return this1->line;
00121 }
00122
00123
00124
00132 LineStream ls_createFromPipe (char *command)
00133 {
00134 LineStream this1;
00135
00136 if (!command)
00137 die ("ls_createFromPipe: no command given");
00138 this1 = (LineStream) hlr_malloc (sizeof (struct _lineStreamStruct_));
00139 this1->line = NULL;
00140 this1->count = 0;
00141 this1->status = -2;
00142 this1->fp = PLABLA_POPEN (command,"r");
00143 if (!this1->fp) {
00144 warnAdd("ls_createFromPipe",
00145 stringPrintBuf("'%s': %s", command, strerror(errno))) ;
00146 return NULL;
00147 }
00148 register_nextLine (this1,nextLinePipe);
00149 this1->buffer = NULL ;
00150 return this1;
00151 }
00152
00153
00154
00155 static char *nextLinePipe (LineStream this1)
00156 {
00157
00158
00159
00160
00161
00162
00163 int ll;
00164
00165 if (!this1)
00166 die ("nextLinePipe: NULL LineStream");
00167 if (!(ll = getLine (this1->fp,&this1->line,&this1->lineLen))) {
00168 this1->status = PLABLA_PCLOSE (this1->fp);
00169 this1->fp = NULL;
00170 hlr_free (this1->line);
00171 return NULL;
00172 }
00173 if (ll > 1 && this1->line[ll-2] == '\r')
00174 this1->line[ll-2] = '\0';
00175 else if (ll > 0 && this1->line[ll-1] == '\n')
00176 this1->line[ll-1] = '\0';
00177 this1->count++;
00178 return this1->line;
00179 }
00180
00181
00182
00190 LineStream ls_createFromBuffer (char *buffer)
00191 {
00192 LineStream this1;
00193 int len ;
00194 int manySepsAreOne = 0 ;
00195
00196 if (!buffer)
00197 die ("ls_createFromBuffer: NULL buffer");
00198 len = strlen(buffer) ;
00199 if (len) {
00200 if (buffer[len-1] == '\n')
00201 buffer[--len] = '\0' ;
00202 }
00203 else
00204 manySepsAreOne = 1 ;
00205
00206 this1 = (LineStream) hlr_malloc (sizeof (struct _lineStreamStruct_));
00207 this1->count = 0;
00208 this1->status = 0;
00209 this1->wi = wordIterCreate(buffer,"\n", manySepsAreOne);
00210 register_nextLine (this1,nextLineBuffer);
00211 this1->buffer = NULL ;
00212 return this1;
00213 }
00214
00215
00216
00217 static char *nextLineBuffer (LineStream this1)
00218 {
00219
00220
00221
00222
00223
00224
00225 char *s ;
00226 int len ;
00227
00228 if (!this1)
00229 die ("nextLineFile: NULL LineStream");
00230 s = wordNextG(this1->wi, &len) ;
00231 if (!s) {
00232 wordIterDestroy (this1->wi);
00233 return NULL;
00234 }
00235 this1->count++;
00236 if (len && s[len-1] == '\r')
00237 s[len-1] = '\0' ;
00238 return s;
00239 }
00240
00241
00242
00249 void ls_destroy_func (LineStream this1)
00250 {
00251 char line[1000];
00252
00253 if (!this1)
00254 return ;
00255
00256 if (this1->nextLine_hook == nextLinePipe && this1->fp) {
00257 while (fgets (line,sizeof (line),this1->fp)) {}
00258 this1->status = PLABLA_PCLOSE (this1->fp);
00259 hlr_free (this1->line);
00260 }
00261 else if (this1->nextLine_hook == nextLineFile && this1->fp) {
00262
00263 if (!PLABLA_ISATTY(fileno(this1->fp)))
00264 while (fgets (line,sizeof (line),this1->fp)) {}
00265 fclose (this1->fp);
00266 hlr_free (this1->line);
00267 }
00268 else if (this1->nextLine_hook == nextLineBuffer && this1->wi) {
00269 wordIterDestroy (this1->wi);
00270 }
00271 stringDestroy(this1->buffer) ;
00272 hlr_free (this1);
00273 }
00274
00275
00276
00277
00278 static void register_nextLine (LineStream this1,char *(*f)(LineStream this1))
00279 {
00280
00281
00282 this1->nextLine_hook = f;
00283 }
00284
00285
00286
00295 char *ls_nextLine (LineStream this1)
00296 {
00297 char *line ;
00298 if (!this1)
00299 die("%s", warnCount(NULL,NULL) ? warnReport() : "ls_nextLine: invalid LineStream") ;
00300 if (this1->buffer) {
00301 if (this1->bufferBack) {
00302 this1->bufferBack = 0 ;
00303 line = this1->bufferLine ;
00304 }
00305 else {
00306
00307
00308 line = this1->bufferLine ? this1->nextLine_hook (this1) : NULL ;
00309 if (line) {
00310 stringCpy(this1->buffer, line) ;
00311 this1->bufferLine = string(this1->buffer) ;
00312 }
00313 else
00314 this1->bufferLine = NULL ;
00315 }
00316 }
00317 else
00318 line = this1->nextLine_hook (this1) ;
00319 return line ;
00320 }
00321
00322
00323
00331 void ls_back(LineStream this1, int lineCnt)
00332 {
00333 if (! this1->buffer)
00334 die("ls_back() without preceeding ls_bufferSet()") ;
00335 if (this1->bufferBack)
00336 die("ls_back() twice in a row") ;
00337 if (lineCnt != 1)
00338 die("ls_back: sorry, not yet implemented") ;
00339 this1->bufferBack = 1 ;
00340 }
00341
00342
00343
00351 void ls_bufferSet(LineStream this1, int lineCnt)
00352 {
00353 if (this1->buffer || this1->count)
00354 die("ls_bufferSet() more than once or too late") ;
00355 if (lineCnt != 1)
00356 die("ls_bufferSet() sorry, not yet implemented") ;
00357 this1->buffer = stringCreate(80) ;
00358 this1->bufferBack = 0 ;
00359 this1->bufferLine = "" ;
00360 }
00361
00362
00363
00368 int ls_lineCountGet (LineStream this1)
00369 {
00370 return this1->count;
00371 }
00372
00373
00374
00384 int ls_skipStatusGet(LineStream this1)
00385 {
00386 if (this1->nextLine_hook == nextLineBuffer) {
00387 if (this1->wi)
00388 wordIterDestroy(this1->wi);
00389 }
00390 else if (this1->nextLine_hook == nextLineFile) {
00391 if (this1->fp) {
00392 fclose (this1->fp);
00393 this1->fp = NULL;
00394 hlr_free (this1->line);
00395 }
00396 }
00397 else if (this1->nextLine_hook == nextLinePipe) {
00398 if (this1->fp)
00399 while(nextLinePipe(this1))
00400 ;
00401 }
00402
00403 return this1->status ;
00404 }
00405
00406
00407
00414 void ls_cat(LineStream this1, char *filename)
00415 {
00416 if (filename) {
00417 char *line ;
00418 FILE *f ;
00419 if (strEqual(filename, "-"))
00420 f = stdout ;
00421 else
00422 f = fopen(filename, "w") ;
00423 if (!f) {
00424 die("%s: in ls_cat(%s)", strerror(errno), filename) ;
00425 }
00426 while (line = ls_nextLine(this1)) {
00427 fputs(line, f) ;
00428 putc('\n', f) ;
00429 }
00430 if (f != stdout)
00431 fclose(f) ;
00432 }
00433 else
00434 while (ls_nextLine(this1)) ;
00435 }
00436
00437
00438
00445 int ls_isEof(LineStream this1)
00446 {
00447 if (this1->nextLine_hook == nextLineBuffer)
00448 return this1->wi == NULL ? 1 : 0 ;
00449 else
00450 return this1->fp == NULL ? 1 : 0 ;
00451 }