25use_log_macro=
"log_packet_detailed"
26generate_variant_logs=1
29fold_bool_into_header=1
36import re, string, os, sys
46 lines=map(
lambda x,prefix=prefix: prefix+x,lines)
47 return "\n".join(lines)
51 /****************************************************************************
52 * THIS FILE WAS GENERATED *
53 * Script: common/generate_packets.py *
54 * Input: common/networking/packets.def *
55 * DO NOT CHANGE THIS FILE *
56 ****************************************************************************/
67 def helper(helper,all, index, so_far):
72 t1.append(
list(all)[index])
73 return helper(helper,all,index+1,t1)+helper(helper,all,index+1,t0)
75 result=helper(helper,all,0,[])
76 assert len(result)==2**
len(all)
96 mo=re.search(
r"^\s*(\S+(?:\(.*\))?)\s+([^;()]*)\s*;\s*(.*)\s*$",str)
101 arr.append(i.strip())
104 type,fields_,flags=arr
119 mo = re.search(
r"^(.*)\((.*)\)$", type)
121 typeinfo[
"dataio_type"],typeinfo[
"struct_type"]=mo.groups()
123 if typeinfo[
"struct_type"]==
"float":
124 mo = re.search(
r"^(\D+)(\d+)$", typeinfo[
"dataio_type"])
126 typeinfo[
"dataio_type"]=mo.group(1)
127 typeinfo[
"float_factor"]=int(mo.group(2))
131 for i
in fields_.split(
","):
141 arr.append(
"old->"+arr[1])
142 arr[1]=
"real_packet->"+arr[1]
145 mo=re.search(
r"^(.*)\[(.*)\]\[(.*)\]$",i)
147 t[
"name"]=mo.group(1)
149 t[
"array_size1_d"],t[
"array_size1_u"],t[
"array_size1_o"]=f(mo.group(2))
150 t[
"array_size2_d"],t[
"array_size2_u"],t[
"array_size2_o"]=f(mo.group(3))
152 mo=re.search(
r"^(.*)\[(.*)\]$",i)
154 t[
"name"]=mo.group(1)
156 t[
"array_size_d"],t[
"array_size_u"],t[
"array_size_o"]=f(mo.group(2))
164 arr=
list(item.strip()
for item
in flags.split(
","))
165 arr=
list(filter(
lambda x:
len(x)>0,arr))
166 flaginfo[
"is_key"]=(
"key" in arr)
167 if flaginfo[
"is_key"]: arr.remove(
"key")
168 flaginfo[
"diff"]=(
"diff" in arr)
169 if flaginfo[
"diff"]: arr.remove(
"diff")
174 mo = re.search(
r"^add-cap\((.*)\)$", i)
176 adds.append(mo.group(1))
178 mo = re.search(
r"^remove-cap\((.*)\)$", i)
180 removes.append(mo.group(1))
184 assert len(arr)==0,repr(arr)
185 assert len(adds)+
len(removes)
in [0,1]
188 flaginfo[
"add_cap"]=adds[0]
190 flaginfo[
"add_cap"]=
""
193 flaginfo[
"remove_cap"]=removes[0]
195 flaginfo[
"remove_cap"]=
""
200 result.append(
Field(f,typeinfo,flaginfo))
207 for i
in fieldinfo,typeinfo,flaginfo:
220 return "const char *"
231 return "%(struct_type)s %(name)s[%(array_size1_d)s][%(array_size2_d)s]"%self.
__dict__
233 return "%(struct_type)s %(name)s[%(array_size_d)s]"%self.
__dict__
235 return "%(struct_type)s %(name)s"%self.
__dict__
241 return " worklist_copy(&real_packet->%(name)s, %(name)s);"%self.
__dict__
243 return " real_packet->%(name)s = %(name)s;"%self.
__dict__
245 return " sz_strlcpy(real_packet->%(name)s, %(name)s);"%self.
__dict__
247 tmp=
"real_packet->%(name)s[i] = %(name)s[i]"%self.
__dict__
251 for (i = 0; i < %(array_size_u) s; i++) {
262 return " differ = (memcmp(old->%(name)s, real_packet->%(name)s, %(array_size_d)s) != 0);"%self.
__dict__
264 return " differ = !BV_ARE_EQUAL(old->%(name)s, real_packet->%(name)s);"%self.
__dict__
266 return " differ = (strcmp(old->%(name)s, real_packet->%(name)s) != 0);"%self.
__dict__
268 return " differ = !cm_are_parameter_equal(&old->%(name)s, &real_packet->%(name)s);" % self.
__dict__
270 return " differ = !are_%(dataio_type)ss_equal(&old->%(name)s, &real_packet->%(name)s);"%self.
__dict__
272 return " differ = (old->%(name)s != real_packet->%(name)s);"%self.
__dict__
275 c=
"strcmp(old->%(name)s[i], real_packet->%(name)s[i]) != 0"%self.
__dict__
276 array_size_u=self.array_size1_u
277 array_size_o=self.array_size1_o
279 c=
"!are_%(dataio_type)ss_equal(&old->%(name)s[i], &real_packet->%(name)s[i])"%self.
__dict__
280 array_size_u = self.array_size_u
281 array_size_o = self.array_size_o
283 c=
"old->%(name)s[i] != real_packet->%(name)s[i]"%self.
__dict__
284 array_size_u = self.array_size_u
285 array_size_o = self.array_size_o
287 if array_size_u != array_size_o:
290 differ = (%(array_size_o)s != %(array_size_u)s);
291 if (!differ) {''' % self.
get_dict(vars())
300 for (i = 0; i < %(array_size_u)s; i++) {
312 fold_bool_into_header
323 if pack.is_info !=
"no":
333 b=
"packet->%(name)s"%self.
get_dict(vars())
334 return '''%s'''%(cmp) + differ_part +
''' if (%s) {
341 if pack.is_info !=
"no":
360 if fold_bool_into_header
and self.
struct_type==
"bool" and \
362 return " /* field %(i)d is folded into the header */\n"%vars()
363 put=self.
get_put(deltafragment)
364 packet_name=packet.name
365 log_macro=packet.log_macro
367 f=
' %(log_macro)s(" field \'%(name)s\' has changed");\n'%self.
get_dict(vars())
371 s=
' stats_%(packet_name)s_counters[%(i)d]++;\n'%self.
get_dict(vars())
374 return ''' if (BV_ISSET(fields, %(i)d)) {
381 return '''#ifdef FREECIV_JSON_CONNECTION
382 field_addr.name = \"%(name)s\";
383#endif /* FREECIV_JSON_CONNECTION */
390 return "DIO_BV_PUT(&dout, &field_addr, packet->%(name)s);"%self.
__dict__
393 return " DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s, %(float_factor)d);"%self.
__dict__
395 if self.
dataio_type in [
"worklist",
"cm_parameter"]:
396 return " DIO_PUT(%(dataio_type)s, &dout, &field_addr, &real_packet->%(name)s);"%self.
__dict__
399 return " DIO_PUT(%(dataio_type)s, &dout, &field_addr, &real_packet->%(name)s, %(array_size_u)s);"%self.
__dict__
401 arr_types=[
"string",
"estring",
"city_map"]
404 return " DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s);"%self.
__dict__
407 c=
"DIO_PUT(%(dataio_type)s, &dout, &field_addr, &real_packet->%(name)s[i][j]);"%self.
__dict__
409 c=
"DIO_PUT(%(dataio_type)s, &dout, &field_addr, &real_packet->%(name)s[i]);"%self.
__dict__
411 c=
"DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s[i]);"%self.
__dict__
412 array_size_u=self.array_size1_u
416 c=
" DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s[i][j], %(float_factor)d);"%self.
__dict__
418 c=
" DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s[i], %(float_factor)d);"%self.
__dict__
421 c=
"DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s[i][j]);"%self.
__dict__
423 c=
"DIO_PUT(%(dataio_type)s, &dout, &field_addr, real_packet->%(name)s[i]);"%self.
__dict__
425 if deltafragment
and self.diff
and self.
is_array == 1:
430#ifdef FREECIV_JSON_CONNECTION
433 for (i = 0; i < %(array_size_u)s; i++) {
434 if (old->%(name)s[i] != real_packet->%(name)s[i]) {
438 /* Create the array. */
439 DIO_PUT(farray, &dout, &field_addr, count + 1);
442 field_addr.sub_location = plocation_elem_new(0);
445#endif /* FREECIV_JSON_CONNECTION */
447 fc_assert(%(array_size_u)s < 255);
449 for (i = 0; i < %(array_size_u)s; i++) {
450 if (old->%(name)s[i] != real_packet->%(name)s[i]) {
451#ifdef FREECIV_JSON_CONNECTION
452 /* Next diff array element. */
453 field_addr.sub_location->number = count - 1;
455 /* Create the diff array element. */
456 DIO_PUT(farray, &dout, &field_addr, 2);
458 /* Enter diff array element (start at the index address). */
459 field_addr.sub_location->sub_location = plocation_elem_new(0);
460#endif /* FREECIV_JSON_CONNECTION */
461 DIO_PUT(uint8, &dout, &field_addr, i);
463#ifdef FREECIV_JSON_CONNECTION
464 /* Content address. */
465 field_addr.sub_location->sub_location->number = 1;
466#endif /* FREECIV_JSON_CONNECTION */
469#ifdef FREECIV_JSON_CONNECTION
470 /* Exit diff array element. */
471 free(field_addr.sub_location->sub_location);
472 field_addr.sub_location->sub_location = NULL;
473#endif /* FREECIV_JSON_CONNECTION */
476#ifdef FREECIV_JSON_CONNECTION
477 field_addr.sub_location->number = count - 1;
479 /* Create the diff array element. */
480 DIO_PUT(farray, &dout, &field_addr, %(array_size_u)s);
482 /* Enter diff array element. Point to index address. */
483 field_addr.sub_location->sub_location = plocation_elem_new(0);
484#endif /* FREECIV_JSON_CONNECTION */
485 DIO_PUT(uint8, &dout, &field_addr, 255);
487#ifdef FREECIV_JSON_CONNECTION
488 /* Exit diff array element. */
489 free(field_addr.sub_location->sub_location);
490 field_addr.sub_location->sub_location = NULL;
493 free(field_addr.sub_location);
494 field_addr.sub_location = NULL;
495#endif /* FREECIV_JSON_CONNECTION */
503#ifdef FREECIV_JSON_CONNECTION
504 /* Create the outer array. */
505 DIO_PUT(farray, &dout, &field_addr, %(array_size_u)s);
507 /* Enter the outer array. */
508 field_addr.sub_location = plocation_elem_new(0);
509#endif /* FREECIV_JSON_CONNECTION */
511 for (i = 0; i < %(array_size1_u)s; i++) {
512#ifdef FREECIV_JSON_CONNECTION
513 /* Next inner array (an element in the outer array). */
514 field_addr.sub_location->number = i;
516 /* Create the inner array. */
517 DIO_PUT(farray, &dout, &field_addr, %(array_size_u)s);
519 /* Enter the inner array. */
520 field_addr.sub_location->sub_location = plocation_elem_new(0);
521#endif /* FREECIV_JSON_CONNECTION */
523 for (j = 0; j < %(array_size2_u)s; j++) {
524#ifdef FREECIV_JSON_CONNECTION
525 /* Next element (in the inner array). */
526 field_addr.sub_location->sub_location->number = j;
527#endif /* FREECIV_JSON_CONNECTION */
531#ifdef FREECIV_JSON_CONNECTION
532 /* Exit the inner array. */
533 free(field_addr.sub_location->sub_location);
534 field_addr.sub_location->sub_location = NULL;
535#endif /* FREECIV_JSON_CONNECTION */
538#ifdef FREECIV_JSON_CONNECTION
539 /* Exit the outer array. */
540 free(field_addr.sub_location);
541 field_addr.sub_location = NULL;
542#endif /* FREECIV_JSON_CONNECTION */
549#ifdef FREECIV_JSON_CONNECTION
550 /* Create the array. */
551 DIO_PUT(farray, &dout, &field_addr, %(array_size_u)s);
553 /* Enter the array. */
554 field_addr.sub_location = plocation_elem_new(0);
555#endif /* FREECIV_JSON_CONNECTION */
557 for (i = 0; i < %(array_size_u)s; i++) {
558#ifdef FREECIV_JSON_CONNECTION
559 /* Next array element. */
560 field_addr.sub_location->number = i;
561#endif /* FREECIV_JSON_CONNECTION */
565#ifdef FREECIV_JSON_CONNECTION
567 free(field_addr.sub_location);
568 field_addr.sub_location = NULL;
569#endif /* FREECIV_JSON_CONNECTION */
575 get=self.
get_get(deltafragment)
576 if fold_bool_into_header
and self.
struct_type==
"bool" and \
578 return " real_packet->%(name)s = BV_ISSET(fields, %(i)d);\n"%self.
get_dict(vars())
580 log_macro=packet.log_macro
582 f=
" %(log_macro)s(\" got field '%(name)s'\");\n"%self.
get_dict(vars())
585 return ''' if (BV_ISSET(fields, %(i)d)) {
592 return '''#ifdef FREECIV_JSON_CONNECTION
593field_addr.name = \"%(name)s\";
594#endif /* FREECIV_JSON_CONNECTION */
601 return '''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s, %(float_factor)d)) {
602 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
605 return '''if (!DIO_BV_GET(&din, &field_addr, real_packet->%(name)s)) {
606 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
608 if self.
dataio_type in [
"string",
"estring",
"city_map"]
and \
610 return '''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, real_packet->%(name)s, sizeof(real_packet->%(name)s))) {
611 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
614 return '''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s)) {
615 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
619 return '''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s)) {
620 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
626 if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &readin)) {
627 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
629 real_packet->%(name)s = readin;
634 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s[i][j])) {
635 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
638 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s[i])) {
639 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
642 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, real_packet->%(name)s[i], sizeof(real_packet->%(name)s[i]))) {
643 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
647 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s[i][j], %(float_factor)d)) {
648 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
651 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s[i], %(float_factor)d)) {
652 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
656 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s[i][j])) {
657 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
663 if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &readin)) {
664 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
666 real_packet->%(name)s[i][j] = readin;
669 c=
'''if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &real_packet->%(name)s[i])) {
670 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
676 if (!DIO_GET(%(dataio_type)s, &din, &field_addr, &readin)) {
677 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
679 real_packet->%(name)s[i] = readin;
683 array_size_u=self.array_size1_u
684 array_size_d=self.array_size1_d
686 array_size_u=self.array_size_u
687 array_size_d=self.array_size_d
690 if array_size_u != array_size_d:
692 if (%(array_size_u)s > %(array_size_d)s) {
693 RECEIVE_PACKET_FIELD_ERROR(%(name)s, ": truncation array");
699 if (!DIO_GET(%(dataio_type)s, &din, &field_addr, real_packet->%(name)s, %(array_size_u)s)) {
700 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
708#ifdef FREECIV_JSON_CONNECTION
709 /* Enter outer array. */
710 field_addr.sub_location = plocation_elem_new(0);
711#endif /* FREECIV_JSON_CONNECTION */
713 for (i = 0; i < %(array_size1_u)s; i++) {
714#ifdef FREECIV_JSON_CONNECTION
715 /* Update address of outer array element (inner array). */
716 field_addr.sub_location->number = i;
718 /* Enter inner array. */
719 field_addr.sub_location->sub_location = plocation_elem_new(0);
720#endif /* FREECIV_JSON_CONNECTION */
721 for (j = 0; j < %(array_size2_u)s; j++) {
722#ifdef FREECIV_JSON_CONNECTION
723 /* Update address of element in inner array. */
724 field_addr.sub_location->sub_location->number = j;
725#endif /* FREECIV_JSON_CONNECTION */
729#ifdef FREECIV_JSON_CONNECTION
730 /* Exit inner array. */
731 free(field_addr.sub_location->sub_location);
732 field_addr.sub_location->sub_location = NULL;
733#endif /* FREECIV_JSON_CONNECTION */
736#ifdef FREECIV_JSON_CONNECTION
737 /* Exit outer array. */
738 free(field_addr.sub_location);
739 field_addr.sub_location = NULL;
740#endif /* FREECIV_JSON_CONNECTION */
747#ifdef FREECIV_JSON_CONNECTION
749 field_addr.sub_location = plocation_elem_new(0);
750#endif /* FREECIV_JSON_CONNECTION */
752 for (i = 0; i < %(array_size_u)s; i++) {
753#ifdef FREECIV_JSON_CONNECTION
754 field_addr.sub_location->number = i;
755#endif /* FREECIV_JSON_CONNECTION */
759#ifdef FREECIV_JSON_CONNECTION
761 free(field_addr.sub_location);
762 field_addr.sub_location = NULL;
763#endif /* FREECIV_JSON_CONNECTION */
765 elif deltafragment
and self.diff
and self.
is_array == 1:
768#ifdef FREECIV_JSON_CONNECTION
772field_addr.sub_location = plocation_elem_new(0);
774for (count = 0;; count++) {
777 field_addr.sub_location->number = count;
779 /* Enter diff array element (start at the index address). */
780 field_addr.sub_location->sub_location = plocation_elem_new(0);
781#else /* FREECIV_JSON_CONNECTION */
784#endif /* FREECIV_JSON_CONNECTION */
786 if (!DIO_GET(uint8, &din, &field_addr, &i)) {
787 RECEIVE_PACKET_FIELD_ERROR(%(name)s);
790#ifdef FREECIV_JSON_CONNECTION
791 /* Exit diff array element. */
792 free(field_addr.sub_location->sub_location);
793 field_addr.sub_location->sub_location = NULL;
795 /* Exit diff array. */
796 free(field_addr.sub_location);
797 field_addr.sub_location = NULL;
798#endif /* FREECIV_JSON_CONNECTION */
802 if (i > %(array_size_u)s) {
803 RECEIVE_PACKET_FIELD_ERROR(%(name)s,
804 \": unexpected value %%%%d \"
805 \"(> %(array_size_u)s) in array diff\",
808#ifdef FREECIV_JSON_CONNECTION
809 /* Content address. */
810 field_addr.sub_location->sub_location->number = 1;
811#endif /* FREECIV_JSON_CONNECTION */
815#ifdef FREECIV_JSON_CONNECTION
816 /* Exit diff array element. */
817 free(field_addr.sub_location->sub_location);
818 field_addr.sub_location->sub_location = NULL;
819#endif /* FREECIV_JSON_CONNECTION */
822#ifdef FREECIV_JSON_CONNECTION
824free(field_addr.sub_location);
825field_addr.sub_location = NULL;
826#endif /* FREECIV_JSON_CONNECTION */
833 for (i = 0; i < %(array_size_u)s; i++) {
841 def __init__(self,poscaps,negcaps,name,fields,packet,no):
863 not field.folded_into_head
875 return 'has_capability("%s", capability)'%(cap)
885 self.
keys_arg=
", ".join(map(
lambda x:
"real_packet->"+x.name,
900 map(
lambda x:
"%s%s"%(x.get_handle_type(), x.name),
914 self.
receive_prototype=
'static struct %(packet_name)s *receive_%(name)s(struct connection *pc)'%self.__dict__
915 self.
send_prototype=
'static int send_%(name)s(struct connection *pc%(extra_send_args)s)'%self.__dict__
919 self.
send_handler=
'phandlers->send[%(type)s].no_packet = (int(*)(struct connection *)) send_%(name)s;'%self.__dict__
921 self.
send_handler=
'phandlers->send[%(type)s].force_to_send = (int(*)(struct connection *, const void *, bool)) send_%(name)s;'%self.__dict__
923 self.
send_handler=
'phandlers->send[%(type)s].packet = (int(*)(struct connection *, const void *)) send_%(name)s;'%self.__dict__
924 self.
receive_handler=
'phandlers->receive[%(type)s] = (void *(*)(struct connection *)) receive_%(name)s;'%self.__dict__
928 result=self.__dict__.copy()
936 names=
", ".join(names)
938 return '''static int stats_%(name)s_sent;
939static int stats_%(name)s_discarded;
940static int stats_%(name)s_counters[%(bits)d];
941static char *stats_%(name)s_names[] = {%(names)s};
949 return "BV_DEFINE(%(name)s_fields, %(bits)d);\n"%self.__dict__
955 if (stats_%(name)s_sent > 0
956 && stats_%(name)s_discarded != stats_%(name)s_sent) {
957 log_test(\"%(name)s %%d out of %%d got discarded\",
958 stats_%(name)s_discarded, stats_%(name)s_sent);
959 for (i = 0; i < %(bits)d; i++) {
960 if (stats_%(name)s_counters[i] > 0) {
961 log_test(\" %%4d / %%4d: %%2d = %%s\",
962 stats_%(name)s_counters[i],
963 (stats_%(name)s_sent - stats_%(name)s_discarded),
964 i, stats_%(name)s_names[i]);
974 stats_%(name)s_sent = 0;
975 stats_%(name)s_discarded = 0;
976 memset(stats_%(name)s_counters, 0,
977 sizeof(stats_%(name)s_counters));
984 return "#define hash_%(name)s hash_const\n\n"%self.__dict__
986 intro=
'''static genhash_val_t hash_%(name)s(const void *vkey)
990 body=
''' const struct %(packet_name)s *key = (const struct %(packet_name)s *) vkey;
998 a=
"(%s << 8) ^ %s"%(keys[0], keys[1])
1001 body=body+(
' return %s;\n'%a)
1003 return intro+body+extro
1010 return "#define cmp_%(name)s cmp_const\n\n"%self.__dict__
1012 intro=
'''static bool cmp_%(name)s(const void *vkey1, const void *vkey2)
1016 body=body+
''' const struct %(packet_name)s *key1 = (const struct %(packet_name)s *) vkey1;
1017 const struct %(packet_name)s *key2 = (const struct %(packet_name)s *) vkey2;
1021 body=body+
''' return key1->%s == key2->%s;
1022'''%(field.name,field.name)
1024 return intro+body+extro
1030 temp=
'''%(send_prototype)s
1032<real_packet1><delta_header> SEND_PACKET_START(%(type)s);
1033<faddr><log><report><pre1><body><pre2><post> SEND_PACKET_END(%(type)s);
1040 stats_%(name)s_sent++;
1045 log=
'\n %(log_macro)s("%(name)s: sending info about (%(keys_format)s)"%(keys_arg)s);\n'
1051 struct %(packet_name)s *tmp = fc_malloc(sizeof(*tmp));
1054 pre_send_%(packet_name)s(pc, tmp);
1059 if (real_packet != packet) {
1060 free((void *) real_packet);
1068 real_packet1=
" const struct %(packet_name)s *real_packet = packet;\n"
1075 diff=
'force_to_send'
1078 delta_header =
'''#ifdef FREECIV_DELTA_PROTOCOL
1079 %(name)s_fields fields;
1080 struct %(packet_name)s *old;
1082 delta_header2 =
''' struct genhash **hash = pc->phs.sent + %(type)s;
1085 delta_header2 = delta_header2 +
''' int different = %(diff)s;
1087 delta_header2 = delta_header2 +
'''#endif /* FREECIV_DELTA_PROTOCOL */
1092 body=
"#if 1 /* To match endif */"
1094 for field
in self.
fields:
1095 body=body+field.get_put(0)+
"\n"
1096 body=body+
"\n#endif\n"
1103 post=
" post_send_%(packet_name)s(pc, NULL);\n"
1105 post=
" post_send_%(packet_name)s(pc, real_packet);\n"
1110 faddr =
'''#ifdef FREECIV_JSON_CONNECTION
1111 struct plocation field_addr;
1113 struct plocation *field_addr_tmp = plocation_field_new(NULL);
1114 field_addr = *field_addr_tmp;
1115 FC_FREE(field_addr_tmp);
1117#endif /* FREECIV_JSON_CONNECTION */
1122 if delta_header !=
"":
1124 delta_header = delta_header +
''' bool differ;
1127 delta_header = delta_header + delta_header2
1129 for k,v
in vars().items():
1131 temp=temp.replace(
"<%s>"%k,v)
1139#ifdef FREECIV_DELTA_PROTOCOL
1140 if (NULL == *hash) {
1141 *hash = genhash_new_full(hash_%(name)s, cmp_%(name)s,
1142 NULL, NULL, NULL, free);
1146 if (!genhash_lookup(*hash, real_packet, (void **) &old)) {
1147 old = fc_malloc(sizeof(*old));
1148 *old = *real_packet;
1149 genhash_insert(*hash, old, old);
1150 memset(old, 0, sizeof(*old));
1153 intro = intro +
''' different = 1; /* Force to send. */
1155 intro = intro +
''' }
1160 body=body+field.get_cmp_wrapper(i, self)
1162 fl=
' %(log_macro)s(" no change -> discard");\n'
1166 s=
' stats_%(name)s_discarded++;\n'
1172 if (different == 0) {
1173%(fl)s%(s)s<pre2> return 0;
1178#ifdef FREECIV_JSON_CONNECTION
1179 field_addr.name = "fields";
1180#endif /* FREECIV_JSON_CONNECTION */
1181 DIO_BV_PUT(&dout, &field_addr, fields);
1185 body=body+field.get_put(1)+
"\n"
1190 body=body+field.get_put_wrapper(self,i,1)
1192 *old = *real_packet;
1198 hash = pc->phs.sent + %s;
1199 if (NULL != *hash) {
1200 genhash_remove(*hash, real_packet);
1203 body=body+
'''#endif /* FREECIV_DELTA_PROTOCOL */'''
1211 temp=
'''%(receive_prototype)s
1213<delta_header> RECEIVE_PACKET_START(%(packet_name)s, real_packet);
1214<faddr><delta_body1><body1><log><body2><post> RECEIVE_PACKET_END(real_packet);
1219 delta_header=
'''#ifdef FREECIV_DELTA_PROTOCOL
1220 %(name)s_fields fields;
1221 struct %(packet_name)s *old;
1222 struct genhash **hash = pc->phs.received + %(type)s;
1223#endif /* FREECIV_DELTA_PROTOCOL */
1226#ifdef FREECIV_DELTA_PROTOCOL
1227#ifdef FREECIV_JSON_CONNECTION
1228 field_addr.name = "fields";
1229#endif /* FREECIV_JSON_CONNECTION */
1230 DIO_BV_GET(&din, &field_addr, fields);
1234 body1=body1+
prefix(
" ",field.get_get(1))+
"\n"
1235 body1=body1+
"\n#else /* FREECIV_DELTA_PROTOCOL */\n"
1240 body1=
"#if 1 /* To match endif */\n"
1243 for field
in self.
fields:
1244 nondelta=nondelta+
prefix(
" ",field.get_get(0))+
"\n"
1246 nondelta=
" real_packet->__dummy = 0xff;"
1247 body1=body1+nondelta+
"\n#endif\n"
1250 log=
' %(log_macro)s("%(name)s: got info about (%(keys_format)s)"%(keys_arg)s);\n'
1255 post=
" post_receive_%(packet_name)s(pc, real_packet);\n"
1260 faddr =
'''#ifdef FREECIV_JSON_CONNECTION
1261 struct plocation field_addr;
1263 struct plocation *field_addr_tmp = plocation_field_new(NULL);
1264 field_addr = *field_addr_tmp;
1265 FC_FREE(field_addr_tmp);
1267#endif /* FREECIV_JSON_CONNECTION */
1273 for k,v
in vars().items():
1275 temp=temp.replace(
"<%s>"%k,v)
1280 key1=map(
lambda x:
" %s %s = real_packet->%s;"%(x.struct_type,x.name,x.name),self.
key_fields)
1281 key2=map(
lambda x:
" real_packet->%s = %s;"%(x.name,x.name),self.
key_fields)
1282 key1=
"\n".join(key1)
1283 key2=
"\n".join(key2)
1284 if key1: key1=key1+
"\n\n"
1285 if key2: key2=
"\n\n"+key2
1287 fl=
' %(log_macro)s(" no old info");\n'
1291#ifdef FREECIV_DELTA_PROTOCOL
1292 if (NULL == *hash) {
1293 *hash = genhash_new_full(hash_%(name)s, cmp_%(name)s,
1294 NULL, NULL, NULL, free);
1297 if (genhash_lookup(*hash, real_packet, (void **) &old)) {
1298 *real_packet = *old;
1300%(key1)s%(fl)s memset(real_packet, 0, sizeof(*real_packet));%(key2)s
1306 body=body+field.get_get_wrapper(self,i,1)
1310 old = fc_malloc(sizeof(*old));
1311 *old = *real_packet;
1312 genhash_insert(*hash, old, old);
1314 *old = *real_packet;
1321 hash = pc->phs.received + %s;
1322 if (NULL != *hash) {
1323 genhash_remove(*hash, real_packet);
1327 return body+extro+
'''
1328#endif /* FREECIV_DELTA_PROTOCOL */
1339 lines=str.split(
"\n")
1341 mo = re.search(
r"^\s*(\S+)\s*=\s*(\d+)\s*;\s*(.*?)\s*$", lines[0])
1342 assert mo,repr(lines[0])
1352 arr=
list(item.strip()
for item
in dummy.split(
",")
if item)
1357 self.
dirs.append(
"sc")
1360 self.
dirs.append(
"cs")
1368 if "is-info" in arr:
1370 arr.remove(
"is-info")
1371 if "is-game-info" in arr:
1373 arr.remove(
"is-game-info")
1385 if not self.
delta: arr.remove(
"no-delta")
1388 if self.
no_packet: arr.remove(
"no-packet")
1397 if self.
no_handle: arr.remove(
"no-handle")
1412 mo = re.search(
r"^cancel\((.*)\)$", i)
1414 self.
cancel.append(mo.group(1))
1419 assert len(arr)==0,repr(arr)
1428 self.
keys_arg=
", ".join(map(
lambda x:
"real_packet->"+x.name,
1439 assert not self.
want_dsend,
"dsend for a packet without fields isn't useful"
1441 if len(self.
fields)>5
or self.
name.split(
"_")[1]==
"ruleset":
1447 map(
lambda x:
"%s%s"%(x.get_handle_type(), x.name),
1461 self.
send_prototype=
'int send_%(name)s(struct connection *pc%(extra_send_args)s)'%self.__dict__
1463 self.
lsend_prototype=
'void lsend_%(name)s(struct conn_list *dest%(extra_send_args)s)'%self.__dict__
1465 self.
dsend_prototype=
'int dsend_%(name)s(struct connection *pc%(extra_send_args3)s)'%self.__dict__
1467 self.
dlsend_prototype=
'void dlsend_%(name)s(struct conn_list *dest%(extra_send_args3)s)'%self.__dict__
1472 if f.add_cap: all_caps[f.add_cap]=1
1473 if f.remove_cap: all_caps[f.remove_cap]=1
1475 all_caps=all_caps.keys()
1480 negcaps=
without(all_caps,poscaps)
1482 for field
in self.
fields:
1483 if not field.add_cap
and not field.remove_cap:
1484 fields.append(field)
1485 elif field.add_cap
and field.add_cap
in poscaps:
1486 fields.append(field)
1487 elif field.remove_cap
and field.remove_cap
in negcaps:
1488 fields.append(field)
1496 intro=
"struct %(name)s {\n"%self.__dict__
1501 body=body+
" %s;\n"%field.get_declar()
1503 body=
" char __dummy; /* to avoid malloc(0); */\n"
1504 return intro+body+extro
1521 result=self.__dict__.copy()
1530 func=
"force_to_send"
1531 args=
", packet, force_to_send"
1536 return '''%(send_prototype)s
1539 log_error("WARNING: trying to send data to the closed connection %%s",
1540 conn_description(pc));
1543 fc_assert_ret_val_msg(pc->phs.handlers->send[%(type)s].%(func)s != NULL, -1,
1544 "Handler for %(type)s not installed");
1545 return pc->phs.handlers->send[%(type)s].%(func)s(pc%(args)s);
1554 result=result+
"#ifdef FREECIV_DELTA_PROTOCOL\n"
1555 result=result+v.get_hash()
1556 result=result+v.get_cmp()
1557 result=result+v.get_bitvector()
1558 result=result+
"#endif /* FREECIV_DELTA_PROTOCOL */\n\n"
1559 result=result+v.get_receive()
1560 result=result+v.get_send()
1567 return '''%(lsend_prototype)s
1569 conn_list_iterate(dest, pconn) {
1570 send_%(name)s(pconn%(extra_send_args2)s);
1571 } conn_list_iterate_end;
1580 fill=
"\n".join(map(
lambda x:x.get_fill(),self.
fields))
1581 return '''%(dsend_prototype)s
1583 struct %(name)s packet, *real_packet = &packet;
1587 return send_%(name)s(pc, real_packet);
1596 fill=
"\n".join(map(
lambda x:x.get_fill(),self.
fields))
1597 return '''%(dlsend_prototype)s
1599 struct %(name)s packet, *real_packet = &packet;
1603 lsend_%(name)s(dest, real_packet);
1614 if f.add_cap: all_caps[f.add_cap]=1
1615 if f.remove_cap: all_caps[f.remove_cap]=1
1617const char *const packet_functional_capability = "%s";
1618'''%
' '.join(all_caps.keys())
1623 if not generate_stats:
return 'void delta_stats_report(void) {}\n\n'
1626void delta_stats_report(void) {
1634 body=body+p.get_report_part()
1635 return intro+body+extro
1640 if not generate_stats:
return 'void delta_stats_reset(void) {}\n\n'
1642void delta_stats_reset(void) {
1648 body=body+p.get_reset_part()
1649 return intro+body+extro
1654 intro=
'''const char *packet_name(enum packet_type type)
1656 static const char *const names[PACKET_LAST] = {
1661 mapping[p.type_number]=p
1662 sorted=
list(mapping.keys())
1668 for i
in range(last + 1, n):
1669 body=body+
' "unknown",\n'
1670 body=body+
' "%s",\n'%mapping[n].type
1675 return (type < PACKET_LAST ? names[type] : "unknown");
1679 return intro+body+extro
1684 intro=
'''bool packet_has_game_info_flag(enum packet_type type)
1686 static const bool flag[PACKET_LAST] = {
1691 mapping[p.type_number]=p
1692 sorted=
list(mapping.keys())
1698 for i
in range(last + 1, n):
1699 body=body+
' FALSE,\n'
1700 if mapping[n].is_info!=
"game":
1701 body=body+
' FALSE, /* %s */\n'%mapping[n].type
1703 body=body+
' TRUE, /* %s */\n'%mapping[n].type
1708 return (type < PACKET_LAST ? flag[type] : FALSE);
1712 return intro+body+extro
1717 intro=
'''void packet_handlers_fill_initial(struct packet_handlers *phandlers)
1723 if f.add_cap: all_caps[f.add_cap]=1
1724 if f.remove_cap: all_caps[f.remove_cap]=1
1725 for cap
in all_caps.keys():
1726 intro=intro+
''' fc_assert_msg(has_capability("%s", our_capability),
1727 "Packets have support for unknown '%s' capability!");
1734 if len(p.variants)==1:
1740 if len(p.dirs)==1
and p.dirs[0]==
"sc":
1741 sc_packets.append(p)
1742 elif len(p.dirs)==1
and p.dirs[0]==
"cs":
1743 cs_packets.append(p)
1745 unrestricted.append(p)
1748 for p
in unrestricted:
1749 body=body+
''' %(send_handler)s
1751'''%p.variants[0].__dict__
1752 body=body+
''' if (is_server()) {
1754 for p
in sc_packets:
1755 body=body+
''' %(send_handler)s
1756'''%p.variants[0].__dict__
1757 for p
in cs_packets:
1758 body=body+
''' %(receive_handler)s
1759'''%p.variants[0].__dict__
1760 body=body+
''' } else {
1762 for p
in cs_packets:
1763 body=body+
''' %(send_handler)s
1764'''%p.variants[0].__dict__
1765 for p
in sc_packets:
1766 body=body+
''' %(receive_handler)s
1767'''%p.variants[0].__dict__
1773 return intro+body+extro
1778 intro=
'''void packet_handlers_fill_capability(struct packet_handlers *phandlers,
1779 const char *capability)
1787 if len(p.variants)>1:
1788 if len(p.dirs)==1
and p.dirs[0]==
"sc":
1789 sc_packets.append(p)
1790 elif len(p.dirs)==1
and p.dirs[0]==
"cs":
1791 cs_packets.append(p)
1793 unrestricted.append(p)
1796 for p
in unrestricted:
1798 for v
in p.variants:
1799 body=body+
'''if (%(condition)s) {
1800 %(log_macro)s("%(type)s: using variant=%(no)s cap=%%s", capability);
1803 } else '''%v.__dict__
1805 log_error("Unknown %(type)s variant for cap %%s", capability);
1808 if len(cs_packets)>0
or len(sc_packets)>0:
1809 body=body+
''' if (is_server()) {
1811 for p
in sc_packets:
1813 for v
in p.variants:
1814 body=body+
'''if (%(condition)s) {
1815 %(log_macro)s("%(type)s: using variant=%(no)s cap=%%s", capability);
1817 } else '''%v.__dict__
1819 log_error("Unknown %(type)s variant for cap %%s", capability);
1822 for p
in cs_packets:
1824 for v
in p.variants:
1825 body=body+
'''if (%(condition)s) {
1826 %(log_macro)s("%(type)s: using variant=%(no)s cap=%%s", capability);
1828 } else '''%v.__dict__
1830 log_error("Unknown %(type)s variant for cap %%s", capability);
1833 body=body+
''' } else {
1835 for p
in cs_packets:
1837 for v
in p.variants:
1838 body=body+
'''if (%(condition)s) {
1839 %(log_macro)s("%(type)s: using variant=%(no)s cap=%%s", capability);
1841 } else '''%v.__dict__
1843 log_error("Unknown %(type)s variant for cap %%s", capability);
1846 for p
in sc_packets:
1848 for v
in p.variants:
1849 body=body+
'''if (%(condition)s) {
1850 %(log_macro)s("%(type)s: using variant=%(no)s cap=%%s", capability);
1852 } else '''%v.__dict__
1854 log_error("Unknown %(type)s variant for cap %%s", capability);
1862 return intro+body+extro
1867 intro=
"enum packet_type {\n"
1871 if p.type_number
in mapping :
1872 print(p.name,mapping[p.type_number].name)
1874 mapping[p.type_number]=p
1875 sorted=
list(mapping.keys())
1883 line=
" %s = %d,"%(p.type,i)
1885 line=
" %s,"%(p.type)
1888 line=
"%-40s /* %d */"%(line,i)
1893 PACKET_LAST /* leave this last */
1897 return intro+body+extro
1905 for i
in filter(
lambda x:x,s.split(
"/*")):
1907 assert len(l)==2,repr(i)
1915 src_dir=os.path.dirname(sys.argv[0])
1916 src_root=src_dir+
"/.."
1917 input_name=src_dir+
"/networking/packets.def"
1919 content=open(input_name).read()
1921 lines=content.split(
"\n")
1922 lines = map(
lambda x: re.sub(
r"\s*#.*$",
"", x), lines)
1923 lines = map(
lambda x: re.sub(
r"\s*//.*$",
"", x), lines)
1924 lines = filter(
lambda x:
not re.search(
r"^\s*$", x), lines)
1928 mo = re.search(
r"^type\s+(\S+)\s*=\s*(.+)\s*$", i)
1930 types.append(
Type(mo.group(1),mo.group(2)))
1935 for str
in re.split(
"(?m)^end$",
"\n".join(lines2)):
1938 packets.append(
Packet(str,types))
1943 output_h_name=sys.argv[1]
1945 if output_h_name !=
"":
1947 output_h=
fc_open(output_h_name+
".tmp")
1949 output_h=
fc_open(output_h_name)
1954#endif /* __cplusplus */
1959#include "disaster.h"
1969 output_h.write(p.get_struct())
1975 output_h.write(p.get_prototypes())
1977void delta_stats_report(void);
1978void delta_stats_reset(void);
1982#endif /* __cplusplus */
1987 output_c_name=sys.argv[2]
1988 if output_c_name !=
"":
1990 output_c=
fc_open(output_c_name+
".tmp")
1992 output_c=
fc_open(output_c_name)
1996#include <fc_config.h>
2002#include "bitvector.h"
2003#include "capability.h"
2011#include "connection.h"
2019#ifdef FREECIV_DELTA_PROTOCOL
2020static genhash_val_t hash_const(const void *vkey)
2025static bool cmp_const(const void *vkey1, const void *vkey2)
2029#endif /* FREECIV_DELTA_PROTOCOL */
2034static int stats_total_sent;
2041 output_c.write(p.get_stats())
2051 output_c.write(p.get_variants())
2052 output_c.write(p.get_send())
2053 output_c.write(p.get_lsend())
2054 output_c.write(p.get_dsend())
2055 output_c.write(p.get_dlsend())
2062 for i
in [output_h_name,output_c_name]:
2063 if os.path.isfile(i):
2067 new=open(i+
".tmp").read()
2069 open(i,
"w").write(new)
2072 if sys.argv[5] !=
"":
2075#ifndef FC__HAND_GEN_H
2076#define FC__HAND_GEN_H
2082#include "fc_types.h"
2087bool server_handle_packet(enum packet_type type, const void *packet,
2088 struct player *pplayer, struct connection *pconn);
2093 if "cs" in p.dirs
and not p.no_handle:
2094 a=p.name[
len(
"packet_"):]
2095 type=a.split(
"_")[0]
2097 b=map(
lambda x:
"%s%s"%(x.get_handle_type(), x.name),b)
2101 if p.handle_via_packet:
2102 f.write(
'struct %s;\n'%p.name)
2103 if p.handle_per_conn:
2104 f.write(
'void handle_%s(struct connection *pc, const struct %s *packet);\n'%(a,p.name))
2106 f.write(
'void handle_%s(struct player *pplayer, const struct %s *packet);\n'%(a,p.name))
2108 if p.handle_per_conn:
2109 f.write(
'void handle_%s(struct connection *pc%s);\n'%(a,b))
2111 f.write(
'void handle_%s(struct player *pplayer%s);\n'%(a,b))
2113#endif /* FC__HAND_GEN_H */
2117 if sys.argv[3] !=
"":
2120#ifndef FC__PACKHAND_GEN_H
2121#define FC__PACKHAND_GEN_H
2125#endif /* __cplusplus */
2133bool client_handle_packet(enum packet_type type, const void *packet);
2137 if "sc" not in p.dirs:
continue
2139 a=p.name[
len(
"packet_"):]
2142 b=map(
lambda x:
"%s%s"%(x.get_handle_type(), x.name),b)
2146 if p.handle_via_packet:
2147 f.write(
'struct %s;\n'%p.name)
2148 f.write(
'void handle_%s(const struct %s *packet);\n'%(a,p.name))
2150 f.write(
'void handle_%s(%s);\n'%(a,b))
2154#endif /* __cplusplus */
2156#endif /* FC__PACKHAND_GEN_H */
2160 if sys.argv[6] !=
"":
2165#include <fc_config.h>
2171#include "hand_gen.h"
2173bool server_handle_packet(enum packet_type type, const void *packet,
2174 struct player *pplayer, struct connection *pconn)
2179 if "cs" not in p.dirs:
continue
2180 if p.no_handle:
continue
2181 a=p.name[
len(
"packet_"):]
2182 c=
'((const struct %s *)packet)->'%p.name
2186 if x.dataio_type==
"worklist":
2193 if p.handle_via_packet:
2194 if p.handle_per_conn:
2195 args=
"pconn, packet"
2197 args=
"pplayer, packet"
2200 if p.handle_per_conn:
2205 f.write(
''' case %s:
2210 f.write(
''' default:
2217 if sys.argv[4] !=
"":
2222#include <fc_config.h>
2228#include "packhand_gen.h"
2230bool client_handle_packet(enum packet_type type, const void *packet)
2235 if "sc" not in p.dirs:
continue
2236 if p.no_handle:
continue
2237 a=p.name[
len(
"packet_"):]
2238 c=
'((const struct %s *)packet)->'%p.name
2242 if x.dataio_type==
"worklist":
2249 if p.handle_via_packet:
2254 f.write(
''' case %s:
2259 f.write(
''' default:
__init__(self, fieldinfo, typeinfo, flaginfo)
get_get_real(self, deltafragment)
get_get_wrapper(self, packet, i, deltafragment)
get_cmp_wrapper(self, i, pack)
get_put_wrapper(self, packet, i, deltafragment)
get_put_real(self, deltafragment)
get_put(self, deltafragment)
get_get(self, deltafragment)
__init__(self, str, types)
__init__(self, alias, dest)
__init__(self, poscaps, negcaps, name, fields, packet, no)
get_delta_receive_body(self)
get_delta_send_body(self)
static struct fc_sockaddr_list * list
get_packet_has_game_info_flag(packets)
get_packet_handlers_fill_initial(packets)
get_packet_functional_capability(packets)
get_packet_handlers_fill_capability(packets)