-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheader.c
More file actions
137 lines (125 loc) · 5.05 KB
/
Copy pathheader.c
File metadata and controls
137 lines (125 loc) · 5.05 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* header.c
* Chris Blades
* February 4, 2011
*
* Parses a PPM header and prints out version number, width, height, and maximum
* value for color components.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include "header.h"
#define DEFAULT_STRING_SIZE 256
#define DELIMITERS " \t\n\r\v\f"
#define NUM_PPM_NUMS 3
#define TRUE 1
#define FALSE 0
/**
* Parses a PPM header and prints out version magic number and 3 numbers.
* PPM headers are in the format:
* <magic number>
* <whitespace>
* <number>
* <whitespace>
* <number>
* <whitespace>
* <number>
* where <magic num> is in the format [pP][0-9].
*
* Comments are also allowed. Comments begin with '#' and continue until the
* end of the line.
*
* PARAMETERS
* in - file pointer to header
* header - struct to store header info in
*/
void readHeader(FILE *in, ppm_header *header) {
// whether magic num has been compiled already or not, necessary because
// magicPattern is static
static int regexCompiled = FALSE;
// compiled regex pattern to match version magic number
static regex_t magicPattern;
int numsFound = 0; // number of nums found
int currNum; // current number found
regmatch_t matches; // match of magicPattern
char *token; // current token in line
char line[DEFAULT_STRING_SIZE]; // current line
int inComment; // whether current token
// is in a comment
int foundVersion; // if version num has been
// found already
// if magic num regex hasn't already been compiled, compile it
if (!regexCompiled) {
regcomp(&magicPattern, "[pP][123456]", REG_EXTENDED);
}
// if input file couldn't be opened, return
if (in == NULL) {
return;
}
foundVersion = FALSE;
// read from file, line by line, and parse each line for version, comments,
// or numbers
while (fgets(line, DEFAULT_STRING_SIZE, in) != NULL
&& numsFound < NUM_PPM_NUMS) {
inComment = FALSE;
token = strtok(line, DELIMITERS);
if (token != NULL) {
do {
// if this token starts a comment, set flag...
if (token[0] == '#') {
inComment = TRUE;
}
// only check for version or numbers if not in a comment
if (!inComment) {
// check for version magic num
if (regexec(&magicPattern, token, 1, &matches, 0) == 0) {
// print version number...
if (!foundVersion) {
sscanf(token, "%*c%d", &header->version);
foundVersion = TRUE;
// ...unless version num has already been found, in
// which case print error message and return
} else {
printf("\nHeader contains incorrrect formating: "
"specifies version more than once.\n"
"Program will quit parsing header.\n");
return;
}
// check for number
} else if (sscanf(token, "%d", &currNum) > 0) {
if (numsFound < NUM_PPM_NUMS) {
switch (numsFound) {
case 0:
header->width = currNum;
break;
case 1:
header->height = currNum;
break;
case 2:
header->maxValue = currNum;
break;
}
numsFound++;
} else {
printf("\nHeader has extra data.\n");
}
// else, header is formatted incorrectly, print error
} else {
printf("Header contains incorrect formatting "
"on line: \"%s\".\n"
"Program will quit parsing header.\n",
line);
return;
}
}
} while (numsFound < NUM_PPM_NUMS &&
(token = strtok(NULL, DELIMITERS)) != NULL);
if (numsFound >= NUM_PPM_NUMS) {
break;
}
}
}
}