gitlab-pg_query 1.3.1 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (480) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +217 -99
  3. data/README.md +92 -69
  4. data/Rakefile +85 -5
  5. data/ext/pg_query/extconf.rb +3 -40
  6. data/ext/pg_query/guc-file.c +0 -0
  7. data/ext/pg_query/include/access/amapi.h +246 -0
  8. data/ext/pg_query/include/access/attmap.h +52 -0
  9. data/ext/pg_query/include/access/attnum.h +64 -0
  10. data/ext/pg_query/include/access/clog.h +61 -0
  11. data/ext/pg_query/include/access/commit_ts.h +77 -0
  12. data/ext/pg_query/include/access/detoast.h +92 -0
  13. data/ext/pg_query/include/access/genam.h +228 -0
  14. data/ext/pg_query/include/access/gin.h +78 -0
  15. data/ext/pg_query/include/access/htup.h +89 -0
  16. data/ext/pg_query/include/access/htup_details.h +819 -0
  17. data/ext/pg_query/include/access/itup.h +161 -0
  18. data/ext/pg_query/include/access/parallel.h +82 -0
  19. data/ext/pg_query/include/access/printtup.h +35 -0
  20. data/ext/pg_query/include/access/relation.h +28 -0
  21. data/ext/pg_query/include/access/relscan.h +176 -0
  22. data/ext/pg_query/include/access/rmgr.h +35 -0
  23. data/ext/pg_query/include/access/rmgrlist.h +49 -0
  24. data/ext/pg_query/include/access/sdir.h +58 -0
  25. data/ext/pg_query/include/access/skey.h +151 -0
  26. data/ext/pg_query/include/access/stratnum.h +83 -0
  27. data/ext/pg_query/include/access/sysattr.h +29 -0
  28. data/ext/pg_query/include/access/table.h +27 -0
  29. data/ext/pg_query/include/access/tableam.h +1825 -0
  30. data/ext/pg_query/include/access/transam.h +265 -0
  31. data/ext/pg_query/include/access/tupconvert.h +51 -0
  32. data/ext/pg_query/include/access/tupdesc.h +154 -0
  33. data/ext/pg_query/include/access/tupmacs.h +247 -0
  34. data/ext/pg_query/include/access/twophase.h +61 -0
  35. data/ext/pg_query/include/access/xact.h +463 -0
  36. data/ext/pg_query/include/access/xlog.h +398 -0
  37. data/ext/pg_query/include/access/xlog_internal.h +330 -0
  38. data/ext/pg_query/include/access/xlogdefs.h +109 -0
  39. data/ext/pg_query/include/access/xloginsert.h +64 -0
  40. data/ext/pg_query/include/access/xlogreader.h +327 -0
  41. data/ext/pg_query/include/access/xlogrecord.h +227 -0
  42. data/ext/pg_query/include/bootstrap/bootstrap.h +62 -0
  43. data/ext/pg_query/include/c.h +1322 -0
  44. data/ext/pg_query/include/catalog/catalog.h +42 -0
  45. data/ext/pg_query/include/catalog/catversion.h +58 -0
  46. data/ext/pg_query/include/catalog/dependency.h +275 -0
  47. data/ext/pg_query/include/catalog/genbki.h +64 -0
  48. data/ext/pg_query/include/catalog/index.h +199 -0
  49. data/ext/pg_query/include/catalog/indexing.h +366 -0
  50. data/ext/pg_query/include/catalog/namespace.h +188 -0
  51. data/ext/pg_query/include/catalog/objectaccess.h +197 -0
  52. data/ext/pg_query/include/catalog/objectaddress.h +84 -0
  53. data/ext/pg_query/include/catalog/pg_aggregate.h +176 -0
  54. data/ext/pg_query/include/catalog/pg_aggregate_d.h +77 -0
  55. data/ext/pg_query/include/catalog/pg_am.h +60 -0
  56. data/ext/pg_query/include/catalog/pg_am_d.h +45 -0
  57. data/ext/pg_query/include/catalog/pg_attribute.h +204 -0
  58. data/ext/pg_query/include/catalog/pg_attribute_d.h +59 -0
  59. data/ext/pg_query/include/catalog/pg_authid.h +58 -0
  60. data/ext/pg_query/include/catalog/pg_authid_d.h +49 -0
  61. data/ext/pg_query/include/catalog/pg_class.h +200 -0
  62. data/ext/pg_query/include/catalog/pg_class_d.h +103 -0
  63. data/ext/pg_query/include/catalog/pg_collation.h +73 -0
  64. data/ext/pg_query/include/catalog/pg_collation_d.h +45 -0
  65. data/ext/pg_query/include/catalog/pg_constraint.h +247 -0
  66. data/ext/pg_query/include/catalog/pg_constraint_d.h +67 -0
  67. data/ext/pg_query/include/catalog/pg_control.h +250 -0
  68. data/ext/pg_query/include/catalog/pg_conversion.h +72 -0
  69. data/ext/pg_query/include/catalog/pg_conversion_d.h +35 -0
  70. data/ext/pg_query/include/catalog/pg_depend.h +73 -0
  71. data/ext/pg_query/include/catalog/pg_depend_d.h +34 -0
  72. data/ext/pg_query/include/catalog/pg_event_trigger.h +51 -0
  73. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +34 -0
  74. data/ext/pg_query/include/catalog/pg_index.h +80 -0
  75. data/ext/pg_query/include/catalog/pg_index_d.h +56 -0
  76. data/ext/pg_query/include/catalog/pg_language.h +67 -0
  77. data/ext/pg_query/include/catalog/pg_language_d.h +39 -0
  78. data/ext/pg_query/include/catalog/pg_namespace.h +59 -0
  79. data/ext/pg_query/include/catalog/pg_namespace_d.h +34 -0
  80. data/ext/pg_query/include/catalog/pg_opclass.h +85 -0
  81. data/ext/pg_query/include/catalog/pg_opclass_d.h +49 -0
  82. data/ext/pg_query/include/catalog/pg_operator.h +102 -0
  83. data/ext/pg_query/include/catalog/pg_operator_d.h +106 -0
  84. data/ext/pg_query/include/catalog/pg_opfamily.h +60 -0
  85. data/ext/pg_query/include/catalog/pg_opfamily_d.h +47 -0
  86. data/ext/pg_query/include/catalog/pg_partitioned_table.h +63 -0
  87. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +35 -0
  88. data/ext/pg_query/include/catalog/pg_proc.h +211 -0
  89. data/ext/pg_query/include/catalog/pg_proc_d.h +99 -0
  90. data/ext/pg_query/include/catalog/pg_publication.h +115 -0
  91. data/ext/pg_query/include/catalog/pg_publication_d.h +36 -0
  92. data/ext/pg_query/include/catalog/pg_replication_origin.h +57 -0
  93. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +29 -0
  94. data/ext/pg_query/include/catalog/pg_statistic.h +275 -0
  95. data/ext/pg_query/include/catalog/pg_statistic_d.h +194 -0
  96. data/ext/pg_query/include/catalog/pg_statistic_ext.h +74 -0
  97. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +40 -0
  98. data/ext/pg_query/include/catalog/pg_transform.h +45 -0
  99. data/ext/pg_query/include/catalog/pg_transform_d.h +32 -0
  100. data/ext/pg_query/include/catalog/pg_trigger.h +137 -0
  101. data/ext/pg_query/include/catalog/pg_trigger_d.h +106 -0
  102. data/ext/pg_query/include/catalog/pg_ts_config.h +50 -0
  103. data/ext/pg_query/include/catalog/pg_ts_config_d.h +32 -0
  104. data/ext/pg_query/include/catalog/pg_ts_dict.h +54 -0
  105. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +33 -0
  106. data/ext/pg_query/include/catalog/pg_ts_parser.h +57 -0
  107. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +35 -0
  108. data/ext/pg_query/include/catalog/pg_ts_template.h +48 -0
  109. data/ext/pg_query/include/catalog/pg_ts_template_d.h +32 -0
  110. data/ext/pg_query/include/catalog/pg_type.h +372 -0
  111. data/ext/pg_query/include/catalog/pg_type_d.h +285 -0
  112. data/ext/pg_query/include/catalog/storage.h +48 -0
  113. data/ext/pg_query/include/commands/async.h +54 -0
  114. data/ext/pg_query/include/commands/dbcommands.h +35 -0
  115. data/ext/pg_query/include/commands/defrem.h +173 -0
  116. data/ext/pg_query/include/commands/event_trigger.h +88 -0
  117. data/ext/pg_query/include/commands/explain.h +127 -0
  118. data/ext/pg_query/include/commands/prepare.h +61 -0
  119. data/ext/pg_query/include/commands/tablespace.h +67 -0
  120. data/ext/pg_query/include/commands/trigger.h +277 -0
  121. data/ext/pg_query/include/commands/user.h +37 -0
  122. data/ext/pg_query/include/commands/vacuum.h +293 -0
  123. data/ext/pg_query/include/commands/variable.h +38 -0
  124. data/ext/pg_query/include/common/file_perm.h +56 -0
  125. data/ext/pg_query/include/common/hashfn.h +104 -0
  126. data/ext/pg_query/include/common/ip.h +37 -0
  127. data/ext/pg_query/include/common/keywords.h +33 -0
  128. data/ext/pg_query/include/common/kwlookup.h +44 -0
  129. data/ext/pg_query/include/common/relpath.h +90 -0
  130. data/ext/pg_query/include/common/string.h +19 -0
  131. data/ext/pg_query/include/common/unicode_combining_table.h +196 -0
  132. data/ext/pg_query/include/datatype/timestamp.h +197 -0
  133. data/ext/pg_query/include/executor/execdesc.h +70 -0
  134. data/ext/pg_query/include/executor/executor.h +614 -0
  135. data/ext/pg_query/include/executor/functions.h +41 -0
  136. data/ext/pg_query/include/executor/instrument.h +101 -0
  137. data/ext/pg_query/include/executor/spi.h +175 -0
  138. data/ext/pg_query/include/executor/tablefunc.h +67 -0
  139. data/ext/pg_query/include/executor/tuptable.h +487 -0
  140. data/ext/pg_query/include/fmgr.h +775 -0
  141. data/ext/pg_query/include/funcapi.h +348 -0
  142. data/ext/pg_query/include/getaddrinfo.h +162 -0
  143. data/ext/pg_query/include/jit/jit.h +105 -0
  144. data/ext/pg_query/include/kwlist_d.h +1072 -0
  145. data/ext/pg_query/include/lib/ilist.h +727 -0
  146. data/ext/pg_query/include/lib/pairingheap.h +102 -0
  147. data/ext/pg_query/include/lib/simplehash.h +1059 -0
  148. data/ext/pg_query/include/lib/stringinfo.h +161 -0
  149. data/ext/pg_query/include/libpq/auth.h +29 -0
  150. data/ext/pg_query/include/libpq/crypt.h +46 -0
  151. data/ext/pg_query/include/libpq/hba.h +140 -0
  152. data/ext/pg_query/include/libpq/libpq-be.h +326 -0
  153. data/ext/pg_query/include/libpq/libpq.h +133 -0
  154. data/ext/pg_query/include/libpq/pqcomm.h +208 -0
  155. data/ext/pg_query/include/libpq/pqformat.h +210 -0
  156. data/ext/pg_query/include/libpq/pqsignal.h +42 -0
  157. data/ext/pg_query/include/mb/pg_wchar.h +672 -0
  158. data/ext/pg_query/include/mb/stringinfo_mb.h +24 -0
  159. data/ext/pg_query/include/miscadmin.h +476 -0
  160. data/ext/pg_query/include/nodes/bitmapset.h +122 -0
  161. data/ext/pg_query/include/nodes/execnodes.h +2520 -0
  162. data/ext/pg_query/include/nodes/extensible.h +160 -0
  163. data/ext/pg_query/include/nodes/lockoptions.h +61 -0
  164. data/ext/pg_query/include/nodes/makefuncs.h +108 -0
  165. data/ext/pg_query/include/nodes/memnodes.h +108 -0
  166. data/ext/pg_query/include/nodes/nodeFuncs.h +162 -0
  167. data/ext/pg_query/include/nodes/nodes.h +842 -0
  168. data/ext/pg_query/include/nodes/params.h +170 -0
  169. data/ext/pg_query/include/nodes/parsenodes.h +3579 -0
  170. data/ext/pg_query/include/nodes/pathnodes.h +2556 -0
  171. data/ext/pg_query/include/nodes/pg_list.h +605 -0
  172. data/ext/pg_query/include/nodes/plannodes.h +1251 -0
  173. data/ext/pg_query/include/nodes/primnodes.h +1541 -0
  174. data/ext/pg_query/include/nodes/print.h +34 -0
  175. data/ext/pg_query/include/nodes/tidbitmap.h +75 -0
  176. data/ext/pg_query/include/nodes/value.h +61 -0
  177. data/ext/pg_query/include/optimizer/cost.h +206 -0
  178. data/ext/pg_query/include/optimizer/geqo.h +88 -0
  179. data/ext/pg_query/include/optimizer/geqo_gene.h +45 -0
  180. data/ext/pg_query/include/optimizer/optimizer.h +199 -0
  181. data/ext/pg_query/include/optimizer/paths.h +249 -0
  182. data/ext/pg_query/include/optimizer/planmain.h +119 -0
  183. data/ext/pg_query/include/parser/analyze.h +49 -0
  184. data/ext/pg_query/include/parser/gram.h +1067 -0
  185. data/ext/pg_query/include/parser/gramparse.h +75 -0
  186. data/ext/pg_query/include/parser/kwlist.h +477 -0
  187. data/ext/pg_query/include/parser/parse_agg.h +68 -0
  188. data/ext/pg_query/include/parser/parse_clause.h +54 -0
  189. data/ext/pg_query/include/parser/parse_coerce.h +97 -0
  190. data/ext/pg_query/include/parser/parse_collate.h +27 -0
  191. data/ext/pg_query/include/parser/parse_expr.h +26 -0
  192. data/ext/pg_query/include/parser/parse_func.h +73 -0
  193. data/ext/pg_query/include/parser/parse_node.h +327 -0
  194. data/ext/pg_query/include/parser/parse_oper.h +67 -0
  195. data/ext/pg_query/include/parser/parse_relation.h +123 -0
  196. data/ext/pg_query/include/parser/parse_target.h +46 -0
  197. data/ext/pg_query/include/parser/parse_type.h +60 -0
  198. data/ext/pg_query/include/parser/parser.h +41 -0
  199. data/ext/pg_query/include/parser/parsetree.h +61 -0
  200. data/ext/pg_query/include/parser/scanner.h +152 -0
  201. data/ext/pg_query/include/parser/scansup.h +30 -0
  202. data/ext/pg_query/include/partitioning/partdefs.h +26 -0
  203. data/ext/pg_query/include/pg_config.h +989 -0
  204. data/ext/pg_query/include/pg_config_ext.h +8 -0
  205. data/ext/pg_query/include/pg_config_manual.h +350 -0
  206. data/ext/pg_query/include/pg_config_os.h +8 -0
  207. data/ext/pg_query/include/pg_getopt.h +56 -0
  208. data/ext/pg_query/include/pg_query.h +121 -0
  209. data/ext/pg_query/include/pg_query_enum_defs.c +2454 -0
  210. data/ext/pg_query/include/pg_query_fingerprint_conds.c +875 -0
  211. data/ext/pg_query/include/pg_query_fingerprint_defs.c +12413 -0
  212. data/ext/pg_query/include/pg_query_json_helper.c +61 -0
  213. data/ext/pg_query/include/pg_query_outfuncs_conds.c +686 -0
  214. data/ext/pg_query/include/pg_query_outfuncs_defs.c +2437 -0
  215. data/ext/pg_query/include/pg_query_readfuncs_conds.c +222 -0
  216. data/ext/pg_query/include/pg_query_readfuncs_defs.c +2878 -0
  217. data/ext/pg_query/include/pg_trace.h +17 -0
  218. data/ext/pg_query/include/pgstat.h +1487 -0
  219. data/ext/pg_query/include/pgtime.h +84 -0
  220. data/ext/pg_query/include/pl_gram.h +385 -0
  221. data/ext/pg_query/include/pl_reserved_kwlist.h +52 -0
  222. data/ext/pg_query/include/pl_reserved_kwlist_d.h +114 -0
  223. data/ext/pg_query/include/pl_unreserved_kwlist.h +112 -0
  224. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +246 -0
  225. data/ext/pg_query/include/plerrcodes.h +990 -0
  226. data/ext/pg_query/include/plpgsql.h +1347 -0
  227. data/ext/pg_query/include/port.h +524 -0
  228. data/ext/pg_query/include/port/atomics.h +524 -0
  229. data/ext/pg_query/include/port/atomics/arch-arm.h +26 -0
  230. data/ext/pg_query/include/port/atomics/arch-ppc.h +254 -0
  231. data/ext/pg_query/include/port/atomics/arch-x86.h +252 -0
  232. data/ext/pg_query/include/port/atomics/fallback.h +170 -0
  233. data/ext/pg_query/include/port/atomics/generic-gcc.h +286 -0
  234. data/ext/pg_query/include/port/atomics/generic.h +401 -0
  235. data/ext/pg_query/include/port/pg_bitutils.h +226 -0
  236. data/ext/pg_query/include/port/pg_bswap.h +161 -0
  237. data/ext/pg_query/include/port/pg_crc32c.h +101 -0
  238. data/ext/pg_query/include/portability/instr_time.h +256 -0
  239. data/ext/pg_query/include/postgres.h +764 -0
  240. data/ext/pg_query/include/postgres_ext.h +74 -0
  241. data/ext/pg_query/include/postmaster/autovacuum.h +83 -0
  242. data/ext/pg_query/include/postmaster/bgworker.h +161 -0
  243. data/ext/pg_query/include/postmaster/bgworker_internals.h +64 -0
  244. data/ext/pg_query/include/postmaster/bgwriter.h +45 -0
  245. data/ext/pg_query/include/postmaster/fork_process.h +17 -0
  246. data/ext/pg_query/include/postmaster/interrupt.h +32 -0
  247. data/ext/pg_query/include/postmaster/pgarch.h +39 -0
  248. data/ext/pg_query/include/postmaster/postmaster.h +77 -0
  249. data/ext/pg_query/include/postmaster/syslogger.h +98 -0
  250. data/ext/pg_query/include/postmaster/walwriter.h +21 -0
  251. data/ext/pg_query/include/protobuf-c.h +1106 -0
  252. data/ext/pg_query/include/protobuf-c/protobuf-c.h +1106 -0
  253. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +10846 -0
  254. data/ext/pg_query/include/protobuf/pg_query.pb.h +124718 -0
  255. data/ext/pg_query/include/regex/regex.h +184 -0
  256. data/ext/pg_query/include/replication/logicallauncher.h +31 -0
  257. data/ext/pg_query/include/replication/logicalproto.h +110 -0
  258. data/ext/pg_query/include/replication/logicalworker.h +19 -0
  259. data/ext/pg_query/include/replication/origin.h +73 -0
  260. data/ext/pg_query/include/replication/reorderbuffer.h +467 -0
  261. data/ext/pg_query/include/replication/slot.h +219 -0
  262. data/ext/pg_query/include/replication/syncrep.h +115 -0
  263. data/ext/pg_query/include/replication/walreceiver.h +340 -0
  264. data/ext/pg_query/include/replication/walsender.h +74 -0
  265. data/ext/pg_query/include/rewrite/prs2lock.h +46 -0
  266. data/ext/pg_query/include/rewrite/rewriteHandler.h +40 -0
  267. data/ext/pg_query/include/rewrite/rewriteManip.h +87 -0
  268. data/ext/pg_query/include/rewrite/rewriteSupport.h +26 -0
  269. data/ext/pg_query/include/storage/backendid.h +37 -0
  270. data/ext/pg_query/include/storage/block.h +121 -0
  271. data/ext/pg_query/include/storage/buf.h +46 -0
  272. data/ext/pg_query/include/storage/bufmgr.h +292 -0
  273. data/ext/pg_query/include/storage/bufpage.h +459 -0
  274. data/ext/pg_query/include/storage/condition_variable.h +62 -0
  275. data/ext/pg_query/include/storage/dsm.h +61 -0
  276. data/ext/pg_query/include/storage/dsm_impl.h +75 -0
  277. data/ext/pg_query/include/storage/fd.h +168 -0
  278. data/ext/pg_query/include/storage/ipc.h +81 -0
  279. data/ext/pg_query/include/storage/item.h +19 -0
  280. data/ext/pg_query/include/storage/itemid.h +184 -0
  281. data/ext/pg_query/include/storage/itemptr.h +206 -0
  282. data/ext/pg_query/include/storage/large_object.h +100 -0
  283. data/ext/pg_query/include/storage/latch.h +190 -0
  284. data/ext/pg_query/include/storage/lmgr.h +114 -0
  285. data/ext/pg_query/include/storage/lock.h +612 -0
  286. data/ext/pg_query/include/storage/lockdefs.h +59 -0
  287. data/ext/pg_query/include/storage/lwlock.h +232 -0
  288. data/ext/pg_query/include/storage/lwlocknames.h +51 -0
  289. data/ext/pg_query/include/storage/off.h +57 -0
  290. data/ext/pg_query/include/storage/pg_sema.h +61 -0
  291. data/ext/pg_query/include/storage/pg_shmem.h +90 -0
  292. data/ext/pg_query/include/storage/pmsignal.h +94 -0
  293. data/ext/pg_query/include/storage/predicate.h +87 -0
  294. data/ext/pg_query/include/storage/proc.h +333 -0
  295. data/ext/pg_query/include/storage/proclist_types.h +51 -0
  296. data/ext/pg_query/include/storage/procsignal.h +75 -0
  297. data/ext/pg_query/include/storage/relfilenode.h +99 -0
  298. data/ext/pg_query/include/storage/s_lock.h +1047 -0
  299. data/ext/pg_query/include/storage/sharedfileset.h +45 -0
  300. data/ext/pg_query/include/storage/shm_mq.h +85 -0
  301. data/ext/pg_query/include/storage/shm_toc.h +58 -0
  302. data/ext/pg_query/include/storage/shmem.h +81 -0
  303. data/ext/pg_query/include/storage/sinval.h +153 -0
  304. data/ext/pg_query/include/storage/sinvaladt.h +43 -0
  305. data/ext/pg_query/include/storage/smgr.h +109 -0
  306. data/ext/pg_query/include/storage/spin.h +77 -0
  307. data/ext/pg_query/include/storage/standby.h +91 -0
  308. data/ext/pg_query/include/storage/standbydefs.h +74 -0
  309. data/ext/pg_query/include/storage/sync.h +62 -0
  310. data/ext/pg_query/include/tcop/cmdtag.h +58 -0
  311. data/ext/pg_query/include/tcop/cmdtaglist.h +217 -0
  312. data/ext/pg_query/include/tcop/deparse_utility.h +108 -0
  313. data/ext/pg_query/include/tcop/dest.h +149 -0
  314. data/ext/pg_query/include/tcop/fastpath.h +21 -0
  315. data/ext/pg_query/include/tcop/pquery.h +45 -0
  316. data/ext/pg_query/include/tcop/tcopprot.h +89 -0
  317. data/ext/pg_query/include/tcop/utility.h +108 -0
  318. data/ext/pg_query/include/tsearch/ts_cache.h +98 -0
  319. data/ext/pg_query/include/utils/acl.h +312 -0
  320. data/ext/pg_query/include/utils/aclchk_internal.h +45 -0
  321. data/ext/pg_query/include/utils/array.h +458 -0
  322. data/ext/pg_query/include/utils/builtins.h +127 -0
  323. data/ext/pg_query/include/utils/bytea.h +27 -0
  324. data/ext/pg_query/include/utils/catcache.h +231 -0
  325. data/ext/pg_query/include/utils/date.h +90 -0
  326. data/ext/pg_query/include/utils/datetime.h +343 -0
  327. data/ext/pg_query/include/utils/datum.h +68 -0
  328. data/ext/pg_query/include/utils/dsa.h +123 -0
  329. data/ext/pg_query/include/utils/dynahash.h +19 -0
  330. data/ext/pg_query/include/utils/elog.h +439 -0
  331. data/ext/pg_query/include/utils/errcodes.h +352 -0
  332. data/ext/pg_query/include/utils/expandeddatum.h +159 -0
  333. data/ext/pg_query/include/utils/expandedrecord.h +231 -0
  334. data/ext/pg_query/include/utils/float.h +356 -0
  335. data/ext/pg_query/include/utils/fmgroids.h +2657 -0
  336. data/ext/pg_query/include/utils/fmgrprotos.h +2646 -0
  337. data/ext/pg_query/include/utils/fmgrtab.h +48 -0
  338. data/ext/pg_query/include/utils/guc.h +443 -0
  339. data/ext/pg_query/include/utils/guc_tables.h +272 -0
  340. data/ext/pg_query/include/utils/hsearch.h +149 -0
  341. data/ext/pg_query/include/utils/inval.h +64 -0
  342. data/ext/pg_query/include/utils/lsyscache.h +197 -0
  343. data/ext/pg_query/include/utils/memdebug.h +82 -0
  344. data/ext/pg_query/include/utils/memutils.h +225 -0
  345. data/ext/pg_query/include/utils/numeric.h +76 -0
  346. data/ext/pg_query/include/utils/palloc.h +136 -0
  347. data/ext/pg_query/include/utils/partcache.h +102 -0
  348. data/ext/pg_query/include/utils/pg_locale.h +119 -0
  349. data/ext/pg_query/include/utils/pg_lsn.h +29 -0
  350. data/ext/pg_query/include/utils/pidfile.h +56 -0
  351. data/ext/pg_query/include/utils/plancache.h +235 -0
  352. data/ext/pg_query/include/utils/portal.h +241 -0
  353. data/ext/pg_query/include/utils/probes.h +114 -0
  354. data/ext/pg_query/include/utils/ps_status.h +25 -0
  355. data/ext/pg_query/include/utils/queryenvironment.h +74 -0
  356. data/ext/pg_query/include/utils/regproc.h +28 -0
  357. data/ext/pg_query/include/utils/rel.h +644 -0
  358. data/ext/pg_query/include/utils/relcache.h +151 -0
  359. data/ext/pg_query/include/utils/reltrigger.h +81 -0
  360. data/ext/pg_query/include/utils/resowner.h +86 -0
  361. data/ext/pg_query/include/utils/rls.h +50 -0
  362. data/ext/pg_query/include/utils/ruleutils.h +44 -0
  363. data/ext/pg_query/include/utils/sharedtuplestore.h +61 -0
  364. data/ext/pg_query/include/utils/snapmgr.h +158 -0
  365. data/ext/pg_query/include/utils/snapshot.h +206 -0
  366. data/ext/pg_query/include/utils/sortsupport.h +276 -0
  367. data/ext/pg_query/include/utils/syscache.h +219 -0
  368. data/ext/pg_query/include/utils/timeout.h +88 -0
  369. data/ext/pg_query/include/utils/timestamp.h +116 -0
  370. data/ext/pg_query/include/utils/tuplesort.h +277 -0
  371. data/ext/pg_query/include/utils/tuplestore.h +91 -0
  372. data/ext/pg_query/include/utils/typcache.h +202 -0
  373. data/ext/pg_query/include/utils/tzparser.h +39 -0
  374. data/ext/pg_query/include/utils/varlena.h +39 -0
  375. data/ext/pg_query/include/utils/xml.h +84 -0
  376. data/ext/pg_query/include/xxhash.h +5445 -0
  377. data/ext/pg_query/include/xxhash/xxhash.h +5445 -0
  378. data/ext/pg_query/pg_query.c +104 -0
  379. data/ext/pg_query/pg_query.pb-c.c +37628 -0
  380. data/ext/pg_query/pg_query_deparse.c +9959 -0
  381. data/ext/pg_query/pg_query_fingerprint.c +295 -0
  382. data/ext/pg_query/pg_query_fingerprint.h +8 -0
  383. data/ext/pg_query/pg_query_internal.h +24 -0
  384. data/ext/pg_query/pg_query_json_plpgsql.c +738 -0
  385. data/ext/pg_query/pg_query_json_plpgsql.h +9 -0
  386. data/ext/pg_query/pg_query_normalize.c +439 -0
  387. data/ext/pg_query/pg_query_outfuncs.h +10 -0
  388. data/ext/pg_query/pg_query_outfuncs_json.c +297 -0
  389. data/ext/pg_query/pg_query_outfuncs_protobuf.c +237 -0
  390. data/ext/pg_query/pg_query_parse.c +148 -0
  391. data/ext/pg_query/pg_query_parse_plpgsql.c +460 -0
  392. data/ext/pg_query/pg_query_readfuncs.h +11 -0
  393. data/ext/pg_query/pg_query_readfuncs_protobuf.c +142 -0
  394. data/ext/pg_query/pg_query_ruby.c +108 -12
  395. data/ext/pg_query/pg_query_scan.c +173 -0
  396. data/ext/pg_query/pg_query_split.c +221 -0
  397. data/ext/pg_query/protobuf-c.c +3660 -0
  398. data/ext/pg_query/src_backend_catalog_namespace.c +1051 -0
  399. data/ext/pg_query/src_backend_catalog_pg_proc.c +142 -0
  400. data/ext/pg_query/src_backend_commands_define.c +117 -0
  401. data/ext/pg_query/src_backend_libpq_pqcomm.c +651 -0
  402. data/ext/pg_query/src_backend_nodes_bitmapset.c +513 -0
  403. data/ext/pg_query/src_backend_nodes_copyfuncs.c +6013 -0
  404. data/ext/pg_query/src_backend_nodes_equalfuncs.c +4003 -0
  405. data/ext/pg_query/src_backend_nodes_extensible.c +99 -0
  406. data/ext/pg_query/src_backend_nodes_list.c +922 -0
  407. data/ext/pg_query/src_backend_nodes_makefuncs.c +417 -0
  408. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +1363 -0
  409. data/ext/pg_query/src_backend_nodes_value.c +84 -0
  410. data/ext/pg_query/src_backend_parser_gram.c +47456 -0
  411. data/ext/pg_query/src_backend_parser_parse_expr.c +313 -0
  412. data/ext/pg_query/src_backend_parser_parser.c +497 -0
  413. data/ext/pg_query/src_backend_parser_scan.c +7091 -0
  414. data/ext/pg_query/src_backend_parser_scansup.c +160 -0
  415. data/ext/pg_query/src_backend_postmaster_postmaster.c +2230 -0
  416. data/ext/pg_query/src_backend_storage_ipc_ipc.c +192 -0
  417. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +370 -0
  418. data/ext/pg_query/src_backend_tcop_postgres.c +776 -0
  419. data/ext/pg_query/src_backend_utils_adt_datum.c +326 -0
  420. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +98 -0
  421. data/ext/pg_query/src_backend_utils_adt_format_type.c +136 -0
  422. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +1683 -0
  423. data/ext/pg_query/src_backend_utils_error_assert.c +74 -0
  424. data/ext/pg_query/src_backend_utils_error_elog.c +1748 -0
  425. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +570 -0
  426. data/ext/pg_query/src_backend_utils_hash_dynahash.c +1086 -0
  427. data/ext/pg_query/src_backend_utils_init_globals.c +168 -0
  428. data/ext/pg_query/src_backend_utils_mb_mbutils.c +839 -0
  429. data/ext/pg_query/src_backend_utils_misc_guc.c +1831 -0
  430. data/ext/pg_query/src_backend_utils_mmgr_aset.c +1560 -0
  431. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +1006 -0
  432. data/ext/pg_query/src_common_encnames.c +158 -0
  433. data/ext/pg_query/src_common_keywords.c +39 -0
  434. data/ext/pg_query/src_common_kwlist_d.h +1081 -0
  435. data/ext/pg_query/src_common_kwlookup.c +91 -0
  436. data/ext/pg_query/src_common_psprintf.c +158 -0
  437. data/ext/pg_query/src_common_string.c +86 -0
  438. data/ext/pg_query/src_common_stringinfo.c +336 -0
  439. data/ext/pg_query/src_common_wchar.c +1651 -0
  440. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +1133 -0
  441. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +877 -0
  442. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +6533 -0
  443. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +107 -0
  444. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +123 -0
  445. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +671 -0
  446. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +255 -0
  447. data/ext/pg_query/src_port_erand48.c +127 -0
  448. data/ext/pg_query/src_port_pg_bitutils.c +246 -0
  449. data/ext/pg_query/src_port_pgsleep.c +69 -0
  450. data/ext/pg_query/src_port_pgstrcasecmp.c +83 -0
  451. data/ext/pg_query/src_port_qsort.c +240 -0
  452. data/ext/pg_query/src_port_random.c +31 -0
  453. data/ext/pg_query/src_port_snprintf.c +1449 -0
  454. data/ext/pg_query/src_port_strerror.c +324 -0
  455. data/ext/pg_query/src_port_strnlen.c +39 -0
  456. data/ext/pg_query/xxhash.c +43 -0
  457. data/lib/pg_query.rb +7 -4
  458. data/lib/pg_query/constants.rb +21 -0
  459. data/lib/pg_query/deparse.rb +15 -1581
  460. data/lib/pg_query/filter_columns.rb +88 -85
  461. data/lib/pg_query/fingerprint.rb +122 -87
  462. data/lib/pg_query/json_field_names.rb +1402 -0
  463. data/lib/pg_query/node.rb +31 -0
  464. data/lib/pg_query/param_refs.rb +42 -37
  465. data/lib/pg_query/parse.rb +220 -203
  466. data/lib/pg_query/parse_error.rb +1 -1
  467. data/lib/pg_query/pg_query_pb.rb +3211 -0
  468. data/lib/pg_query/scan.rb +23 -0
  469. data/lib/pg_query/treewalker.rb +24 -40
  470. data/lib/pg_query/truncate.rb +71 -42
  471. data/lib/pg_query/version.rb +2 -2
  472. metadata +472 -11
  473. data/ext/pg_query/pg_query_ruby.h +0 -10
  474. data/lib/pg_query/deep_dup.rb +0 -16
  475. data/lib/pg_query/deparse/alter_table.rb +0 -42
  476. data/lib/pg_query/deparse/interval.rb +0 -105
  477. data/lib/pg_query/deparse/keywords.rb +0 -159
  478. data/lib/pg_query/deparse/rename.rb +0 -41
  479. data/lib/pg_query/legacy_parsetree.rb +0 -109
  480. data/lib/pg_query/node_types.rb +0 -296
@@ -0,0 +1,69 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - pg_usleep
4
+ *--------------------------------------------------------------------
5
+ */
6
+
7
+ /*-------------------------------------------------------------------------
8
+ *
9
+ * pgsleep.c
10
+ * Portable delay handling.
11
+ *
12
+ *
13
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
14
+ *
15
+ * src/port/pgsleep.c
16
+ *
17
+ *-------------------------------------------------------------------------
18
+ */
19
+ #include "c.h"
20
+
21
+ #include <unistd.h>
22
+ #include <sys/time.h>
23
+ #ifdef HAVE_SYS_SELECT_H
24
+ #include <sys/select.h>
25
+ #endif
26
+
27
+ /*
28
+ * In a Windows backend, we don't use this implementation, but rather
29
+ * the signal-aware version in src/backend/port/win32/signal.c.
30
+ */
31
+ #if defined(FRONTEND) || !defined(WIN32)
32
+
33
+ /*
34
+ * pg_usleep --- delay the specified number of microseconds.
35
+ *
36
+ * NOTE: although the delay is specified in microseconds, the effective
37
+ * resolution is only 1/HZ, or 10 milliseconds, on most Unixen. Expect
38
+ * the requested delay to be rounded up to the next resolution boundary.
39
+ *
40
+ * On machines where "long" is 32 bits, the maximum delay is ~2000 seconds.
41
+ *
42
+ * CAUTION: the behavior when a signal arrives during the sleep is platform
43
+ * dependent. On most Unix-ish platforms, a signal does not terminate the
44
+ * sleep; but on some, it will (the Windows implementation also allows signals
45
+ * to terminate pg_usleep). And there are platforms where not only does a
46
+ * signal not terminate the sleep, but it actually resets the timeout counter
47
+ * so that the sleep effectively starts over! It is therefore rather hazardous
48
+ * to use this for long sleeps; a continuing stream of signal events could
49
+ * prevent the sleep from ever terminating. Better practice for long sleeps
50
+ * is to use WaitLatch() with a timeout.
51
+ */
52
+ void
53
+ pg_usleep(long microsec)
54
+ {
55
+ if (microsec > 0)
56
+ {
57
+ #ifndef WIN32
58
+ struct timeval delay;
59
+
60
+ delay.tv_sec = microsec / 1000000L;
61
+ delay.tv_usec = microsec % 1000000L;
62
+ (void) select(0, NULL, NULL, NULL, &delay);
63
+ #else
64
+ SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE);
65
+ #endif
66
+ }
67
+ }
68
+
69
+ #endif /* defined(FRONTEND) || !defined(WIN32) */
@@ -0,0 +1,83 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - pg_toupper
4
+ *--------------------------------------------------------------------
5
+ */
6
+
7
+ /*-------------------------------------------------------------------------
8
+ *
9
+ * pgstrcasecmp.c
10
+ * Portable SQL-like case-independent comparisons and conversions.
11
+ *
12
+ * SQL99 specifies Unicode-aware case normalization, which we don't yet
13
+ * have the infrastructure for. Instead we use tolower() to provide a
14
+ * locale-aware translation. However, there are some locales where this
15
+ * is not right either (eg, Turkish may do strange things with 'i' and
16
+ * 'I'). Our current compromise is to use tolower() for characters with
17
+ * the high bit set, and use an ASCII-only downcasing for 7-bit
18
+ * characters.
19
+ *
20
+ * NB: this code should match downcase_truncate_identifier() in scansup.c.
21
+ *
22
+ * We also provide strict ASCII-only case conversion functions, which can
23
+ * be used to implement C/POSIX case folding semantics no matter what the
24
+ * C library thinks the locale is.
25
+ *
26
+ *
27
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
28
+ *
29
+ * src/port/pgstrcasecmp.c
30
+ *
31
+ *-------------------------------------------------------------------------
32
+ */
33
+ #include "c.h"
34
+
35
+ #include <ctype.h>
36
+
37
+
38
+ /*
39
+ * Case-independent comparison of two null-terminated strings.
40
+ */
41
+
42
+
43
+ /*
44
+ * Case-independent comparison of two not-necessarily-null-terminated strings.
45
+ * At most n bytes will be examined from each string.
46
+ */
47
+
48
+
49
+ /*
50
+ * Fold a character to upper case.
51
+ *
52
+ * Unlike some versions of toupper(), this is safe to apply to characters
53
+ * that aren't lower case letters. Note however that the whole thing is
54
+ * a bit bogus for multibyte character sets.
55
+ */
56
+ unsigned char
57
+ pg_toupper(unsigned char ch)
58
+ {
59
+ if (ch >= 'a' && ch <= 'z')
60
+ ch += 'A' - 'a';
61
+ else if (IS_HIGHBIT_SET(ch) && islower(ch))
62
+ ch = toupper(ch);
63
+ return ch;
64
+ }
65
+
66
+ /*
67
+ * Fold a character to lower case.
68
+ *
69
+ * Unlike some versions of tolower(), this is safe to apply to characters
70
+ * that aren't upper case letters. Note however that the whole thing is
71
+ * a bit bogus for multibyte character sets.
72
+ */
73
+
74
+
75
+ /*
76
+ * Fold a character to upper case, following C/POSIX locale rules.
77
+ */
78
+
79
+
80
+ /*
81
+ * Fold a character to lower case, following C/POSIX locale rules.
82
+ */
83
+
@@ -0,0 +1,240 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - pg_qsort
4
+ * - pg_qsort
5
+ * - swapfunc
6
+ * - med3
7
+ *--------------------------------------------------------------------
8
+ */
9
+
10
+ /*
11
+ * qsort.c: standard quicksort algorithm
12
+ *
13
+ * Modifications from vanilla NetBSD source:
14
+ * Add do ... while() macro fix
15
+ * Remove __inline, _DIAGASSERTs, __P
16
+ * Remove ill-considered "swap_cnt" switch to insertion sort,
17
+ * in favor of a simple check for presorted input.
18
+ * Take care to recurse on the smaller partition, to bound stack usage.
19
+ *
20
+ * CAUTION: if you change this file, see also qsort_arg.c, gen_qsort_tuple.pl
21
+ *
22
+ * src/port/qsort.c
23
+ */
24
+
25
+ /* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
26
+
27
+ /*-
28
+ * Copyright (c) 1992, 1993
29
+ * The Regents of the University of California. All rights reserved.
30
+ *
31
+ * Redistribution and use in source and binary forms, with or without
32
+ * modification, are permitted provided that the following conditions
33
+ * are met:
34
+ * 1. Redistributions of source code must retain the above copyright
35
+ * notice, this list of conditions and the following disclaimer.
36
+ * 2. Redistributions in binary form must reproduce the above copyright
37
+ * notice, this list of conditions and the following disclaimer in the
38
+ * documentation and/or other materials provided with the distribution.
39
+ * 3. Neither the name of the University nor the names of its contributors
40
+ * may be used to endorse or promote products derived from this software
41
+ * without specific prior written permission.
42
+ *
43
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53
+ * SUCH DAMAGE.
54
+ */
55
+
56
+ #include "c.h"
57
+
58
+
59
+ static char *med3(char *a, char *b, char *c,
60
+ int (*cmp) (const void *, const void *));
61
+ static void swapfunc(char *, char *, size_t, int);
62
+
63
+ /*
64
+ * Qsort routine based on J. L. Bentley and M. D. McIlroy,
65
+ * "Engineering a sort function",
66
+ * Software--Practice and Experience 23 (1993) 1249-1265.
67
+ *
68
+ * We have modified their original by adding a check for already-sorted input,
69
+ * which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
70
+ *
71
+ * Also, we recurse on the smaller partition and iterate on the larger one,
72
+ * which ensures we cannot recurse more than log(N) levels (since the
73
+ * partition recursed to is surely no more than half of the input). Bentley
74
+ * and McIlroy explicitly rejected doing this on the grounds that it's "not
75
+ * worth the effort", but we have seen crashes in the field due to stack
76
+ * overrun, so that judgment seems wrong.
77
+ */
78
+
79
+ #define swapcode(TYPE, parmi, parmj, n) \
80
+ do { \
81
+ size_t i = (n) / sizeof (TYPE); \
82
+ TYPE *pi = (TYPE *)(void *)(parmi); \
83
+ TYPE *pj = (TYPE *)(void *)(parmj); \
84
+ do { \
85
+ TYPE t = *pi; \
86
+ *pi++ = *pj; \
87
+ *pj++ = t; \
88
+ } while (--i > 0); \
89
+ } while (0)
90
+
91
+ #define SWAPINIT(a, es) swaptype = ((char *)(a) - (char *)0) % sizeof(long) || \
92
+ (es) % sizeof(long) ? 2 : (es) == sizeof(long)? 0 : 1
93
+
94
+ static void
95
+ swapfunc(char *a, char *b, size_t n, int swaptype)
96
+ {
97
+ if (swaptype <= 1)
98
+ swapcode(long, a, b, n);
99
+ else
100
+ swapcode(char, a, b, n);
101
+ }
102
+
103
+ #define swap(a, b) \
104
+ if (swaptype == 0) { \
105
+ long t = *(long *)(void *)(a); \
106
+ *(long *)(void *)(a) = *(long *)(void *)(b); \
107
+ *(long *)(void *)(b) = t; \
108
+ } else \
109
+ swapfunc(a, b, es, swaptype)
110
+
111
+ #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
112
+
113
+ static char *
114
+ med3(char *a, char *b, char *c, int (*cmp) (const void *, const void *))
115
+ {
116
+ return cmp(a, b) < 0 ?
117
+ (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a))
118
+ : (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c));
119
+ }
120
+
121
+ void
122
+ pg_qsort(void *a, size_t n, size_t es, int (*cmp) (const void *, const void *))
123
+ {
124
+ char *pa,
125
+ *pb,
126
+ *pc,
127
+ *pd,
128
+ *pl,
129
+ *pm,
130
+ *pn;
131
+ size_t d1,
132
+ d2;
133
+ int r,
134
+ swaptype,
135
+ presorted;
136
+
137
+ loop:SWAPINIT(a, es);
138
+ if (n < 7)
139
+ {
140
+ for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
141
+ for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
142
+ pl -= es)
143
+ swap(pl, pl - es);
144
+ return;
145
+ }
146
+ presorted = 1;
147
+ for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
148
+ {
149
+ if (cmp(pm - es, pm) > 0)
150
+ {
151
+ presorted = 0;
152
+ break;
153
+ }
154
+ }
155
+ if (presorted)
156
+ return;
157
+ pm = (char *) a + (n / 2) * es;
158
+ if (n > 7)
159
+ {
160
+ pl = (char *) a;
161
+ pn = (char *) a + (n - 1) * es;
162
+ if (n > 40)
163
+ {
164
+ size_t d = (n / 8) * es;
165
+
166
+ pl = med3(pl, pl + d, pl + 2 * d, cmp);
167
+ pm = med3(pm - d, pm, pm + d, cmp);
168
+ pn = med3(pn - 2 * d, pn - d, pn, cmp);
169
+ }
170
+ pm = med3(pl, pm, pn, cmp);
171
+ }
172
+ swap(a, pm);
173
+ pa = pb = (char *) a + es;
174
+ pc = pd = (char *) a + (n - 1) * es;
175
+ for (;;)
176
+ {
177
+ while (pb <= pc && (r = cmp(pb, a)) <= 0)
178
+ {
179
+ if (r == 0)
180
+ {
181
+ swap(pa, pb);
182
+ pa += es;
183
+ }
184
+ pb += es;
185
+ }
186
+ while (pb <= pc && (r = cmp(pc, a)) >= 0)
187
+ {
188
+ if (r == 0)
189
+ {
190
+ swap(pc, pd);
191
+ pd -= es;
192
+ }
193
+ pc -= es;
194
+ }
195
+ if (pb > pc)
196
+ break;
197
+ swap(pb, pc);
198
+ pb += es;
199
+ pc -= es;
200
+ }
201
+ pn = (char *) a + n * es;
202
+ d1 = Min(pa - (char *) a, pb - pa);
203
+ vecswap(a, pb - d1, d1);
204
+ d1 = Min(pd - pc, pn - pd - es);
205
+ vecswap(pb, pn - d1, d1);
206
+ d1 = pb - pa;
207
+ d2 = pd - pc;
208
+ if (d1 <= d2)
209
+ {
210
+ /* Recurse on left partition, then iterate on right partition */
211
+ if (d1 > es)
212
+ pg_qsort(a, d1 / es, es, cmp);
213
+ if (d2 > es)
214
+ {
215
+ /* Iterate rather than recurse to save stack space */
216
+ /* pg_qsort(pn - d2, d2 / es, es, cmp); */
217
+ a = pn - d2;
218
+ n = d2 / es;
219
+ goto loop;
220
+ }
221
+ }
222
+ else
223
+ {
224
+ /* Recurse on right partition, then iterate on left partition */
225
+ if (d2 > es)
226
+ pg_qsort(pn - d2, d2 / es, es, cmp);
227
+ if (d1 > es)
228
+ {
229
+ /* Iterate rather than recurse to save stack space */
230
+ /* pg_qsort(a, d1 / es, es, cmp); */
231
+ n = d1 / es;
232
+ goto loop;
233
+ }
234
+ }
235
+ }
236
+
237
+ /*
238
+ * qsort comparator wrapper for strcmp.
239
+ */
240
+
@@ -0,0 +1,31 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - random
4
+ *--------------------------------------------------------------------
5
+ */
6
+
7
+ /*-------------------------------------------------------------------------
8
+ *
9
+ * random.c
10
+ * random() wrapper
11
+ *
12
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
13
+ * Portions Copyright (c) 1994, Regents of the University of California
14
+ *
15
+ *
16
+ * IDENTIFICATION
17
+ * src/port/random.c
18
+ *
19
+ *-------------------------------------------------------------------------
20
+ */
21
+
22
+ #include "c.h"
23
+
24
+ #include <math.h>
25
+
26
+
27
+ long
28
+ random(void)
29
+ {
30
+ return pg_lrand48();
31
+ }
@@ -0,0 +1,1449 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - pg_vfprintf
4
+ * - dopr
5
+ * - pg_snprintf
6
+ * - pg_vsnprintf
7
+ * - strchrnul
8
+ * - dostr
9
+ * - find_arguments
10
+ * - fmtint
11
+ * - adjust_sign
12
+ * - compute_padlen
13
+ * - leading_pad
14
+ * - dopr_outchmulti
15
+ * - trailing_pad
16
+ * - fmtchar
17
+ * - fmtstr
18
+ * - fmtptr
19
+ * - fmtfloat
20
+ * - dopr_outch
21
+ * - flushbuffer
22
+ * - pg_fprintf
23
+ * - pg_sprintf
24
+ * - pg_vsprintf
25
+ * - pg_printf
26
+ *--------------------------------------------------------------------
27
+ */
28
+
29
+ /*
30
+ * Copyright (c) 1983, 1995, 1996 Eric P. Allman
31
+ * Copyright (c) 1988, 1993
32
+ * The Regents of the University of California. All rights reserved.
33
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
34
+ *
35
+ * Redistribution and use in source and binary forms, with or without
36
+ * modification, are permitted provided that the following conditions
37
+ * are met:
38
+ * 1. Redistributions of source code must retain the above copyright
39
+ * notice, this list of conditions and the following disclaimer.
40
+ * 2. Redistributions in binary form must reproduce the above copyright
41
+ * notice, this list of conditions and the following disclaimer in the
42
+ * documentation and/or other materials provided with the distribution.
43
+ * 3. Neither the name of the University nor the names of its contributors
44
+ * may be used to endorse or promote products derived from this software
45
+ * without specific prior written permission.
46
+ *
47
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57
+ * SUCH DAMAGE.
58
+ *
59
+ * src/port/snprintf.c
60
+ */
61
+
62
+ #include "c.h"
63
+
64
+ #include <math.h>
65
+
66
+ /*
67
+ * We used to use the platform's NL_ARGMAX here, but that's a bad idea,
68
+ * first because the point of this module is to remove platform dependencies
69
+ * not perpetuate them, and second because some platforms use ridiculously
70
+ * large values, leading to excessive stack consumption in dopr().
71
+ */
72
+ #define PG_NL_ARGMAX 31
73
+
74
+
75
+ /*
76
+ * SNPRINTF, VSNPRINTF and friends
77
+ *
78
+ * These versions have been grabbed off the net. They have been
79
+ * cleaned up to compile properly and support for most of the C99
80
+ * specification has been added. Remaining unimplemented features are:
81
+ *
82
+ * 1. No locale support: the radix character is always '.' and the '
83
+ * (single quote) format flag is ignored.
84
+ *
85
+ * 2. No support for the "%n" format specification.
86
+ *
87
+ * 3. No support for wide characters ("lc" and "ls" formats).
88
+ *
89
+ * 4. No support for "long double" ("Lf" and related formats).
90
+ *
91
+ * 5. Space and '#' flags are not implemented.
92
+ *
93
+ * In addition, we support some extensions over C99:
94
+ *
95
+ * 1. Argument order control through "%n$" and "*n$", as required by POSIX.
96
+ *
97
+ * 2. "%m" expands to the value of strerror(errno), where errno is the
98
+ * value that variable had at the start of the call. This is a glibc
99
+ * extension, but a very useful one.
100
+ *
101
+ *
102
+ * Historically the result values of sprintf/snprintf varied across platforms.
103
+ * This implementation now follows the C99 standard:
104
+ *
105
+ * 1. -1 is returned if an error is detected in the format string, or if
106
+ * a write to the target stream fails (as reported by fwrite). Note that
107
+ * overrunning snprintf's target buffer is *not* an error.
108
+ *
109
+ * 2. For successful writes to streams, the actual number of bytes written
110
+ * to the stream is returned.
111
+ *
112
+ * 3. For successful sprintf/snprintf, the number of bytes that would have
113
+ * been written to an infinite-size buffer (excluding the trailing '\0')
114
+ * is returned. snprintf will truncate its output to fit in the buffer
115
+ * (ensuring a trailing '\0' unless count == 0), but this is not reflected
116
+ * in the function result.
117
+ *
118
+ * snprintf buffer overrun can be detected by checking for function result
119
+ * greater than or equal to the supplied count.
120
+ */
121
+
122
+ /**************************************************************
123
+ * Original:
124
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
125
+ * A bombproof version of doprnt (dopr) included.
126
+ * Sigh. This sort of thing is always nasty do deal with. Note that
127
+ * the version here does not include floating point. (now it does ... tgl)
128
+ **************************************************************/
129
+
130
+ /* Prevent recursion */
131
+ #undef vsnprintf
132
+ #undef snprintf
133
+ #undef vsprintf
134
+ #undef sprintf
135
+ #undef vfprintf
136
+ #undef fprintf
137
+ #undef vprintf
138
+ #undef printf
139
+
140
+ /*
141
+ * Info about where the formatted output is going.
142
+ *
143
+ * dopr and subroutines will not write at/past bufend, but snprintf
144
+ * reserves one byte, ensuring it may place the trailing '\0' there.
145
+ *
146
+ * In snprintf, we use nchars to count the number of bytes dropped on the
147
+ * floor due to buffer overrun. The correct result of snprintf is thus
148
+ * (bufptr - bufstart) + nchars. (This isn't as inconsistent as it might
149
+ * seem: nchars is the number of emitted bytes that are not in the buffer now,
150
+ * either because we sent them to the stream or because we couldn't fit them
151
+ * into the buffer to begin with.)
152
+ */
153
+ typedef struct
154
+ {
155
+ char *bufptr; /* next buffer output position */
156
+ char *bufstart; /* first buffer element */
157
+ char *bufend; /* last+1 buffer element, or NULL */
158
+ /* bufend == NULL is for sprintf, where we assume buf is big enough */
159
+ FILE *stream; /* eventual output destination, or NULL */
160
+ int nchars; /* # chars sent to stream, or dropped */
161
+ bool failed; /* call is a failure; errno is set */
162
+ } PrintfTarget;
163
+
164
+ /*
165
+ * Info about the type and value of a formatting parameter. Note that we
166
+ * don't currently support "long double", "wint_t", or "wchar_t *" data,
167
+ * nor the '%n' formatting code; else we'd need more types. Also, at this
168
+ * level we need not worry about signed vs unsigned values.
169
+ */
170
+ typedef enum
171
+ {
172
+ ATYPE_NONE = 0,
173
+ ATYPE_INT,
174
+ ATYPE_LONG,
175
+ ATYPE_LONGLONG,
176
+ ATYPE_DOUBLE,
177
+ ATYPE_CHARPTR
178
+ } PrintfArgType;
179
+
180
+ typedef union
181
+ {
182
+ int i;
183
+ long l;
184
+ long long ll;
185
+ double d;
186
+ char *cptr;
187
+ } PrintfArgValue;
188
+
189
+
190
+ static void flushbuffer(PrintfTarget *target);
191
+ static void dopr(PrintfTarget *target, const char *format, va_list args);
192
+
193
+
194
+ /*
195
+ * Externally visible entry points.
196
+ *
197
+ * All of these are just wrappers around dopr(). Note it's essential that
198
+ * they not change the value of "errno" before reaching dopr().
199
+ */
200
+
201
+ int
202
+ pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
203
+ {
204
+ PrintfTarget target;
205
+ char onebyte[1];
206
+
207
+ /*
208
+ * C99 allows the case str == NULL when count == 0. Rather than
209
+ * special-casing this situation further down, we substitute a one-byte
210
+ * local buffer. Callers cannot tell, since the function result doesn't
211
+ * depend on count.
212
+ */
213
+ if (count == 0)
214
+ {
215
+ str = onebyte;
216
+ count = 1;
217
+ }
218
+ target.bufstart = target.bufptr = str;
219
+ target.bufend = str + count - 1;
220
+ target.stream = NULL;
221
+ target.nchars = 0;
222
+ target.failed = false;
223
+ dopr(&target, fmt, args);
224
+ *(target.bufptr) = '\0';
225
+ return target.failed ? -1 : (target.bufptr - target.bufstart
226
+ + target.nchars);
227
+ }
228
+
229
+ int
230
+ pg_snprintf(char *str, size_t count, const char *fmt,...)
231
+ {
232
+ int len;
233
+ va_list args;
234
+
235
+ va_start(args, fmt);
236
+ len = pg_vsnprintf(str, count, fmt, args);
237
+ va_end(args);
238
+ return len;
239
+ }
240
+
241
+ int
242
+ pg_vsprintf(char *str, const char *fmt, va_list args)
243
+ {
244
+ PrintfTarget target;
245
+
246
+ target.bufstart = target.bufptr = str;
247
+ target.bufend = NULL;
248
+ target.stream = NULL;
249
+ target.nchars = 0; /* not really used in this case */
250
+ target.failed = false;
251
+ dopr(&target, fmt, args);
252
+ *(target.bufptr) = '\0';
253
+ return target.failed ? -1 : (target.bufptr - target.bufstart
254
+ + target.nchars);
255
+ }
256
+
257
+ int
258
+ pg_sprintf(char *str, const char *fmt,...)
259
+ {
260
+ int len;
261
+ va_list args;
262
+
263
+ va_start(args, fmt);
264
+ len = pg_vsprintf(str, fmt, args);
265
+ va_end(args);
266
+ return len;
267
+ }
268
+
269
+ int
270
+ pg_vfprintf(FILE *stream, const char *fmt, va_list args)
271
+ {
272
+ PrintfTarget target;
273
+ char buffer[1024]; /* size is arbitrary */
274
+
275
+ if (stream == NULL)
276
+ {
277
+ errno = EINVAL;
278
+ return -1;
279
+ }
280
+ target.bufstart = target.bufptr = buffer;
281
+ target.bufend = buffer + sizeof(buffer); /* use the whole buffer */
282
+ target.stream = stream;
283
+ target.nchars = 0;
284
+ target.failed = false;
285
+ dopr(&target, fmt, args);
286
+ /* dump any remaining buffer contents */
287
+ flushbuffer(&target);
288
+ return target.failed ? -1 : target.nchars;
289
+ }
290
+
291
+ int
292
+ pg_fprintf(FILE *stream, const char *fmt,...)
293
+ {
294
+ int len;
295
+ va_list args;
296
+
297
+ va_start(args, fmt);
298
+ len = pg_vfprintf(stream, fmt, args);
299
+ va_end(args);
300
+ return len;
301
+ }
302
+
303
+
304
+
305
+ int
306
+ pg_printf(const char *fmt,...)
307
+ {
308
+ int len;
309
+ va_list args;
310
+
311
+ va_start(args, fmt);
312
+ len = pg_vfprintf(stdout, fmt, args);
313
+ va_end(args);
314
+ return len;
315
+ }
316
+
317
+ /*
318
+ * Attempt to write the entire buffer to target->stream; discard the entire
319
+ * buffer in any case. Call this only when target->stream is defined.
320
+ */
321
+ static void
322
+ flushbuffer(PrintfTarget *target)
323
+ {
324
+ size_t nc = target->bufptr - target->bufstart;
325
+
326
+ /*
327
+ * Don't write anything if we already failed; this is to ensure we
328
+ * preserve the original failure's errno.
329
+ */
330
+ if (!target->failed && nc > 0)
331
+ {
332
+ size_t written;
333
+
334
+ written = fwrite(target->bufstart, 1, nc, target->stream);
335
+ target->nchars += written;
336
+ if (written != nc)
337
+ target->failed = true;
338
+ }
339
+ target->bufptr = target->bufstart;
340
+ }
341
+
342
+
343
+ static bool find_arguments(const char *format, va_list args,
344
+ PrintfArgValue *argvalues);
345
+ static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth,
346
+ int pointflag, PrintfTarget *target);
347
+ static void fmtptr(void *value, PrintfTarget *target);
348
+ static void fmtint(long long value, char type, int forcesign,
349
+ int leftjust, int minlen, int zpad, int precision, int pointflag,
350
+ PrintfTarget *target);
351
+ static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target);
352
+ static void fmtfloat(double value, char type, int forcesign,
353
+ int leftjust, int minlen, int zpad, int precision, int pointflag,
354
+ PrintfTarget *target);
355
+ static void dostr(const char *str, int slen, PrintfTarget *target);
356
+ static void dopr_outch(int c, PrintfTarget *target);
357
+ static void dopr_outchmulti(int c, int slen, PrintfTarget *target);
358
+ static int adjust_sign(int is_negative, int forcesign, int *signvalue);
359
+ static int compute_padlen(int minlen, int vallen, int leftjust);
360
+ static void leading_pad(int zpad, int signvalue, int *padlen,
361
+ PrintfTarget *target);
362
+ static void trailing_pad(int padlen, PrintfTarget *target);
363
+
364
+ /*
365
+ * If strchrnul exists (it's a glibc-ism), it's a good bit faster than the
366
+ * equivalent manual loop. If it doesn't exist, provide a replacement.
367
+ *
368
+ * Note: glibc declares this as returning "char *", but that would require
369
+ * casting away const internally, so we don't follow that detail.
370
+ */
371
+ #ifndef HAVE_STRCHRNUL
372
+
373
+ static inline const char *
374
+ strchrnul(const char *s, int c)
375
+ {
376
+ while (*s != '\0' && *s != c)
377
+ s++;
378
+ return s;
379
+ }
380
+
381
+ #else
382
+
383
+ /*
384
+ * glibc's <string.h> declares strchrnul only if _GNU_SOURCE is defined.
385
+ * While we typically use that on glibc platforms, configure will set
386
+ * HAVE_STRCHRNUL whether it's used or not. Fill in the missing declaration
387
+ * so that this file will compile cleanly with or without _GNU_SOURCE.
388
+ */
389
+ #ifndef _GNU_SOURCE
390
+ extern char *strchrnul(const char *s, int c);
391
+ #endif
392
+
393
+ #endif /* HAVE_STRCHRNUL */
394
+
395
+
396
+ /*
397
+ * dopr(): the guts of *printf for all cases.
398
+ */
399
+ static void
400
+ dopr(PrintfTarget *target, const char *format, va_list args)
401
+ {
402
+ int save_errno = errno;
403
+ const char *first_pct = NULL;
404
+ int ch;
405
+ bool have_dollar;
406
+ bool have_star;
407
+ bool afterstar;
408
+ int accum;
409
+ int longlongflag;
410
+ int longflag;
411
+ int pointflag;
412
+ int leftjust;
413
+ int fieldwidth;
414
+ int precision;
415
+ int zpad;
416
+ int forcesign;
417
+ int fmtpos;
418
+ int cvalue;
419
+ long long numvalue;
420
+ double fvalue;
421
+ char *strvalue;
422
+ PrintfArgValue argvalues[PG_NL_ARGMAX + 1];
423
+
424
+ /*
425
+ * Initially, we suppose the format string does not use %n$. The first
426
+ * time we come to a conversion spec that has that, we'll call
427
+ * find_arguments() to check for consistent use of %n$ and fill the
428
+ * argvalues array with the argument values in the correct order.
429
+ */
430
+ have_dollar = false;
431
+
432
+ while (*format != '\0')
433
+ {
434
+ /* Locate next conversion specifier */
435
+ if (*format != '%')
436
+ {
437
+ /* Scan to next '%' or end of string */
438
+ const char *next_pct = strchrnul(format + 1, '%');
439
+
440
+ /* Dump literal data we just scanned over */
441
+ dostr(format, next_pct - format, target);
442
+ if (target->failed)
443
+ break;
444
+
445
+ if (*next_pct == '\0')
446
+ break;
447
+ format = next_pct;
448
+ }
449
+
450
+ /*
451
+ * Remember start of first conversion spec; if we find %n$, then it's
452
+ * sufficient for find_arguments() to start here, without rescanning
453
+ * earlier literal text.
454
+ */
455
+ if (first_pct == NULL)
456
+ first_pct = format;
457
+
458
+ /* Process conversion spec starting at *format */
459
+ format++;
460
+
461
+ /* Fast path for conversion spec that is exactly %s */
462
+ if (*format == 's')
463
+ {
464
+ format++;
465
+ strvalue = va_arg(args, char *);
466
+ Assert(strvalue != NULL);
467
+ dostr(strvalue, strlen(strvalue), target);
468
+ if (target->failed)
469
+ break;
470
+ continue;
471
+ }
472
+
473
+ fieldwidth = precision = zpad = leftjust = forcesign = 0;
474
+ longflag = longlongflag = pointflag = 0;
475
+ fmtpos = accum = 0;
476
+ have_star = afterstar = false;
477
+ nextch2:
478
+ ch = *format++;
479
+ switch (ch)
480
+ {
481
+ case '-':
482
+ leftjust = 1;
483
+ goto nextch2;
484
+ case '+':
485
+ forcesign = 1;
486
+ goto nextch2;
487
+ case '0':
488
+ /* set zero padding if no nonzero digits yet */
489
+ if (accum == 0 && !pointflag)
490
+ zpad = '0';
491
+ /* FALL THRU */
492
+ case '1':
493
+ case '2':
494
+ case '3':
495
+ case '4':
496
+ case '5':
497
+ case '6':
498
+ case '7':
499
+ case '8':
500
+ case '9':
501
+ accum = accum * 10 + (ch - '0');
502
+ goto nextch2;
503
+ case '.':
504
+ if (have_star)
505
+ have_star = false;
506
+ else
507
+ fieldwidth = accum;
508
+ pointflag = 1;
509
+ accum = 0;
510
+ goto nextch2;
511
+ case '*':
512
+ if (have_dollar)
513
+ {
514
+ /*
515
+ * We'll process value after reading n$. Note it's OK to
516
+ * assume have_dollar is set correctly, because in a valid
517
+ * format string the initial % must have had n$ if * does.
518
+ */
519
+ afterstar = true;
520
+ }
521
+ else
522
+ {
523
+ /* fetch and process value now */
524
+ int starval = va_arg(args, int);
525
+
526
+ if (pointflag)
527
+ {
528
+ precision = starval;
529
+ if (precision < 0)
530
+ {
531
+ precision = 0;
532
+ pointflag = 0;
533
+ }
534
+ }
535
+ else
536
+ {
537
+ fieldwidth = starval;
538
+ if (fieldwidth < 0)
539
+ {
540
+ leftjust = 1;
541
+ fieldwidth = -fieldwidth;
542
+ }
543
+ }
544
+ }
545
+ have_star = true;
546
+ accum = 0;
547
+ goto nextch2;
548
+ case '$':
549
+ /* First dollar sign? */
550
+ if (!have_dollar)
551
+ {
552
+ /* Yup, so examine all conversion specs in format */
553
+ if (!find_arguments(first_pct, args, argvalues))
554
+ goto bad_format;
555
+ have_dollar = true;
556
+ }
557
+ if (afterstar)
558
+ {
559
+ /* fetch and process star value */
560
+ int starval = argvalues[accum].i;
561
+
562
+ if (pointflag)
563
+ {
564
+ precision = starval;
565
+ if (precision < 0)
566
+ {
567
+ precision = 0;
568
+ pointflag = 0;
569
+ }
570
+ }
571
+ else
572
+ {
573
+ fieldwidth = starval;
574
+ if (fieldwidth < 0)
575
+ {
576
+ leftjust = 1;
577
+ fieldwidth = -fieldwidth;
578
+ }
579
+ }
580
+ afterstar = false;
581
+ }
582
+ else
583
+ fmtpos = accum;
584
+ accum = 0;
585
+ goto nextch2;
586
+ case 'l':
587
+ if (longflag)
588
+ longlongflag = 1;
589
+ else
590
+ longflag = 1;
591
+ goto nextch2;
592
+ case 'z':
593
+ #if SIZEOF_SIZE_T == 8
594
+ #ifdef HAVE_LONG_INT_64
595
+ longflag = 1;
596
+ #elif defined(HAVE_LONG_LONG_INT_64)
597
+ longlongflag = 1;
598
+ #else
599
+ #error "Don't know how to print 64bit integers"
600
+ #endif
601
+ #else
602
+ /* assume size_t is same size as int */
603
+ #endif
604
+ goto nextch2;
605
+ case 'h':
606
+ case '\'':
607
+ /* ignore these */
608
+ goto nextch2;
609
+ case 'd':
610
+ case 'i':
611
+ if (!have_star)
612
+ {
613
+ if (pointflag)
614
+ precision = accum;
615
+ else
616
+ fieldwidth = accum;
617
+ }
618
+ if (have_dollar)
619
+ {
620
+ if (longlongflag)
621
+ numvalue = argvalues[fmtpos].ll;
622
+ else if (longflag)
623
+ numvalue = argvalues[fmtpos].l;
624
+ else
625
+ numvalue = argvalues[fmtpos].i;
626
+ }
627
+ else
628
+ {
629
+ if (longlongflag)
630
+ numvalue = va_arg(args, long long);
631
+ else if (longflag)
632
+ numvalue = va_arg(args, long);
633
+ else
634
+ numvalue = va_arg(args, int);
635
+ }
636
+ fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
637
+ precision, pointflag, target);
638
+ break;
639
+ case 'o':
640
+ case 'u':
641
+ case 'x':
642
+ case 'X':
643
+ if (!have_star)
644
+ {
645
+ if (pointflag)
646
+ precision = accum;
647
+ else
648
+ fieldwidth = accum;
649
+ }
650
+ if (have_dollar)
651
+ {
652
+ if (longlongflag)
653
+ numvalue = (unsigned long long) argvalues[fmtpos].ll;
654
+ else if (longflag)
655
+ numvalue = (unsigned long) argvalues[fmtpos].l;
656
+ else
657
+ numvalue = (unsigned int) argvalues[fmtpos].i;
658
+ }
659
+ else
660
+ {
661
+ if (longlongflag)
662
+ numvalue = (unsigned long long) va_arg(args, long long);
663
+ else if (longflag)
664
+ numvalue = (unsigned long) va_arg(args, long);
665
+ else
666
+ numvalue = (unsigned int) va_arg(args, int);
667
+ }
668
+ fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
669
+ precision, pointflag, target);
670
+ break;
671
+ case 'c':
672
+ if (!have_star)
673
+ {
674
+ if (pointflag)
675
+ precision = accum;
676
+ else
677
+ fieldwidth = accum;
678
+ }
679
+ if (have_dollar)
680
+ cvalue = (unsigned char) argvalues[fmtpos].i;
681
+ else
682
+ cvalue = (unsigned char) va_arg(args, int);
683
+ fmtchar(cvalue, leftjust, fieldwidth, target);
684
+ break;
685
+ case 's':
686
+ if (!have_star)
687
+ {
688
+ if (pointflag)
689
+ precision = accum;
690
+ else
691
+ fieldwidth = accum;
692
+ }
693
+ if (have_dollar)
694
+ strvalue = argvalues[fmtpos].cptr;
695
+ else
696
+ strvalue = va_arg(args, char *);
697
+ /* Whine if someone tries to print a NULL string */
698
+ Assert(strvalue != NULL);
699
+ fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag,
700
+ target);
701
+ break;
702
+ case 'p':
703
+ /* fieldwidth/leftjust are ignored ... */
704
+ if (have_dollar)
705
+ strvalue = argvalues[fmtpos].cptr;
706
+ else
707
+ strvalue = va_arg(args, char *);
708
+ fmtptr((void *) strvalue, target);
709
+ break;
710
+ case 'e':
711
+ case 'E':
712
+ case 'f':
713
+ case 'g':
714
+ case 'G':
715
+ if (!have_star)
716
+ {
717
+ if (pointflag)
718
+ precision = accum;
719
+ else
720
+ fieldwidth = accum;
721
+ }
722
+ if (have_dollar)
723
+ fvalue = argvalues[fmtpos].d;
724
+ else
725
+ fvalue = va_arg(args, double);
726
+ fmtfloat(fvalue, ch, forcesign, leftjust,
727
+ fieldwidth, zpad,
728
+ precision, pointflag,
729
+ target);
730
+ break;
731
+ case 'm':
732
+ {
733
+ char errbuf[PG_STRERROR_R_BUFLEN];
734
+ const char *errm = strerror_r(save_errno,
735
+ errbuf, sizeof(errbuf));
736
+
737
+ dostr(errm, strlen(errm), target);
738
+ }
739
+ break;
740
+ case '%':
741
+ dopr_outch('%', target);
742
+ break;
743
+ default:
744
+
745
+ /*
746
+ * Anything else --- in particular, '\0' indicating end of
747
+ * format string --- is bogus.
748
+ */
749
+ goto bad_format;
750
+ }
751
+
752
+ /* Check for failure after each conversion spec */
753
+ if (target->failed)
754
+ break;
755
+ }
756
+
757
+ return;
758
+
759
+ bad_format:
760
+ errno = EINVAL;
761
+ target->failed = true;
762
+ }
763
+
764
+ /*
765
+ * find_arguments(): sort out the arguments for a format spec with %n$
766
+ *
767
+ * If format is valid, return true and fill argvalues[i] with the value
768
+ * for the conversion spec that has %i$ or *i$. Else return false.
769
+ */
770
+ static bool
771
+ find_arguments(const char *format, va_list args,
772
+ PrintfArgValue *argvalues)
773
+ {
774
+ int ch;
775
+ bool afterstar;
776
+ int accum;
777
+ int longlongflag;
778
+ int longflag;
779
+ int fmtpos;
780
+ int i;
781
+ int last_dollar;
782
+ PrintfArgType argtypes[PG_NL_ARGMAX + 1];
783
+
784
+ /* Initialize to "no dollar arguments known" */
785
+ last_dollar = 0;
786
+ MemSet(argtypes, 0, sizeof(argtypes));
787
+
788
+ /*
789
+ * This loop must accept the same format strings as the one in dopr().
790
+ * However, we don't need to analyze them to the same level of detail.
791
+ *
792
+ * Since we're only called if there's a dollar-type spec somewhere, we can
793
+ * fail immediately if we find a non-dollar spec. Per the C99 standard,
794
+ * all argument references in the format string must be one or the other.
795
+ */
796
+ while (*format != '\0')
797
+ {
798
+ /* Locate next conversion specifier */
799
+ if (*format != '%')
800
+ {
801
+ /* Unlike dopr, we can just quit if there's no more specifiers */
802
+ format = strchr(format + 1, '%');
803
+ if (format == NULL)
804
+ break;
805
+ }
806
+
807
+ /* Process conversion spec starting at *format */
808
+ format++;
809
+ longflag = longlongflag = 0;
810
+ fmtpos = accum = 0;
811
+ afterstar = false;
812
+ nextch1:
813
+ ch = *format++;
814
+ switch (ch)
815
+ {
816
+ case '-':
817
+ case '+':
818
+ goto nextch1;
819
+ case '0':
820
+ case '1':
821
+ case '2':
822
+ case '3':
823
+ case '4':
824
+ case '5':
825
+ case '6':
826
+ case '7':
827
+ case '8':
828
+ case '9':
829
+ accum = accum * 10 + (ch - '0');
830
+ goto nextch1;
831
+ case '.':
832
+ accum = 0;
833
+ goto nextch1;
834
+ case '*':
835
+ if (afterstar)
836
+ return false; /* previous star missing dollar */
837
+ afterstar = true;
838
+ accum = 0;
839
+ goto nextch1;
840
+ case '$':
841
+ if (accum <= 0 || accum > PG_NL_ARGMAX)
842
+ return false;
843
+ if (afterstar)
844
+ {
845
+ if (argtypes[accum] &&
846
+ argtypes[accum] != ATYPE_INT)
847
+ return false;
848
+ argtypes[accum] = ATYPE_INT;
849
+ last_dollar = Max(last_dollar, accum);
850
+ afterstar = false;
851
+ }
852
+ else
853
+ fmtpos = accum;
854
+ accum = 0;
855
+ goto nextch1;
856
+ case 'l':
857
+ if (longflag)
858
+ longlongflag = 1;
859
+ else
860
+ longflag = 1;
861
+ goto nextch1;
862
+ case 'z':
863
+ #if SIZEOF_SIZE_T == 8
864
+ #ifdef HAVE_LONG_INT_64
865
+ longflag = 1;
866
+ #elif defined(HAVE_LONG_LONG_INT_64)
867
+ longlongflag = 1;
868
+ #else
869
+ #error "Don't know how to print 64bit integers"
870
+ #endif
871
+ #else
872
+ /* assume size_t is same size as int */
873
+ #endif
874
+ goto nextch1;
875
+ case 'h':
876
+ case '\'':
877
+ /* ignore these */
878
+ goto nextch1;
879
+ case 'd':
880
+ case 'i':
881
+ case 'o':
882
+ case 'u':
883
+ case 'x':
884
+ case 'X':
885
+ if (fmtpos)
886
+ {
887
+ PrintfArgType atype;
888
+
889
+ if (longlongflag)
890
+ atype = ATYPE_LONGLONG;
891
+ else if (longflag)
892
+ atype = ATYPE_LONG;
893
+ else
894
+ atype = ATYPE_INT;
895
+ if (argtypes[fmtpos] &&
896
+ argtypes[fmtpos] != atype)
897
+ return false;
898
+ argtypes[fmtpos] = atype;
899
+ last_dollar = Max(last_dollar, fmtpos);
900
+ }
901
+ else
902
+ return false; /* non-dollar conversion spec */
903
+ break;
904
+ case 'c':
905
+ if (fmtpos)
906
+ {
907
+ if (argtypes[fmtpos] &&
908
+ argtypes[fmtpos] != ATYPE_INT)
909
+ return false;
910
+ argtypes[fmtpos] = ATYPE_INT;
911
+ last_dollar = Max(last_dollar, fmtpos);
912
+ }
913
+ else
914
+ return false; /* non-dollar conversion spec */
915
+ break;
916
+ case 's':
917
+ case 'p':
918
+ if (fmtpos)
919
+ {
920
+ if (argtypes[fmtpos] &&
921
+ argtypes[fmtpos] != ATYPE_CHARPTR)
922
+ return false;
923
+ argtypes[fmtpos] = ATYPE_CHARPTR;
924
+ last_dollar = Max(last_dollar, fmtpos);
925
+ }
926
+ else
927
+ return false; /* non-dollar conversion spec */
928
+ break;
929
+ case 'e':
930
+ case 'E':
931
+ case 'f':
932
+ case 'g':
933
+ case 'G':
934
+ if (fmtpos)
935
+ {
936
+ if (argtypes[fmtpos] &&
937
+ argtypes[fmtpos] != ATYPE_DOUBLE)
938
+ return false;
939
+ argtypes[fmtpos] = ATYPE_DOUBLE;
940
+ last_dollar = Max(last_dollar, fmtpos);
941
+ }
942
+ else
943
+ return false; /* non-dollar conversion spec */
944
+ break;
945
+ case 'm':
946
+ case '%':
947
+ break;
948
+ default:
949
+ return false; /* bogus format string */
950
+ }
951
+
952
+ /*
953
+ * If we finish the spec with afterstar still set, there's a
954
+ * non-dollar star in there.
955
+ */
956
+ if (afterstar)
957
+ return false; /* non-dollar conversion spec */
958
+ }
959
+
960
+ /*
961
+ * Format appears valid so far, so collect the arguments in physical
962
+ * order. (Since we rejected any non-dollar specs that would have
963
+ * collected arguments, we know that dopr() hasn't collected any yet.)
964
+ */
965
+ for (i = 1; i <= last_dollar; i++)
966
+ {
967
+ switch (argtypes[i])
968
+ {
969
+ case ATYPE_NONE:
970
+ return false;
971
+ case ATYPE_INT:
972
+ argvalues[i].i = va_arg(args, int);
973
+ break;
974
+ case ATYPE_LONG:
975
+ argvalues[i].l = va_arg(args, long);
976
+ break;
977
+ case ATYPE_LONGLONG:
978
+ argvalues[i].ll = va_arg(args, long long);
979
+ break;
980
+ case ATYPE_DOUBLE:
981
+ argvalues[i].d = va_arg(args, double);
982
+ break;
983
+ case ATYPE_CHARPTR:
984
+ argvalues[i].cptr = va_arg(args, char *);
985
+ break;
986
+ }
987
+ }
988
+
989
+ return true;
990
+ }
991
+
992
+ static void
993
+ fmtstr(const char *value, int leftjust, int minlen, int maxwidth,
994
+ int pointflag, PrintfTarget *target)
995
+ {
996
+ int padlen,
997
+ vallen; /* amount to pad */
998
+
999
+ /*
1000
+ * If a maxwidth (precision) is specified, we must not fetch more bytes
1001
+ * than that.
1002
+ */
1003
+ if (pointflag)
1004
+ vallen = strnlen(value, maxwidth);
1005
+ else
1006
+ vallen = strlen(value);
1007
+
1008
+ padlen = compute_padlen(minlen, vallen, leftjust);
1009
+
1010
+ if (padlen > 0)
1011
+ {
1012
+ dopr_outchmulti(' ', padlen, target);
1013
+ padlen = 0;
1014
+ }
1015
+
1016
+ dostr(value, vallen, target);
1017
+
1018
+ trailing_pad(padlen, target);
1019
+ }
1020
+
1021
+ static void
1022
+ fmtptr(void *value, PrintfTarget *target)
1023
+ {
1024
+ int vallen;
1025
+ char convert[64];
1026
+
1027
+ /* we rely on regular C library's sprintf to do the basic conversion */
1028
+ vallen = sprintf(convert, "%p", value);
1029
+ if (vallen < 0)
1030
+ target->failed = true;
1031
+ else
1032
+ dostr(convert, vallen, target);
1033
+ }
1034
+
1035
+ static void
1036
+ fmtint(long long value, char type, int forcesign, int leftjust,
1037
+ int minlen, int zpad, int precision, int pointflag,
1038
+ PrintfTarget *target)
1039
+ {
1040
+ unsigned long long base;
1041
+ unsigned long long uvalue;
1042
+ int dosign;
1043
+ const char *cvt = "0123456789abcdef";
1044
+ int signvalue = 0;
1045
+ char convert[64];
1046
+ int vallen = 0;
1047
+ int padlen; /* amount to pad */
1048
+ int zeropad; /* extra leading zeroes */
1049
+
1050
+ switch (type)
1051
+ {
1052
+ case 'd':
1053
+ case 'i':
1054
+ base = 10;
1055
+ dosign = 1;
1056
+ break;
1057
+ case 'o':
1058
+ base = 8;
1059
+ dosign = 0;
1060
+ break;
1061
+ case 'u':
1062
+ base = 10;
1063
+ dosign = 0;
1064
+ break;
1065
+ case 'x':
1066
+ base = 16;
1067
+ dosign = 0;
1068
+ break;
1069
+ case 'X':
1070
+ cvt = "0123456789ABCDEF";
1071
+ base = 16;
1072
+ dosign = 0;
1073
+ break;
1074
+ default:
1075
+ return; /* keep compiler quiet */
1076
+ }
1077
+
1078
+ /* disable MSVC warning about applying unary minus to an unsigned value */
1079
+ #ifdef _MSC_VER
1080
+ #pragma warning(push)
1081
+ #pragma warning(disable: 4146)
1082
+ #endif
1083
+ /* Handle +/- */
1084
+ if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
1085
+ uvalue = -(unsigned long long) value;
1086
+ else
1087
+ uvalue = (unsigned long long) value;
1088
+ #ifdef _MSC_VER
1089
+ #pragma warning(pop)
1090
+ #endif
1091
+
1092
+ /*
1093
+ * SUS: the result of converting 0 with an explicit precision of 0 is no
1094
+ * characters
1095
+ */
1096
+ if (value == 0 && pointflag && precision == 0)
1097
+ vallen = 0;
1098
+ else
1099
+ {
1100
+ /* make integer string */
1101
+ do
1102
+ {
1103
+ convert[sizeof(convert) - (++vallen)] = cvt[uvalue % base];
1104
+ uvalue = uvalue / base;
1105
+ } while (uvalue);
1106
+ }
1107
+
1108
+ zeropad = Max(0, precision - vallen);
1109
+
1110
+ padlen = compute_padlen(minlen, vallen + zeropad, leftjust);
1111
+
1112
+ leading_pad(zpad, signvalue, &padlen, target);
1113
+
1114
+ if (zeropad > 0)
1115
+ dopr_outchmulti('0', zeropad, target);
1116
+
1117
+ dostr(convert + sizeof(convert) - vallen, vallen, target);
1118
+
1119
+ trailing_pad(padlen, target);
1120
+ }
1121
+
1122
+ static void
1123
+ fmtchar(int value, int leftjust, int minlen, PrintfTarget *target)
1124
+ {
1125
+ int padlen; /* amount to pad */
1126
+
1127
+ padlen = compute_padlen(minlen, 1, leftjust);
1128
+
1129
+ if (padlen > 0)
1130
+ {
1131
+ dopr_outchmulti(' ', padlen, target);
1132
+ padlen = 0;
1133
+ }
1134
+
1135
+ dopr_outch(value, target);
1136
+
1137
+ trailing_pad(padlen, target);
1138
+ }
1139
+
1140
+ static void
1141
+ fmtfloat(double value, char type, int forcesign, int leftjust,
1142
+ int minlen, int zpad, int precision, int pointflag,
1143
+ PrintfTarget *target)
1144
+ {
1145
+ int signvalue = 0;
1146
+ int prec;
1147
+ int vallen;
1148
+ char fmt[8];
1149
+ char convert[1024];
1150
+ int zeropadlen = 0; /* amount to pad with zeroes */
1151
+ int padlen; /* amount to pad with spaces */
1152
+
1153
+ /*
1154
+ * We rely on the regular C library's sprintf to do the basic conversion,
1155
+ * then handle padding considerations here.
1156
+ *
1157
+ * The dynamic range of "double" is about 1E+-308 for IEEE math, and not
1158
+ * too wildly more than that with other hardware. In "f" format, sprintf
1159
+ * could therefore generate at most 308 characters to the left of the
1160
+ * decimal point; while we need to allow the precision to get as high as
1161
+ * 308+17 to ensure that we don't truncate significant digits from very
1162
+ * small values. To handle both these extremes, we use a buffer of 1024
1163
+ * bytes and limit requested precision to 350 digits; this should prevent
1164
+ * buffer overrun even with non-IEEE math. If the original precision
1165
+ * request was more than 350, separately pad with zeroes.
1166
+ *
1167
+ * We handle infinities and NaNs specially to ensure platform-independent
1168
+ * output.
1169
+ */
1170
+ if (precision < 0) /* cover possible overflow of "accum" */
1171
+ precision = 0;
1172
+ prec = Min(precision, 350);
1173
+
1174
+ if (isnan(value))
1175
+ {
1176
+ strcpy(convert, "NaN");
1177
+ vallen = 3;
1178
+ /* no zero padding, regardless of precision spec */
1179
+ }
1180
+ else
1181
+ {
1182
+ /*
1183
+ * Handle sign (NaNs have no sign, so we don't do this in the case
1184
+ * above). "value < 0.0" will not be true for IEEE minus zero, so we
1185
+ * detect that by looking for the case where value equals 0.0
1186
+ * according to == but not according to memcmp.
1187
+ */
1188
+ static const double dzero = 0.0;
1189
+
1190
+ if (adjust_sign((value < 0.0 ||
1191
+ (value == 0.0 &&
1192
+ memcmp(&value, &dzero, sizeof(double)) != 0)),
1193
+ forcesign, &signvalue))
1194
+ value = -value;
1195
+
1196
+ if (isinf(value))
1197
+ {
1198
+ strcpy(convert, "Infinity");
1199
+ vallen = 8;
1200
+ /* no zero padding, regardless of precision spec */
1201
+ }
1202
+ else if (pointflag)
1203
+ {
1204
+ zeropadlen = precision - prec;
1205
+ fmt[0] = '%';
1206
+ fmt[1] = '.';
1207
+ fmt[2] = '*';
1208
+ fmt[3] = type;
1209
+ fmt[4] = '\0';
1210
+ vallen = sprintf(convert, fmt, prec, value);
1211
+ }
1212
+ else
1213
+ {
1214
+ fmt[0] = '%';
1215
+ fmt[1] = type;
1216
+ fmt[2] = '\0';
1217
+ vallen = sprintf(convert, fmt, value);
1218
+ }
1219
+ if (vallen < 0)
1220
+ goto fail;
1221
+
1222
+ /*
1223
+ * Windows, alone among our supported platforms, likes to emit
1224
+ * three-digit exponent fields even when two digits would do. Hack
1225
+ * such results to look like the way everyone else does it.
1226
+ */
1227
+ #ifdef WIN32
1228
+ if (vallen >= 6 &&
1229
+ convert[vallen - 5] == 'e' &&
1230
+ convert[vallen - 3] == '0')
1231
+ {
1232
+ convert[vallen - 3] = convert[vallen - 2];
1233
+ convert[vallen - 2] = convert[vallen - 1];
1234
+ vallen--;
1235
+ }
1236
+ #endif
1237
+ }
1238
+
1239
+ padlen = compute_padlen(minlen, vallen + zeropadlen, leftjust);
1240
+
1241
+ leading_pad(zpad, signvalue, &padlen, target);
1242
+
1243
+ if (zeropadlen > 0)
1244
+ {
1245
+ /* If 'e' or 'E' format, inject zeroes before the exponent */
1246
+ char *epos = strrchr(convert, 'e');
1247
+
1248
+ if (!epos)
1249
+ epos = strrchr(convert, 'E');
1250
+ if (epos)
1251
+ {
1252
+ /* pad before exponent */
1253
+ dostr(convert, epos - convert, target);
1254
+ dopr_outchmulti('0', zeropadlen, target);
1255
+ dostr(epos, vallen - (epos - convert), target);
1256
+ }
1257
+ else
1258
+ {
1259
+ /* no exponent, pad after the digits */
1260
+ dostr(convert, vallen, target);
1261
+ dopr_outchmulti('0', zeropadlen, target);
1262
+ }
1263
+ }
1264
+ else
1265
+ {
1266
+ /* no zero padding, just emit the number as-is */
1267
+ dostr(convert, vallen, target);
1268
+ }
1269
+
1270
+ trailing_pad(padlen, target);
1271
+ return;
1272
+
1273
+ fail:
1274
+ target->failed = true;
1275
+ }
1276
+
1277
+ /*
1278
+ * Nonstandard entry point to print a double value efficiently.
1279
+ *
1280
+ * This is approximately equivalent to strfromd(), but has an API more
1281
+ * adapted to what float8out() wants. The behavior is like snprintf()
1282
+ * with a format of "%.ng", where n is the specified precision.
1283
+ * However, the target buffer must be nonempty (i.e. count > 0), and
1284
+ * the precision is silently bounded to a sane range.
1285
+ */
1286
+ #ifdef WIN32
1287
+ #endif
1288
+
1289
+
1290
+ static void
1291
+ dostr(const char *str, int slen, PrintfTarget *target)
1292
+ {
1293
+ /* fast path for common case of slen == 1 */
1294
+ if (slen == 1)
1295
+ {
1296
+ dopr_outch(*str, target);
1297
+ return;
1298
+ }
1299
+
1300
+ while (slen > 0)
1301
+ {
1302
+ int avail;
1303
+
1304
+ if (target->bufend != NULL)
1305
+ avail = target->bufend - target->bufptr;
1306
+ else
1307
+ avail = slen;
1308
+ if (avail <= 0)
1309
+ {
1310
+ /* buffer full, can we dump to stream? */
1311
+ if (target->stream == NULL)
1312
+ {
1313
+ target->nchars += slen; /* no, lose the data */
1314
+ return;
1315
+ }
1316
+ flushbuffer(target);
1317
+ continue;
1318
+ }
1319
+ avail = Min(avail, slen);
1320
+ memmove(target->bufptr, str, avail);
1321
+ target->bufptr += avail;
1322
+ str += avail;
1323
+ slen -= avail;
1324
+ }
1325
+ }
1326
+
1327
+ static void
1328
+ dopr_outch(int c, PrintfTarget *target)
1329
+ {
1330
+ if (target->bufend != NULL && target->bufptr >= target->bufend)
1331
+ {
1332
+ /* buffer full, can we dump to stream? */
1333
+ if (target->stream == NULL)
1334
+ {
1335
+ target->nchars++; /* no, lose the data */
1336
+ return;
1337
+ }
1338
+ flushbuffer(target);
1339
+ }
1340
+ *(target->bufptr++) = c;
1341
+ }
1342
+
1343
+ static void
1344
+ dopr_outchmulti(int c, int slen, PrintfTarget *target)
1345
+ {
1346
+ /* fast path for common case of slen == 1 */
1347
+ if (slen == 1)
1348
+ {
1349
+ dopr_outch(c, target);
1350
+ return;
1351
+ }
1352
+
1353
+ while (slen > 0)
1354
+ {
1355
+ int avail;
1356
+
1357
+ if (target->bufend != NULL)
1358
+ avail = target->bufend - target->bufptr;
1359
+ else
1360
+ avail = slen;
1361
+ if (avail <= 0)
1362
+ {
1363
+ /* buffer full, can we dump to stream? */
1364
+ if (target->stream == NULL)
1365
+ {
1366
+ target->nchars += slen; /* no, lose the data */
1367
+ return;
1368
+ }
1369
+ flushbuffer(target);
1370
+ continue;
1371
+ }
1372
+ avail = Min(avail, slen);
1373
+ memset(target->bufptr, c, avail);
1374
+ target->bufptr += avail;
1375
+ slen -= avail;
1376
+ }
1377
+ }
1378
+
1379
+
1380
+ static int
1381
+ adjust_sign(int is_negative, int forcesign, int *signvalue)
1382
+ {
1383
+ if (is_negative)
1384
+ {
1385
+ *signvalue = '-';
1386
+ return true;
1387
+ }
1388
+ else if (forcesign)
1389
+ *signvalue = '+';
1390
+ return false;
1391
+ }
1392
+
1393
+
1394
+ static int
1395
+ compute_padlen(int minlen, int vallen, int leftjust)
1396
+ {
1397
+ int padlen;
1398
+
1399
+ padlen = minlen - vallen;
1400
+ if (padlen < 0)
1401
+ padlen = 0;
1402
+ if (leftjust)
1403
+ padlen = -padlen;
1404
+ return padlen;
1405
+ }
1406
+
1407
+
1408
+ static void
1409
+ leading_pad(int zpad, int signvalue, int *padlen, PrintfTarget *target)
1410
+ {
1411
+ int maxpad;
1412
+
1413
+ if (*padlen > 0 && zpad)
1414
+ {
1415
+ if (signvalue)
1416
+ {
1417
+ dopr_outch(signvalue, target);
1418
+ --(*padlen);
1419
+ signvalue = 0;
1420
+ }
1421
+ if (*padlen > 0)
1422
+ {
1423
+ dopr_outchmulti(zpad, *padlen, target);
1424
+ *padlen = 0;
1425
+ }
1426
+ }
1427
+ maxpad = (signvalue != 0);
1428
+ if (*padlen > maxpad)
1429
+ {
1430
+ dopr_outchmulti(' ', *padlen - maxpad, target);
1431
+ *padlen = maxpad;
1432
+ }
1433
+ if (signvalue)
1434
+ {
1435
+ dopr_outch(signvalue, target);
1436
+ if (*padlen > 0)
1437
+ --(*padlen);
1438
+ else if (*padlen < 0)
1439
+ ++(*padlen);
1440
+ }
1441
+ }
1442
+
1443
+
1444
+ static void
1445
+ trailing_pad(int padlen, PrintfTarget *target)
1446
+ {
1447
+ if (padlen < 0)
1448
+ dopr_outchmulti(' ', -padlen, target);
1449
+ }