int list_names_append_if_new(struct list_names *list, const char *name) { verify(list != NULL, "null arg list"); verify(name != NULL, "null arg name"); verify(name[0] != '\0', "empty arg name"); for (struct name * p = list->head; p != NULL; p = p->next) { if (strcmp(p->name, name) == 0) return 1; // name is on the list already } list_names_append(list, name); return 0; }
void list_names_append_from_file(struct list_names *list, const char *filename) { verify(list != NULL, "null arg list"); verify(filename != NULL, "null arg filename"); verify(filename[0] != '\0', "empty arg filename"); FILE *infile; if (strcmp(filename, "-") == 0) { infile = stdin; } else { infile = fopen(filename, "r"); if (infile == NULL) { fprintf(stderr, "%s: failed: could not open file %s: %s\n", prog, filename, strerror(errno)); exit(EXIT_FAILURE); } } char buffer[256]; char whsp[] = " \t\v\n\f\r"; // whitespace characters char *p; while (fgets(buffer, sizeof(buffer), infile) != NULL) { /* Note that buffer has a newline at the end if the input line * was short enough to fit. Line-too-long is probably an error, * to be caught later. * NULL from fgets() indicates end-of-file or error, so we just quit. */ p = strchr(buffer, '\n'); // points to the newline character, if there is one if (p != NULL) { *p = '\0'; list_names_append(list, "\n");} // remove the newline if(!verbose) { p = strchr(buffer, '#'); // a comment starts with # if (p != NULL) { *p = '\0'; } // remove the comment } int m = strspn(buffer, whsp); // index of first non-whitespace character // remove trailing whitespace int n = 0; while (buffer[n] != '\0') { int n1 = strspn(&buffer[n], whsp); // buffer[n .. n+n1-1] is whitespace int n2 = strcspn(&buffer[n + n1], whsp); // buffer[n+n1 .. n+n1+n2-1] is not if (n2 == 0) { buffer[n] = '\0'; break; } // remove trailing whitespace n += n1 + n2; } if (buffer[m] == '\0') continue; // empty line list_names_append(list, &buffer[m]); } if (infile != stdin && fclose(infile) != 0) { fprintf(stderr, "%s: failed: could not close input file %s: %s\n", prog, filename, strerror(errno)); exit(EXIT_FAILURE); } }
int main(int argc, char *argv[]) { // for use with getopt(3) int ch; extern char *optarg; extern int optind; extern int optopt; extern int opterr; char *inputfile; int line = 0; // option flags and option-arguments set from the command line prog = argv[0]; int status = EXIT_SUCCESS; int f_flag = 0; // number of -f options supplied // first, see if the -v option is given // we'll catch all the other cases on the next pass over argv while ((ch = getopt(argc, argv, ":hva:f:")) != -1) { if (ch == 'v') verbose = 1; } struct list_names filenames; struct list_names line_messages; struct list_names read_filenames; list_names_init(&read_filenames, "read_filenames"); list_names_init(&line_messages, "line_messages"); list_names_init(&filenames, "filenames"); // scan the argv array again, from the beginning optind = 1; while ((ch = getopt(argc, argv, ":hva:f:")) != -1) { switch (ch) { case 'h': usage(EXIT_SUCCESS); break; case 'v': verbose += 1; break; case 'f': f_flag++; // number of -f options supplied inputfile = optarg; list_names_append(&filenames, optarg); break; case '?': fprintf(stderr, "%s: invalid option '%c'\n", prog, optopt); usage(EXIT_FAILURE); break; case ':': fprintf(stderr, "%s: invalid option '%c'\n", prog, optopt); usage(EXIT_FAILURE); break; default: fprintf(stderr, "%s: invalid option '%c'\n", prog, ch); usage(EXIT_FAILURE); break; } } //printf("check here! >> filenames.name: %s\n", inputfile); list_names_append_from_file(&line_messages, filenames.head->name); struct name* p = line_messages.head; struct name* f = filenames.head; //_----------------------------------------------------------------------------------------- // start of option -f if(f_flag > 0 && verbose==0) { while(p != NULL) { char *s = Malloc(sizeof(char)); s = p->name; // current line message in the list int pos = strspn(s, "include"); // current file name position in the line message int quiet = 0; // 0: enable error message, 1: surppress error message int size = strlen(s); // size of the current name if(strcmp(s,"\n")==0) // update number of line { line++; } if((strcmp(s,"include")==0)) { // no file is detected. } else if(strncmp(s, "include", 7) == 0) // read inlude { while(s[pos]==' '||s[pos]=='\t') // ignore all space between include and filenames { pos++; } if((s[pos]=='\'' || s[pos]=='\"') && (s[size-1] != s[pos])) { fprintf(stderr, "%s: %s: line %d: file name error: >>>%s<<<\n", prog, inputfile, line, s+pos); } else { if((s[pos] == '\''||s[pos]=='\"')&&s[size-1]==s[pos]) { pos++; s[size-1] = '\0'; } // check if found a same name in the f for(struct name *q = read_filenames.head; q != NULL; q = q-> next) { if(strcmp(q->name,s+pos)==0) { quiet = 1; //printf("check!! >> quiet: %d >> %s == %s\n", quiet, q->name, s+pos); } } if(read_file(s+pos,quiet)==1) { list_names_append(&filenames, s+pos); list_names_append(&read_filenames, s+pos); } else { list_names_append(&read_filenames, s+pos); } } } // point to next line message p=p->next; } } // end of option -f // ------------------------------------------------------------------------------------------------ // start of option -v -f if(f_flag > 0 && verbose >1) { fprintf(stdout,"%s: read_file(%s)\n", prog, f->name); list_names_print(&filenames); fprintf(stdout,"%s: read_lines(%s)\n", prog, f->name); printf("%s", p->name); while(p != NULL) { char *s = Malloc(sizeof(char)); unsigned int size = strlen(s); s = p->name; int quiet = 0; // 0: enable error message, 1: surppress error message unsigned int pos = strspn(s, "include"); if(strcmp(s,"\n")==0) // update number of line { line++; } else { fprintf(stdout, "%s: %s: line: %d: %s\n", prog, f->name, line, s); if(strspn(s,"include")<=7) { fprintf(stdout, ">>> include\n"); } pos++; if(s[pos]==' '|| s[pos]=='\t') { pos++; } s = s+pos; for(;pos<strlen(s);pos++) { if(s[pos] == ' '||s[pos] == '\t') { s[pos] = '\0'; } } size = strlen(s); if((s[0]=='\''||s[0]=='\"')&&s[0]==s[size-1]) { s = s++; s[size-1] = '\0'; } //----------------------------------------------------------------------------------------------- // got the name already if(s == NULL) { fprintf(stdout, "%s: %s: line: %d: no input file\n", prog, f->name, line); } else if((s[0]=='\'' || s[0]=='\"') && (s[size-1] != s[0])) { fprintf(stderr, "%s: %s: line %d: file name error: >>>%s<<<\n", prog, inputfile, line, s); } else { // check if found a same name in the f for(struct name *q = read_filenames.head; q != NULL; q = q-> next) { if(strcmp(q->name,s)==0) { quiet = 1; printf("check!! >> quiet: %d >> %s == %s\n", quiet, q->name, s); } } if(read_file(s,quiet)==1) { list_names_append(&filenames, s); list_names_append(&read_filenames, s); } else { list_names_append(&read_filenames, s); } } } p = p->next; } } // end of option -v -f //----------------------------------------------------------------------------------------------- printf("end check!\n"); return status; }
void list_names_append_from_file(struct list_names * const list, const char *filename) { verify(list != NULL, "null arg list"); verify(filename != NULL, "null arg filename"); verify(filename[0] != '\0', "empty arg filename"); FILE *infile = NULL; if (strcmp(filename, "-") == 0) { infile = stdin; } else { infile = fopen(filename, "r"); if (infile == NULL) { fprintf(stderr, "%s: failed: could not open file %s: %s\n", prog, filename, strerror(errno)); exit(EXIT_FAILURE); } } #define MAXLINE 256 char buffer[MAXLINE+2]; // extra space for newline buffer[MAXLINE+2-2] = '\n'; // force a newline buffer[MAXLINE+2-1] = '\0'; // to end the string char whsp[] = " \t\n\v\f\r"; // whitespace characters char comm[] = "#\n"; // comment, newline while (fgets(buffer, MAXLINE, infile) != NULL) { /* Note that fgets() places a newline in buffer, if the input line * was short enough to fit. Line-too-long is probably an error, * to be caught later. We work around the rare case by forcing a * newline and not overwriting it. * NULL from fgets() indicates end-of-file or error, so in that case * we just quit. */ // remove comment, if present // remove trailing newline int m = strcspn(buffer, comm); // index of # or newline buffer[m] = '\0'; // remove the tail m = strspn(buffer, whsp); // index of first non-whitespace character char *buf = &buffer[m]; // remove trailing whitespace, by working backward from the end of string char *p = strchr(buf, '\0'); // *p is '\0', or p is NULL if (p == NULL) { fprintf(stderr, "%s: strange string\n", prog); exit(EXIT_FAILURE); } else { p--; // *p is '\0', so back up one position while (p > buf && isspace(*p)) { *p = '\0'; p--; } } if (*buf == '\0') // empty line { continue; } list_names_append(list, buf); // get ready for the next iteration buffer[MAXLINE+2-2] = '\n'; // force a newline buffer[MAXLINE+2-1] = '\0'; // to end the string } if (infile != stdin && fclose(infile) != 0) { fprintf(stderr, "%s: failed: could not close input file %s: %s\n", prog, filename, strerror(errno)); exit(EXIT_FAILURE); } }