Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit72c5d0d

Browse files
author
Arthur Zakirov
committed
Add crazy function get_control_value().
It parses json-like lines of backup_content.control file.
1 parent0077a78 commit72c5d0d

File tree

1 file changed

+165
-57
lines changed

1 file changed

+165
-57
lines changed

‎dir.c‎

Lines changed: 165 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ print_file_list(FILE *out, const parray *files, const char *root)
670670
path=GetRelativePath(path,root);
671671

672672
fprintf(out,"{\"path\":\"%s\", \"size\":\"%lu\",\"mode\":\"%u\","
673-
"\"is_datafile\":\"%u\" \"crc\":\"%u\"",
673+
"\"is_datafile\":\"%u\", \"crc\":\"%u\"",
674674
path, (unsigned long)file->write_size,file->mode,
675675
file->is_datafile?1:0,file->crc);
676676

@@ -689,6 +689,140 @@ print_file_list(FILE *out, const parray *files, const char *root)
689689
}
690690
}
691691

692+
/* Parsing states for get_control_value() */
693+
#defineCONTROL_WAIT_NAME1
694+
#defineCONTROL_INNAME2
695+
#defineCONTROL_WAIT_COLON3
696+
#defineCONTROL_WAIT_VALUE4
697+
#defineCONTROL_INVALUE5
698+
#defineCONTROL_WAIT_NEXT_NAME6
699+
700+
/*
701+
* Get value from json-like line "str" of backup_content.control file.
702+
*
703+
* The line has the following format:
704+
* {"name1":"value1", "name2":"value2"}
705+
*
706+
* The value will be returned to "value_str" as string if it is not NULL. If it
707+
* is NULL the value will be returned to "value_ulong" as unsigned long.
708+
*/
709+
staticvoid
710+
get_control_value(constchar*str,constchar*name,
711+
char*value_str,uint64*value_uint64,boolis_mandatory)
712+
{
713+
intstate=CONTROL_WAIT_NAME;
714+
char*name_ptr= (char*)name;
715+
char*buf= (char*)str;
716+
charbuf_uint64[32],/* Buffer for "value_uint64" */
717+
*buf_uint64_ptr;
718+
719+
/* Set default values */
720+
if (value_str)
721+
*value_str='\0';
722+
elseif (value_uint64)
723+
*value_uint64=0;
724+
725+
while (*buf)
726+
{
727+
switch (state)
728+
{
729+
caseCONTROL_WAIT_NAME:
730+
if (*buf=='"')
731+
state=CONTROL_INNAME;
732+
elseif (IsAlpha(*buf))
733+
gotobad_format;
734+
break;
735+
caseCONTROL_INNAME:
736+
/* Found target field. Parse value. */
737+
if (*buf=='"')
738+
state=CONTROL_WAIT_COLON;
739+
/* Check next field */
740+
elseif (*buf!=*name_ptr)
741+
{
742+
name_ptr= (char*)name;
743+
state=CONTROL_WAIT_NEXT_NAME;
744+
}
745+
else
746+
name_ptr++;
747+
break;
748+
caseCONTROL_WAIT_COLON:
749+
if (*buf==':')
750+
state=CONTROL_WAIT_VALUE;
751+
elseif (!IsSpace(*buf))
752+
gotobad_format;
753+
break;
754+
caseCONTROL_WAIT_VALUE:
755+
if (*buf=='"')
756+
{
757+
state=CONTROL_INVALUE;
758+
buf_uint64_ptr=buf_uint64;
759+
}
760+
elseif (IsAlpha(*buf))
761+
gotobad_format;
762+
break;
763+
caseCONTROL_INVALUE:
764+
/* Value was parsed, exit */
765+
if (*buf=='"')
766+
{
767+
if (value_str)
768+
{
769+
*value_str='\0';
770+
}
771+
elseif (value_uint64)
772+
{
773+
/* Length of buf_uint64 should not be greater than 31 */
774+
if (buf_uint64_ptr-buf_uint64 >=32)
775+
elog(ERROR,"field \"%s\" is out of range in the line %s of the file %s",
776+
name,str,DATABASE_FILE_LIST);
777+
778+
*buf_uint64_ptr='\0';
779+
if (!parse_uint64(buf_uint64,value_uint64))
780+
gotobad_format;
781+
}
782+
783+
return;
784+
}
785+
else
786+
{
787+
if (value_str)
788+
{
789+
*value_str=*buf;
790+
value_str++;
791+
}
792+
else
793+
{
794+
*buf_uint64_ptr=*buf;
795+
buf_uint64_ptr++;
796+
}
797+
}
798+
break;
799+
caseCONTROL_WAIT_NEXT_NAME:
800+
if (*buf==',')
801+
state=CONTROL_WAIT_NAME;
802+
break;
803+
default:
804+
/* Should not happen */
805+
break;
806+
}
807+
808+
buf++;
809+
}
810+
811+
/* There is no close quotes */
812+
if (state==CONTROL_INNAME||state==CONTROL_INVALUE)
813+
gotobad_format;
814+
815+
/* Did not find target field */
816+
if (is_mandatory)
817+
elog(ERROR,"field \"%s\" is not found in the line %s of the file %s",
818+
name,str,DATABASE_FILE_LIST);
819+
return;
820+
821+
bad_format:
822+
elog(ERROR,"%s file has invalid format in line %s",
823+
DATABASE_FILE_LIST,str);
824+
}
825+
692826
/*
693827
* Construct parray of pgFile from the backup content list.
694828
* If root is not NULL, path will be absolute path.
@@ -699,7 +833,6 @@ dir_read_file_list(const char *root, const char *file_txt)
699833
FILE*fp;
700834
parray*files;
701835
charbuf[MAXPGPATH*2];
702-
intline_num=0;
703836

704837
fp=fopen(file_txt,"rt");
705838
if (fp==NULL)
@@ -710,60 +843,33 @@ dir_read_file_list(const char *root, const char *file_txt)
710843

711844
while (fgets(buf,lengthof(buf),fp))
712845
{
713-
charpath[MAXPGPATH];
714-
charfilepath[MAXPGPATH];
715-
charlinked[MAXPGPATH];
716-
uint64generation=-1;
717-
intis_partial_copy=0;
718-
unsigned longwrite_size;
719-
pg_crc32crc;
720-
unsignedintmode;/* bit length of mode_t depends on platforms */
721-
pgFile*file;
722-
char*ptr;
723-
unsignedintis_datafile;
724-
intsegno=0;
725-
726-
/* XXX Maybe use better parser function? */
727-
#defineGET_VALUE(name,value,format,is_mandatory)\
728-
do {\
729-
if (ptr == NULL && is_mandatory)\
730-
elog(ERROR, "parameter \"%s\" is not found in \"%s\" in %d line",\
731-
name, file_txt, line_num);\
732-
if (ptr)\
733-
sscanf(ptr, format, &value);\
734-
} while (0)
735-
736-
line_num++;
737-
738-
ptr=strstr(buf,"\"path\"");
739-
GET_VALUE("path",path,"\"path\":\"%s\"", true);
740-
741-
ptr=strstr(buf,"\"size\"");
742-
GET_VALUE("size",write_size,"\"size\":\"%lu\"", true);
743-
744-
ptr=strstr(buf,"\"mode\"");
745-
GET_VALUE("mode",mode,"\"mode\":\"%u\"", true);
746-
747-
ptr=strstr(buf,"\"is_datafile\"");
748-
GET_VALUE("is_datafile",is_datafile,"\"is_datafile\":\"%u\"", true);
749-
750-
ptr=strstr(buf,"\"crc\"");
751-
GET_VALUE("crc",crc,"\"crc\":\"%u\"", true);
846+
charpath[MAXPGPATH];
847+
charfilepath[MAXPGPATH];
848+
charlinked[MAXPGPATH];
849+
uint64write_size,
850+
mode,/* bit length of mode_t depends on platforms */
851+
is_datafile,
852+
crc,
853+
segno;
854+
#ifdefPGPRO_EE
855+
uint64generation,
856+
is_partial_copy;
857+
#endif
858+
pgFile*file;
752859

753-
/* optional fields */
754-
linked[0]='\0';
755-
ptr=strstr(buf,"\"linked\"");
756-
GET_VALUE("linked",linked,"\"linked\":\"%s\"", false);
860+
get_control_value(buf,"path",path,NULL, true);
861+
get_control_value(buf,"size",NULL,&write_size, true);
862+
get_control_value(buf,"mode",NULL,&mode, true);
863+
get_control_value(buf,"is_datafile",NULL,&is_datafile, true);
864+
get_control_value(buf,"crc",NULL,&crc, true);
757865

758-
ptr=strstr(buf,"\"segno\"");
759-
GET_VALUE("segno",segno,"\"segno\":\"%d\"", false);
866+
/* optional fields */
867+
get_control_value(buf,"linked",linked,NULL, false);
868+
get_control_value(buf,"segno",NULL,&segno, false);
760869

761870
#ifdefPGPRO_EE
762-
ptr=strstr(buf,"\"CFS_generation\"");
763-
GET_VALUE("CFS_generation",generation,"\"CFS_generation\":\"%lu\"", true);
764-
765-
sscanf(buf,"\"CFS_generation\":\"%lu\"",&generation);
766-
GET_VALUE("is_partial_copy",is_partial_copy,"\"is_partial_copy\":\"%d\"", true);
871+
get_control_value(buf,"CFS_generation",NULL,&generation, true);
872+
get_control_value(buf,"is_partial_copy",NULL,&is_partial_copy, true);
767873
#endif
768874
if (root)
769875
join_path_components(filepath,root,path);
@@ -772,15 +878,17 @@ dir_read_file_list(const char *root, const char *file_txt)
772878

773879
file=pgFileInit(filepath);
774880

775-
file->write_size=write_size;
776-
file->mode=mode;
881+
file->write_size=(size_t)write_size;
882+
file->mode=(mode_t)mode;
777883
file->is_datafile=is_datafile ? true : false;
778-
file->crc=crc;
884+
file->crc=(pg_crc32)crc;
779885
if (linked[0])
780886
file->linked=pgut_strdup(linked);
781-
file->segno=segno;
887+
file->segno= (int)segno;
888+
#ifdefPGPRO_EE
782889
file->generation=generation;
783-
file->is_partial_copy=is_partial_copy;
890+
file->is_partial_copy= (int)is_partial_copy;
891+
#endif
784892

785893
parray_append(files,file);
786894
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp