#include #include #include #include "misc.h" /* Read a line of a configuration file and process continuation line. Return buf, or NULL si eof Blank at the end of line are always stripped. Everything following comcar is a comment. The line is cut before. */ char *fgets_strip ( char *buf, int sizebuf, FILE *fin, char contcar, // Continuation char, generally backslash char comcar, // Comment character, generally # int *noline) // This will be updated and contain the line number // Can be NULL { int empty; return fgets_strip (buf,sizebuf,fin,contcar,comcar,noline,&empty); } /* Read a line of a configuration file and process continuation line. Return buf, or NULL si eof Blank at the end of line are always stripped. Everything following comcar is a comment. The line is cut before. Continuation character is \ Comment character is # */ char *fgets_strip ( char *buf, int sizebuf, FILE *fin, int *noline) // This will be updated and contain the line number // Can be NULL { int empty; return fgets_strip (buf,sizebuf,fin,'\\','#',noline,&empty); } /* Read a line of text and process continuation lines unlike fgets_strip, comment are return untouched. Return -1 if end of file, 0 if ok */ int fgets_cont (char *buf, int size, FILE *fin, bool cont) { int ret = -1; char tmp[size]; buf[0] = '\0'; while (fgets(tmp,size-1,fin) != NULL){ str_strip(tmp,tmp); int len = strlen(tmp); strcpy (buf,tmp); buf += len; size -= len; ret = 0; if (len == 0 || (!cont || tmp[len-1] != '\\')) break; *--buf = '\0'; size++; } return ret; } int fgets_cont (char *buf, int size, FILE *fin) { return fgets_cont (buf,size,fin,true); } /* Read lines and accumulate comments. buf will contain the first non comment, non empty line. */ const char *fgets_comments ( char buf[], int size, FILE *fin, SSTRING &comments, char comchar) { comments.setfrom (""); const char *ret = NULL; while (fgets_cont(buf,size,fin)!=-1){ strip_end (buf); char *pt = str_skip (buf); if (pt[0] == '\0' || pt[0] == comchar){ /* #Specification: fgets_comment / strategy When parsing comment out of a configuration file, only the text is kept (the # is striped). This helps the edit process. Comments should be written back with comment_write(). */ if (pt[0] == comchar) pt = str_skip(pt+1); strcat (buf,"\n"); comments.append (pt); }else{ ret = buf; break; } } return ret; } /* Read lines and accumulate comments. buf will contain the first non comment, non empty line. */ const char *fgets_comments ( char buf[], int size, FILE *fin, SSTRING &comments) { return fgets_comments (buf,size,fin,comments,'#'); } /* Write back a bunch of comment lines */ void comment_write (const SSTRING &str, FILE *fout, char comchar) { const char *pt = str.get(); while (*pt != '\0'){ const char *begin = pt; pt = strchr(pt,'\n'); if (pt == begin){ fputc('\n',fout); pt++; }else if (pt != NULL){ char line[1000]; char *ptl = line; while (begin < pt) *ptl++ = *begin++; *ptl = '\0'; fprintf (fout,"%c %s\n",comchar,line); pt++; }else{ fprintf (fout,"%c %s\n",comchar,begin); break; } } } /* Write back a bunch of comment lines */ void comment_write (const SSTRING &str, FILE *fout) { comment_write (str,fout,'#'); } #define FGETS_BUFSIZE 8192 /* Read a very long line and grow the line buffer as needed. The buffer may be initially NULL. The caller must free the buffer when done. realloc is used to grow the buffer. Return NULL at the end of the input. Return the start of the buffer if not (like normal fgets). */ char *fgets_long (char *&line, int &len, FILE *fin) { // Linuxconf is better to die here with an assert // than trying to run with invalid data. if (line == NULL){ line = (char*)malloc(FGETS_BUFSIZE); assert (line != NULL); len = FGETS_BUFSIZE; } char *ret = fgets (line,len-1,fin); if (ret != NULL){ int end = strlen(line); while (end > 0 && line[end-1] != '\n'){ // A very long user list. (Time to move to group // member of other groups ?) // We have to grow the line and read more len += FGETS_BUFSIZE; line = (char*)realloc(line,len); assert (line != NULL); ret = line; if (fgets(line+end,FGETS_BUFSIZE,fin)==NULL) break; end += strlen(line+end); } } return ret; }