File: wcgetline.c

package info (click to toggle)
libuninum 2.7-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,204 kB
  • sloc: ansic: 9,968; sh: 8,721; tcl: 553; makefile: 27
file content (102 lines) | stat: -rw-r--r-- 2,720 bytes parent folder | download | duplicates (4)
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
97
98
99
100
101
102
#include "config.h"
#include "unicode.h"
#include <stdlib.h>
#include <stdio.h>
#include "utf8error.h"
/* 
 * Read a line of arbitrary length from a stream.
 *
 * Return a pointer to the null-terminated string allocated, or null on failure
 * to allocate sufficient storage.
 * It is the responsibility of the caller to free the space allocated.
 *
 * The length of the line is placed in the variable pointed to by
 * the second argument. (-1) is placed in this variable on EOF.
 * A value of zero indicates that an empty line was read.
 */

#define INITLENGTH 32
#define MSGSIZE 128

static char msg [MSGSIZE];

int
ReportReadError(
	FILE *fp,
	UTF32 c, 		/* Error code */
	unsigned char *rp,	/* Pointer to raw input sequence */
	unsigned long RecordNumber,
	unsigned long ByteCnt)
{

  extern void ExplicateBadUTF8(FILE *, unsigned char *);

  switch (c)
    { 
    case UTF8_NOTENOUGHBYTES:
      fprintf(fp,"Truncated UTF-8 sequence encountered at record %ld, byte %ld.\n",
	      RecordNumber, ByteCnt);
      exit(1);
      break;
    case UTF8_BADINCODE:
      fprintf(fp,"Invalid UTF-8 code encountered at record %ld, byte %ld.\n",
	      RecordNumber, ByteCnt);
      ExplicateBadUTF8(fp,rp);
      exit(1);
      break;
    case UTF8_BADOUTCODE:
      fprintf(fp,"Encountered invalid Unicode at record %ld, byte %ld.\n",
	      RecordNumber, ByteCnt);
      exit(1);
      break;
    case UTF8_IOERROR:
      snprintf(msg,MSGSIZE-1,"Error reading input at record %ld, byte %ld.\n",
	       RecordNumber,ByteCnt);
      perror(msg);
      exit(1);
      break;
    default:			/* Normal EOF */
      return(0);
      break;			/* NOTREACHED */
    }
}

UTF32 * wcgetline(FILE *fp, int *LineLength,unsigned long LineNumber)
{
  UTF32 c;
  int Available;
  int CharsRead;
  UTF32 *Line;
  int BytesRead;
  unsigned char *rawptr;

  extern UTF32 UTF8in (int,int *,unsigned char **);

  Available = INITLENGTH;
  CharsRead=0;
  BytesRead=0;  
  Line = (UTF32 *) malloc(sizeof(UTF32) * (size_t)Available);
  if(Line == NULL) return (Line);

  while ((c = UTF8in(fileno(fp),&BytesRead,&rawptr)) < UNI_MAX_UTF32) {
    if(c == 0x000A) {
      Line[CharsRead]= 0L;
      *LineLength=CharsRead;
      return(Line);
    }
    BytesRead++;
    if(CharsRead == (Available-1)){ /* -1 because of null */
      Available += INITLENGTH/2;
      Line = (UTF32 *) realloc( (void *) Line, (size_t) (Available * sizeof (UTF32)));
      if(Line == NULL) return(Line);
    }
    Line[CharsRead++]=c;
  }
  if(c == UTF8_ENDOFFILE){
    Line[CharsRead]= 0L;
      if(BytesRead == 0) *LineLength = (-1); /* Signal EOF */
      else *LineLength=CharsRead;
      return(Line);
  }
  ReportReadError(stderr,c,rawptr,LineNumber,BytesRead);
}