prestogres 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (393) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/LICENSE +202 -0
  5. data/NOTICE +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +13 -0
  8. data/VERSION +1 -0
  9. data/bin/prestogres +254 -0
  10. data/config/pcp.conf.sample +28 -0
  11. data/config/pgpool.conf +678 -0
  12. data/config/pool_hba.conf +84 -0
  13. data/config/pool_passwd +0 -0
  14. data/config/postgresql.conf +2 -0
  15. data/ext/.gitignore +6 -0
  16. data/ext/depend +26 -0
  17. data/ext/extconf.rb +4 -0
  18. data/ext/prestogres_config.c +12 -0
  19. data/pgpool2/.gitignore +36 -0
  20. data/pgpool2/AUTHORS +4 -0
  21. data/pgpool2/COPYING +12 -0
  22. data/pgpool2/ChangeLog +1 -0
  23. data/pgpool2/INSTALL +1 -0
  24. data/pgpool2/Makefile.am +159 -0
  25. data/pgpool2/Makefile.in +1187 -0
  26. data/pgpool2/NEWS +4960 -0
  27. data/pgpool2/README +1 -0
  28. data/pgpool2/README.euc_jp +1 -0
  29. data/pgpool2/README.online-recovery +62 -0
  30. data/pgpool2/TODO +103 -0
  31. data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
  32. data/pgpool2/aclocal.m4 +1088 -0
  33. data/pgpool2/c-compiler.m4 +134 -0
  34. data/pgpool2/c-library.m4 +325 -0
  35. data/pgpool2/child.c +2097 -0
  36. data/pgpool2/config.guess +1532 -0
  37. data/pgpool2/config.h.in +332 -0
  38. data/pgpool2/config.sub +1640 -0
  39. data/pgpool2/configure +15752 -0
  40. data/pgpool2/configure.in +392 -0
  41. data/pgpool2/depcomp +522 -0
  42. data/pgpool2/doc/basebackup.sh +17 -0
  43. data/pgpool2/doc/pgpool-de.html +4220 -0
  44. data/pgpool2/doc/pgpool-en.html +5738 -0
  45. data/pgpool2/doc/pgpool-fr.html +4118 -0
  46. data/pgpool2/doc/pgpool-ja.css +198 -0
  47. data/pgpool2/doc/pgpool-ja.html +11279 -0
  48. data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
  49. data/pgpool2/doc/pgpool.css +280 -0
  50. data/pgpool2/doc/pgpool_remote_start +13 -0
  51. data/pgpool2/doc/recovery.conf.sample +117 -0
  52. data/pgpool2/doc/tutorial-en.html +707 -0
  53. data/pgpool2/doc/tutorial-ja.html +422 -0
  54. data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
  55. data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
  56. data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
  57. data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
  58. data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
  59. data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
  60. data/pgpool2/doc/tutorial-zh_cn.html +537 -0
  61. data/pgpool2/doc/watchdog.png +0 -0
  62. data/pgpool2/doc/wd-en.html +236 -0
  63. data/pgpool2/doc/wd-en.jpg +0 -0
  64. data/pgpool2/doc/wd-ja.html +219 -0
  65. data/pgpool2/doc/wd-ja.jpg +0 -0
  66. data/pgpool2/doc/wd-zh_cn.html +201 -0
  67. data/pgpool2/doc/where_to_send_queries.odg +0 -0
  68. data/pgpool2/doc/where_to_send_queries.pdf +0 -0
  69. data/pgpool2/general.m4 +166 -0
  70. data/pgpool2/getopt_long.c +200 -0
  71. data/pgpool2/getopt_long.h +44 -0
  72. data/pgpool2/install-sh +251 -0
  73. data/pgpool2/ltmain.sh +8406 -0
  74. data/pgpool2/m4/libtool.m4 +7360 -0
  75. data/pgpool2/m4/ltoptions.m4 +368 -0
  76. data/pgpool2/m4/ltsugar.m4 +123 -0
  77. data/pgpool2/m4/ltversion.m4 +23 -0
  78. data/pgpool2/m4/lt~obsolete.m4 +92 -0
  79. data/pgpool2/main.c +2971 -0
  80. data/pgpool2/md5.c +444 -0
  81. data/pgpool2/md5.h +28 -0
  82. data/pgpool2/missing +360 -0
  83. data/pgpool2/mkinstalldirs +40 -0
  84. data/pgpool2/parser/Makefile.am +50 -0
  85. data/pgpool2/parser/Makefile.in +559 -0
  86. data/pgpool2/parser/copyfuncs.c +3310 -0
  87. data/pgpool2/parser/gram.c +39100 -0
  88. data/pgpool2/parser/gram.h +940 -0
  89. data/pgpool2/parser/gram.y +13408 -0
  90. data/pgpool2/parser/gramparse.h +74 -0
  91. data/pgpool2/parser/keywords.c +32 -0
  92. data/pgpool2/parser/keywords.h +39 -0
  93. data/pgpool2/parser/kwlist.h +425 -0
  94. data/pgpool2/parser/kwlookup.c +88 -0
  95. data/pgpool2/parser/list.c +1156 -0
  96. data/pgpool2/parser/makefuncs.c +518 -0
  97. data/pgpool2/parser/makefuncs.h +83 -0
  98. data/pgpool2/parser/memnodes.h +79 -0
  99. data/pgpool2/parser/nodes.c +29 -0
  100. data/pgpool2/parser/nodes.h +609 -0
  101. data/pgpool2/parser/outfuncs.c +5790 -0
  102. data/pgpool2/parser/parsenodes.h +2615 -0
  103. data/pgpool2/parser/parser.c +262 -0
  104. data/pgpool2/parser/parser.h +46 -0
  105. data/pgpool2/parser/pg_class.h +158 -0
  106. data/pgpool2/parser/pg_config_manual.h +273 -0
  107. data/pgpool2/parser/pg_list.h +352 -0
  108. data/pgpool2/parser/pg_trigger.h +147 -0
  109. data/pgpool2/parser/pg_wchar.h +492 -0
  110. data/pgpool2/parser/pool_memory.c +342 -0
  111. data/pgpool2/parser/pool_memory.h +77 -0
  112. data/pgpool2/parser/pool_parser.h +222 -0
  113. data/pgpool2/parser/pool_string.c +121 -0
  114. data/pgpool2/parser/pool_string.h +37 -0
  115. data/pgpool2/parser/primnodes.h +1280 -0
  116. data/pgpool2/parser/scan.c +4094 -0
  117. data/pgpool2/parser/scan.l +1451 -0
  118. data/pgpool2/parser/scanner.h +120 -0
  119. data/pgpool2/parser/scansup.c +221 -0
  120. data/pgpool2/parser/scansup.h +28 -0
  121. data/pgpool2/parser/snprintf.c +1102 -0
  122. data/pgpool2/parser/stringinfo.c +294 -0
  123. data/pgpool2/parser/stringinfo.h +178 -0
  124. data/pgpool2/parser/value.c +78 -0
  125. data/pgpool2/parser/value.h +62 -0
  126. data/pgpool2/parser/wchar.c +2048 -0
  127. data/pgpool2/pcp.conf.sample +28 -0
  128. data/pgpool2/pcp/Makefile.am +40 -0
  129. data/pgpool2/pcp/Makefile.in +771 -0
  130. data/pgpool2/pcp/libpcp_ext.h +250 -0
  131. data/pgpool2/pcp/md5.c +444 -0
  132. data/pgpool2/pcp/md5.h +28 -0
  133. data/pgpool2/pcp/pcp.c +1652 -0
  134. data/pgpool2/pcp/pcp.h +61 -0
  135. data/pgpool2/pcp/pcp_attach_node.c +172 -0
  136. data/pgpool2/pcp/pcp_detach_node.c +185 -0
  137. data/pgpool2/pcp/pcp_error.c +87 -0
  138. data/pgpool2/pcp/pcp_node_count.c +160 -0
  139. data/pgpool2/pcp/pcp_node_info.c +198 -0
  140. data/pgpool2/pcp/pcp_pool_status.c +166 -0
  141. data/pgpool2/pcp/pcp_proc_count.c +166 -0
  142. data/pgpool2/pcp/pcp_proc_info.c +261 -0
  143. data/pgpool2/pcp/pcp_promote_node.c +185 -0
  144. data/pgpool2/pcp/pcp_recovery_node.c +172 -0
  145. data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
  146. data/pgpool2/pcp/pcp_stream.c +385 -0
  147. data/pgpool2/pcp/pcp_stream.h +52 -0
  148. data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
  149. data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
  150. data/pgpool2/pcp_child.c +1493 -0
  151. data/pgpool2/pg_md5.c +305 -0
  152. data/pgpool2/pgpool.8.in +121 -0
  153. data/pgpool2/pgpool.conf +553 -0
  154. data/pgpool2/pgpool.conf.sample +666 -0
  155. data/pgpool2/pgpool.conf.sample-master-slave +665 -0
  156. data/pgpool2/pgpool.conf.sample-replication +664 -0
  157. data/pgpool2/pgpool.conf.sample-stream +664 -0
  158. data/pgpool2/pgpool.spec +264 -0
  159. data/pgpool2/pgpool_adm/TODO +7 -0
  160. data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
  161. data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
  162. data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
  163. data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
  164. data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
  165. data/pgpool2/pool.h +655 -0
  166. data/pgpool2/pool_auth.c +1390 -0
  167. data/pgpool2/pool_config.c +5007 -0
  168. data/pgpool2/pool_config.h +284 -0
  169. data/pgpool2/pool_config.l +3281 -0
  170. data/pgpool2/pool_config_md5.c +29 -0
  171. data/pgpool2/pool_connection_pool.c +812 -0
  172. data/pgpool2/pool_error.c +242 -0
  173. data/pgpool2/pool_globals.c +27 -0
  174. data/pgpool2/pool_hba.c +1723 -0
  175. data/pgpool2/pool_hba.conf.sample +67 -0
  176. data/pgpool2/pool_ip.c +567 -0
  177. data/pgpool2/pool_ip.h +65 -0
  178. data/pgpool2/pool_ipc.h +38 -0
  179. data/pgpool2/pool_lobj.c +242 -0
  180. data/pgpool2/pool_lobj.h +32 -0
  181. data/pgpool2/pool_memqcache.c +3818 -0
  182. data/pgpool2/pool_memqcache.h +268 -0
  183. data/pgpool2/pool_params.c +163 -0
  184. data/pgpool2/pool_passwd.c +249 -0
  185. data/pgpool2/pool_passwd.h +41 -0
  186. data/pgpool2/pool_path.c +193 -0
  187. data/pgpool2/pool_path.h +81 -0
  188. data/pgpool2/pool_process_context.c +247 -0
  189. data/pgpool2/pool_process_context.h +62 -0
  190. data/pgpool2/pool_process_query.c +5001 -0
  191. data/pgpool2/pool_process_reporting.c +1671 -0
  192. data/pgpool2/pool_process_reporting.h +44 -0
  193. data/pgpool2/pool_proto2.c +671 -0
  194. data/pgpool2/pool_proto_modules.c +3524 -0
  195. data/pgpool2/pool_proto_modules.h +185 -0
  196. data/pgpool2/pool_query_cache.c +1020 -0
  197. data/pgpool2/pool_query_context.c +1871 -0
  198. data/pgpool2/pool_query_context.h +105 -0
  199. data/pgpool2/pool_relcache.c +284 -0
  200. data/pgpool2/pool_relcache.h +78 -0
  201. data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
  202. data/pgpool2/pool_rewrite_query.c +715 -0
  203. data/pgpool2/pool_rewrite_query.h +192 -0
  204. data/pgpool2/pool_select_walker.c +1150 -0
  205. data/pgpool2/pool_select_walker.h +68 -0
  206. data/pgpool2/pool_sema.c +161 -0
  207. data/pgpool2/pool_session_context.c +952 -0
  208. data/pgpool2/pool_session_context.h +203 -0
  209. data/pgpool2/pool_shmem.c +185 -0
  210. data/pgpool2/pool_signal.c +158 -0
  211. data/pgpool2/pool_signal.h +61 -0
  212. data/pgpool2/pool_ssl.c +339 -0
  213. data/pgpool2/pool_stream.c +962 -0
  214. data/pgpool2/pool_stream.h +61 -0
  215. data/pgpool2/pool_system.c +659 -0
  216. data/pgpool2/pool_timestamp.c +1215 -0
  217. data/pgpool2/pool_timestamp.h +38 -0
  218. data/pgpool2/pool_type.h +171 -0
  219. data/pgpool2/pool_worker_child.c +384 -0
  220. data/pgpool2/ps_status.c +404 -0
  221. data/pgpool2/recovery.c +435 -0
  222. data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
  223. data/pgpool2/redhat/pgpool.init +201 -0
  224. data/pgpool2/redhat/pgpool.sysconfig +7 -0
  225. data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
  226. data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
  227. data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
  228. data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
  229. data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
  230. data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
  231. data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
  232. data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
  233. data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
  234. data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
  235. data/pgpool2/sample/dist_def_pgbench.sql +73 -0
  236. data/pgpool2/sample/pgpool.pam +3 -0
  237. data/pgpool2/sample/pgpool_recovery +20 -0
  238. data/pgpool2/sample/pgpool_recovery_pitr +19 -0
  239. data/pgpool2/sample/pgpool_remote_start +13 -0
  240. data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
  241. data/pgpool2/sql/insert_lock.sql +15 -0
  242. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
  243. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
  244. data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
  245. data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
  246. data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
  247. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
  248. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
  249. data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
  250. data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
  251. data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
  252. data/pgpool2/sql/system_db.sql +38 -0
  253. data/pgpool2/strlcpy.c +85 -0
  254. data/pgpool2/test/C/test_extended.c +98 -0
  255. data/pgpool2/test/jdbc/.cvsignore +2 -0
  256. data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
  257. data/pgpool2/test/jdbc/BatchTest.java +55 -0
  258. data/pgpool2/test/jdbc/ColumnTest.java +60 -0
  259. data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
  260. data/pgpool2/test/jdbc/InsertTest.java +34 -0
  261. data/pgpool2/test/jdbc/LockTest.java +36 -0
  262. data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
  263. data/pgpool2/test/jdbc/README.euc_jp +73 -0
  264. data/pgpool2/test/jdbc/RunTest.java +83 -0
  265. data/pgpool2/test/jdbc/SelectTest.java +37 -0
  266. data/pgpool2/test/jdbc/UpdateTest.java +32 -0
  267. data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
  268. data/pgpool2/test/jdbc/expected/autocommit +10 -0
  269. data/pgpool2/test/jdbc/expected/batch +1 -0
  270. data/pgpool2/test/jdbc/expected/column +100 -0
  271. data/pgpool2/test/jdbc/expected/insert +1 -0
  272. data/pgpool2/test/jdbc/expected/lock +100 -0
  273. data/pgpool2/test/jdbc/expected/select +2 -0
  274. data/pgpool2/test/jdbc/expected/update +1 -0
  275. data/pgpool2/test/jdbc/pgpool.properties +7 -0
  276. data/pgpool2/test/jdbc/prepare.sql +54 -0
  277. data/pgpool2/test/jdbc/run.sh +6 -0
  278. data/pgpool2/test/parser/.cvsignore +6 -0
  279. data/pgpool2/test/parser/README +32 -0
  280. data/pgpool2/test/parser/expected/copy.out +17 -0
  281. data/pgpool2/test/parser/expected/create.out +64 -0
  282. data/pgpool2/test/parser/expected/cursor.out +37 -0
  283. data/pgpool2/test/parser/expected/delete.out +10 -0
  284. data/pgpool2/test/parser/expected/drop.out +12 -0
  285. data/pgpool2/test/parser/expected/insert.out +13 -0
  286. data/pgpool2/test/parser/expected/misc.out +28 -0
  287. data/pgpool2/test/parser/expected/prepare.out +4 -0
  288. data/pgpool2/test/parser/expected/privileges.out +31 -0
  289. data/pgpool2/test/parser/expected/scanner.out +30 -0
  290. data/pgpool2/test/parser/expected/select.out +89 -0
  291. data/pgpool2/test/parser/expected/transaction.out +38 -0
  292. data/pgpool2/test/parser/expected/update.out +11 -0
  293. data/pgpool2/test/parser/expected/v84.out +37 -0
  294. data/pgpool2/test/parser/expected/v90.out +25 -0
  295. data/pgpool2/test/parser/expected/var.out +22 -0
  296. data/pgpool2/test/parser/input/alter.sql +2 -0
  297. data/pgpool2/test/parser/input/copy.sql +17 -0
  298. data/pgpool2/test/parser/input/create.sql +64 -0
  299. data/pgpool2/test/parser/input/cursor.sql +37 -0
  300. data/pgpool2/test/parser/input/delete.sql +10 -0
  301. data/pgpool2/test/parser/input/drop.sql +12 -0
  302. data/pgpool2/test/parser/input/insert.sql +13 -0
  303. data/pgpool2/test/parser/input/misc.sql +28 -0
  304. data/pgpool2/test/parser/input/prepare.sql +4 -0
  305. data/pgpool2/test/parser/input/privileges.sql +31 -0
  306. data/pgpool2/test/parser/input/scanner.sql +34 -0
  307. data/pgpool2/test/parser/input/select.sql +89 -0
  308. data/pgpool2/test/parser/input/transaction.sql +38 -0
  309. data/pgpool2/test/parser/input/update.sql +11 -0
  310. data/pgpool2/test/parser/input/v84.sql +37 -0
  311. data/pgpool2/test/parser/input/v90.sql +38 -0
  312. data/pgpool2/test/parser/input/var.sql +22 -0
  313. data/pgpool2/test/parser/main.c +96 -0
  314. data/pgpool2/test/parser/parse_schedule +16 -0
  315. data/pgpool2/test/parser/pool.h +13 -0
  316. data/pgpool2/test/parser/run-test +62 -0
  317. data/pgpool2/test/pdo-test/README.euc_jp +58 -0
  318. data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
  319. data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
  320. data/pgpool2/test/pdo-test/collections.inc +11 -0
  321. data/pgpool2/test/pdo-test/def.inc +7 -0
  322. data/pgpool2/test/pdo-test/log.txt +0 -0
  323. data/pgpool2/test/pdo-test/mod/database.inc +36 -0
  324. data/pgpool2/test/pdo-test/mod/def.inc +0 -0
  325. data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
  326. data/pgpool2/test/pdo-test/pdotest.php +11 -0
  327. data/pgpool2/test/pdo-test/regsql.inc +56 -0
  328. data/pgpool2/test/pgpool_setup +898 -0
  329. data/pgpool2/test/regression/README +39 -0
  330. data/pgpool2/test/regression/clean.sh +21 -0
  331. data/pgpool2/test/regression/libs.sh +16 -0
  332. data/pgpool2/test/regression/regress.sh +166 -0
  333. data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
  334. data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
  335. data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
  336. data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
  337. data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
  338. data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
  339. data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
  340. data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
  341. data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
  342. data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
  343. data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
  344. data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
  345. data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
  346. data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
  347. data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
  348. data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
  349. data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
  350. data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
  351. data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
  352. data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
  353. data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
  354. data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
  355. data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
  356. data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
  357. data/pgpool2/test/timestamp/expected/insert.out +16 -0
  358. data/pgpool2/test/timestamp/expected/misc.out +3 -0
  359. data/pgpool2/test/timestamp/expected/update.out +6 -0
  360. data/pgpool2/test/timestamp/input/insert.sql +16 -0
  361. data/pgpool2/test/timestamp/input/misc.sql +3 -0
  362. data/pgpool2/test/timestamp/input/update.sql +6 -0
  363. data/pgpool2/test/timestamp/main.c +129 -0
  364. data/pgpool2/test/timestamp/parse_schedule +3 -0
  365. data/pgpool2/test/timestamp/run-test +69 -0
  366. data/pgpool2/version.h +1 -0
  367. data/pgpool2/watchdog/Makefile.am +17 -0
  368. data/pgpool2/watchdog/Makefile.in +505 -0
  369. data/pgpool2/watchdog/test/stab.c +266 -0
  370. data/pgpool2/watchdog/test/test.c +85 -0
  371. data/pgpool2/watchdog/test/wd_child_t.c +87 -0
  372. data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
  373. data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
  374. data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
  375. data/pgpool2/watchdog/watchdog.c +408 -0
  376. data/pgpool2/watchdog/watchdog.h +209 -0
  377. data/pgpool2/watchdog/wd_child.c +444 -0
  378. data/pgpool2/watchdog/wd_ext.h +123 -0
  379. data/pgpool2/watchdog/wd_heartbeat.c +577 -0
  380. data/pgpool2/watchdog/wd_if.c +216 -0
  381. data/pgpool2/watchdog/wd_init.c +126 -0
  382. data/pgpool2/watchdog/wd_interlock.c +347 -0
  383. data/pgpool2/watchdog/wd_lifecheck.c +512 -0
  384. data/pgpool2/watchdog/wd_list.c +429 -0
  385. data/pgpool2/watchdog/wd_packet.c +1159 -0
  386. data/pgpool2/watchdog/wd_ping.c +330 -0
  387. data/pgpool2/ylwrap +223 -0
  388. data/pgsql/presto_client.py +346 -0
  389. data/pgsql/prestogres.py +156 -0
  390. data/pgsql/setup_functions.sql +21 -0
  391. data/pgsql/setup_language.sql +3 -0
  392. data/prestogres.gemspec +23 -0
  393. metadata +496 -0
@@ -0,0 +1,120 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * scanner.h
4
+ * API for the core scanner (flex machine)
5
+ *
6
+ * The core scanner is also used by PL/pgsql, so we provide a public API
7
+ * for it. However, the rest of the backend is only expected to use the
8
+ * higher-level API provided by parser.h.
9
+ *
10
+ *
11
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
12
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
13
+ * Portions Copyright (c) 1994, Regents of the University of California
14
+ *
15
+ * src/include/parser/scanner.h
16
+ *
17
+ *-------------------------------------------------------------------------
18
+ */
19
+
20
+ #ifndef SCANNER_H
21
+ #define SCANNER_H
22
+
23
+ #include "keywords.h"
24
+
25
+ /*
26
+ * The scanner returns extra data about scanned tokens in this union type.
27
+ * Note that this is a subset of the fields used in YYSTYPE of the bison
28
+ * parsers built atop the scanner.
29
+ */
30
+ typedef union core_YYSTYPE
31
+ {
32
+ int ival; /* for integer literals */
33
+ char *str; /* for identifiers and non-integer literals */
34
+ const char *keyword; /* canonical spelling of keywords */
35
+ } core_YYSTYPE;
36
+
37
+ /*
38
+ * We track token locations in terms of byte offsets from the start of the
39
+ * source string, not the column number/line number representation that
40
+ * bison uses by default. Also, to minimize overhead we track only one
41
+ * location (usually the first token location) for each construct, not
42
+ * the beginning and ending locations as bison does by default. It's
43
+ * therefore sufficient to make YYLTYPE an int.
44
+ */
45
+ #define YYLTYPE int
46
+
47
+ /*
48
+ * Another important component of the scanner's API is the token code numbers.
49
+ * However, those are not defined in this file, because bison insists on
50
+ * defining them for itself. The token codes used by the core scanner are
51
+ * the ASCII characters plus these:
52
+ * %token <str> IDENT FCONST SCONST BCONST XCONST Op
53
+ * %token <ival> ICONST PARAM
54
+ * %token TYPECAST DOT_DOT COLON_EQUALS
55
+ * The above token definitions *must* be the first ones declared in any
56
+ * bison parser built atop this scanner, so that they will have consistent
57
+ * numbers assigned to them (specifically, IDENT = 258 and so on).
58
+ */
59
+
60
+ /*
61
+ * The YY_EXTRA data that a flex scanner allows us to pass around.
62
+ * Private state needed by the core scanner goes here. Note that the actual
63
+ * yy_extra struct may be larger and have this as its first component, thus
64
+ * allowing the calling parser to keep some fields of its own in YY_EXTRA.
65
+ */
66
+ typedef struct core_yy_extra_type
67
+ {
68
+ /*
69
+ * The string the scanner is physically scanning. We keep this mainly so
70
+ * that we can cheaply compute the offset of the current token (yytext).
71
+ */
72
+ char *scanbuf;
73
+ Size scanbuflen;
74
+
75
+ /*
76
+ * The keyword list to use.
77
+ */
78
+ const ScanKeyword *keywords;
79
+ int num_keywords;
80
+
81
+ /*
82
+ * literalbuf is used to accumulate literal values when multiple rules are
83
+ * needed to parse a single literal. Call startlit() to reset buffer to
84
+ * empty, addlit() to add text. NOTE: the string in literalbuf is NOT
85
+ * necessarily null-terminated, but there always IS room to add a trailing
86
+ * null at offset literallen. We store a null only when we need it.
87
+ */
88
+ char *literalbuf; /* palloc'd expandable buffer */
89
+ int literallen; /* actual current string length */
90
+ int literalalloc; /* current allocated buffer size */
91
+
92
+ int xcdepth; /* depth of nesting in slash-star comments */
93
+ char *dolqstart; /* current $foo$ quote start string */
94
+
95
+ /* first part of UTF16 surrogate pair for Unicode escapes */
96
+ int32 utf16_first_part;
97
+
98
+ /* state variables for literal-lexing warnings */
99
+ bool warn_on_first_escape;
100
+ bool saw_non_ascii;
101
+ } core_yy_extra_type;
102
+
103
+ /*
104
+ * The type of yyscanner is opaque outside scan.l.
105
+ */
106
+ typedef void *core_yyscan_t;
107
+
108
+
109
+ /* Entry points in parser/scan.l */
110
+ extern core_yyscan_t scanner_init(const char *str,
111
+ core_yy_extra_type *yyext,
112
+ const ScanKeyword *keywords,
113
+ int num_keywords);
114
+ extern void scanner_finish(core_yyscan_t yyscanner);
115
+ extern int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp,
116
+ core_yyscan_t yyscanner);
117
+ extern int scanner_errposition(int location, core_yyscan_t yyscanner);
118
+ extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner);
119
+
120
+ #endif /* SCANNER_H */
@@ -0,0 +1,221 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * scansup.c
4
+ * support routines for the lex/flex scanner, used by both the normal
5
+ * backend as well as the bootstrap backend
6
+ *
7
+ * Portions Copyright (c) 1996-2013, PgPool Global Development Group
8
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
9
+ * Portions Copyright (c) 1994, Regents of the University of California
10
+ *
11
+ *
12
+ * IDENTIFICATION
13
+ * src/backend/parser/scansup.c
14
+ *
15
+ *-------------------------------------------------------------------------
16
+ */
17
+ #include "pool_parser.h"
18
+ #include "pool_memory.h"
19
+
20
+ #include <ctype.h>
21
+ #include <string.h>
22
+
23
+ #include "scansup.h"
24
+ #include "pg_wchar.h"
25
+
26
+
27
+ /* ----------------
28
+ * scanstr
29
+ *
30
+ * if the string passed in has escaped codes, map the escape codes to actual
31
+ * chars
32
+ *
33
+ * the string returned is palloc'd and should eventually be pfree'd by the
34
+ * caller!
35
+ * ----------------
36
+ */
37
+ char *
38
+ scanstr(const char *s)
39
+ {
40
+ char *newStr;
41
+ int len,
42
+ i,
43
+ j;
44
+
45
+ if (s == NULL || s[0] == '\0')
46
+ return pstrdup("");
47
+
48
+ len = strlen(s);
49
+
50
+ newStr = palloc(len + 1); /* string cannot get longer */
51
+
52
+ for (i = 0, j = 0; i < len; i++)
53
+ {
54
+ if (s[i] == '\'')
55
+ {
56
+ /*
57
+ * Note: if scanner is working right, unescaped quotes can only
58
+ * appear in pairs, so there should be another character.
59
+ */
60
+ i++;
61
+ newStr[j] = s[i];
62
+ }
63
+ else if (s[i] == '\\')
64
+ {
65
+ i++;
66
+ switch (s[i])
67
+ {
68
+ case 'b':
69
+ newStr[j] = '\b';
70
+ break;
71
+ case 'f':
72
+ newStr[j] = '\f';
73
+ break;
74
+ case 'n':
75
+ newStr[j] = '\n';
76
+ break;
77
+ case 'r':
78
+ newStr[j] = '\r';
79
+ break;
80
+ case 't':
81
+ newStr[j] = '\t';
82
+ break;
83
+ case '0':
84
+ case '1':
85
+ case '2':
86
+ case '3':
87
+ case '4':
88
+ case '5':
89
+ case '6':
90
+ case '7':
91
+ {
92
+ int k;
93
+ long octVal = 0;
94
+
95
+ for (k = 0;
96
+ s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
97
+ k++)
98
+ octVal = (octVal << 3) + (s[i + k] - '0');
99
+ i += k - 1;
100
+ newStr[j] = ((char) octVal);
101
+ }
102
+ break;
103
+ default:
104
+ newStr[j] = s[i];
105
+ break;
106
+ } /* switch */
107
+ } /* s[i] == '\\' */
108
+ else
109
+ newStr[j] = s[i];
110
+ j++;
111
+ }
112
+ newStr[j] = '\0';
113
+ return newStr;
114
+ }
115
+
116
+
117
+ /*
118
+ * downcase_truncate_identifier() --- do appropriate downcasing and
119
+ * truncation of an unquoted identifier. Optionally warn of truncation.
120
+ *
121
+ * Returns a palloc'd string containing the adjusted identifier.
122
+ *
123
+ * Note: in some usages the passed string is not null-terminated.
124
+ *
125
+ * Note: the API of this function is designed to allow for downcasing
126
+ * transformations that increase the string length, but we don't yet
127
+ * support that. If you want to implement it, you'll need to fix
128
+ * SplitIdentifierString() in utils/adt/varlena.c.
129
+ */
130
+ char *
131
+ downcase_truncate_identifier(const char *ident, int len, bool warn)
132
+ {
133
+ char *result;
134
+ int i;
135
+
136
+ result = palloc(len + 1);
137
+
138
+ /*
139
+ * SQL99 specifies Unicode-aware case normalization, which we don't yet
140
+ * have the infrastructure for. Instead we use tolower() to provide a
141
+ * locale-aware translation. However, there are some locales where this
142
+ * is not right either (eg, Turkish may do strange things with 'i' and
143
+ * 'I'). Our current compromise is to use tolower() for characters with
144
+ * the high bit set, and use an ASCII-only downcasing for 7-bit
145
+ * characters.
146
+ */
147
+ for (i = 0; i < len; i++)
148
+ {
149
+ unsigned char ch = (unsigned char) ident[i];
150
+
151
+ if (ch >= 'A' && ch <= 'Z')
152
+ ch += 'a' - 'A';
153
+ else if (IS_HIGHBIT_SET(ch) && isupper(ch))
154
+ ch = tolower(ch);
155
+ result[i] = (char) ch;
156
+ }
157
+ result[i] = '\0';
158
+
159
+ if (i >= NAMEDATALEN)
160
+ truncate_identifier(result, i, warn);
161
+
162
+ return result;
163
+ }
164
+
165
+ /*
166
+ * truncate_identifier() --- truncate an identifier to NAMEDATALEN-1 bytes.
167
+ *
168
+ * The given string is modified in-place, if necessary. A warning is
169
+ * issued if requested.
170
+ *
171
+ * We require the caller to pass in the string length since this saves a
172
+ * strlen() call in some common usages.
173
+ */
174
+ void
175
+ truncate_identifier(char *ident, int len, bool warn)
176
+ {
177
+ #if PGPOOL_NOT_USED
178
+ if (len >= NAMEDATALEN)
179
+ {
180
+ len = pg_mbcliplen(ident, len, NAMEDATALEN - 1);
181
+ if (warn)
182
+ {
183
+ /*
184
+ * We avoid using %.*s here because it can misbehave if the data
185
+ * is not valid in what libc thinks is the prevailing encoding.
186
+ */
187
+ char buf[NAMEDATALEN];
188
+
189
+ memcpy(buf, ident, len);
190
+ buf[len] = '\0';
191
+ ereport(NOTICE,
192
+ (errcode(ERRCODE_NAME_TOO_LONG),
193
+ errmsg("identifier \"%s\" will be truncated to \"%s\"",
194
+ ident, buf)));
195
+ }
196
+ ident[len] = '\0';
197
+ }
198
+ #endif
199
+ }
200
+
201
+ /*
202
+ * scanner_isspace() --- return TRUE if flex scanner considers char whitespace
203
+ *
204
+ * This should be used instead of the potentially locale-dependent isspace()
205
+ * function when it's important to match the lexer's behavior.
206
+ *
207
+ * In principle we might need similar functions for isalnum etc, but for the
208
+ * moment only isspace seems needed.
209
+ */
210
+ bool
211
+ scanner_isspace(char ch)
212
+ {
213
+ /* This must match scan.l's list of {space} characters */
214
+ if (ch == ' ' ||
215
+ ch == '\t' ||
216
+ ch == '\n' ||
217
+ ch == '\r' ||
218
+ ch == '\f')
219
+ return true;
220
+ return false;
221
+ }
@@ -0,0 +1,28 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * scansup.h
4
+ * scanner support routines. used by both the bootstrap lexer
5
+ * as well as the normal lexer
6
+ *
7
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
8
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
9
+ * Portions Copyright (c) 1994, Regents of the University of California
10
+ *
11
+ * src/include/parser/scansup.h
12
+ *
13
+ *-------------------------------------------------------------------------
14
+ */
15
+
16
+ #ifndef SCANSUP_H
17
+ #define SCANSUP_H
18
+
19
+ extern char *scanstr(const char *s);
20
+
21
+ extern char *downcase_truncate_identifier(const char *ident, int len,
22
+ bool warn);
23
+
24
+ extern void truncate_identifier(char *ident, int len, bool warn);
25
+
26
+ extern bool scanner_isspace(char ch);
27
+
28
+ #endif /* SCANSUP_H */
@@ -0,0 +1,1102 @@
1
+ /*
2
+ * Copyright (c) 1983, 1995, 1996 Eric P. Allman
3
+ * Copyright (c) 1988, 1993
4
+ * The Regents of the University of California. All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * 3. Neither the name of the University nor the names of its contributors
15
+ * may be used to endorse or promote products derived from this software
16
+ * without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
+ * SUCH DAMAGE.
29
+ *
30
+ * src/port/snprintf.c
31
+ */
32
+
33
+ /*
34
+ #include "c.h"
35
+
36
+ #include <limits.h>
37
+ #ifndef WIN32
38
+ #include <sys/ioctl.h>
39
+ #endif
40
+ #include <sys/param.h>
41
+ */
42
+
43
+ #ifndef NL_ARGMAX
44
+ #define NL_ARGMAX 16
45
+ #endif
46
+
47
+ #include <stdarg.h>
48
+ #include <stdio.h>
49
+ #include <stdint.h>
50
+ #include <stdlib.h>
51
+ #include <string.h>
52
+ #include <ctype.h>
53
+ #include <errno.h>
54
+ #include "pool_memory.h"
55
+ #include "pool_parser.h"
56
+ #include "stringinfo.h"
57
+
58
+ /* --------------------------------------------------------------------- */
59
+ /* c.h */
60
+ /* --------------------------------------------------------------------- */
61
+
62
+ /* Get a bit mask of the bits set in non-long aligned addresses */
63
+ #define LONG_ALIGN_MASK (sizeof(long) - 1)
64
+
65
+ #define MEMSET_LOOP_LIMIT 1024
66
+
67
+ /*
68
+ * MemSet
69
+ * Exactly the same as standard library function memset(), but considerably
70
+ * faster for zeroing small word-aligned structures (such as parsetree nodes).
71
+ * This has to be a macro because the main point is to avoid function-call
72
+ * overhead. However, we have also found that the loop is faster than
73
+ * native libc memset() on some platforms, even those with assembler
74
+ * memset() functions. More research needs to be done, perhaps with
75
+ * MEMSET_LOOP_LIMIT tests in configure.
76
+ */
77
+ #define MemSet(start, val, len) \
78
+ do \
79
+ { \
80
+ /* must be void* because we don't know if it is integer aligned yet */ \
81
+ void *_vstart = (void *) (start); \
82
+ int _val = (val); \
83
+ Size _len = (len); \
84
+ \
85
+ if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
86
+ (_len & LONG_ALIGN_MASK) == 0 && \
87
+ _val == 0 && \
88
+ _len <= MEMSET_LOOP_LIMIT && \
89
+ /* \
90
+ * If MEMSET_LOOP_LIMIT == 0, optimizer should find \
91
+ * the whole "if" false at compile time. \
92
+ */ \
93
+ MEMSET_LOOP_LIMIT != 0) \
94
+ { \
95
+ long *_start = (long *) _vstart; \
96
+ long *_stop = (long *) ((char *) _start + _len); \
97
+ while (_start < _stop) \
98
+ *_start++ = 0; \
99
+ } \
100
+ else \
101
+ memset(_vstart, _val, _len); \
102
+ } while (0)
103
+
104
+ /*
105
+ * SNPRINTF, VSNPRINTF and friends
106
+ *
107
+ * These versions have been grabbed off the net. They have been
108
+ * cleaned up to compile properly and support for most of the Single Unix
109
+ * Specification has been added. Remaining unimplemented features are:
110
+ *
111
+ * 1. No locale support: the radix character is always '.' and the '
112
+ * (single quote) format flag is ignored.
113
+ *
114
+ * 2. No support for the "%n" format specification.
115
+ *
116
+ * 3. No support for wide characters ("lc" and "ls" formats).
117
+ *
118
+ * 4. No support for "long double" ("Lf" and related formats).
119
+ *
120
+ * 5. Space and '#' flags are not implemented.
121
+ *
122
+ *
123
+ * The result values of these functions are not the same across different
124
+ * platforms. This implementation is compatible with the Single Unix Spec:
125
+ *
126
+ * 1. -1 is returned only if processing is abandoned due to an invalid
127
+ * parameter, such as incorrect format string. (Although not required by
128
+ * the spec, this happens only when no characters have yet been transmitted
129
+ * to the destination.)
130
+ *
131
+ * 2. For snprintf and sprintf, 0 is returned if str == NULL or count == 0;
132
+ * no data has been stored.
133
+ *
134
+ * 3. Otherwise, the number of bytes actually transmitted to the destination
135
+ * is returned (excluding the trailing '\0' for snprintf and sprintf).
136
+ *
137
+ * For snprintf with nonzero count, the result cannot be more than count-1
138
+ * (a trailing '\0' is always stored); it is not possible to distinguish
139
+ * buffer overrun from exact fit. This is unlike some implementations that
140
+ * return the number of bytes that would have been needed for the complete
141
+ * result string.
142
+ */
143
+
144
+ /**************************************************************
145
+ * Original:
146
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
147
+ * A bombproof version of doprnt (dopr) included.
148
+ * Sigh. This sort of thing is always nasty do deal with. Note that
149
+ * the version here does not include floating point. (now it does ... tgl)
150
+ **************************************************************/
151
+
152
+ /* Prevent recursion */
153
+ #undef vsnprintf
154
+ #undef snprintf
155
+ #undef sprintf
156
+ #undef vfprintf
157
+ #undef fprintf
158
+ #undef printf
159
+
160
+ /* Info about where the formatted output is going */
161
+ typedef struct
162
+ {
163
+ char *bufptr; /* next buffer output position */
164
+ char *bufstart; /* first buffer element */
165
+ char *bufend; /* last buffer element, or NULL */
166
+ /* bufend == NULL is for sprintf, where we assume buf is big enough */
167
+ FILE *stream; /* eventual output destination, or NULL */
168
+ int nchars; /* # chars already sent to stream */
169
+ } PrintfTarget;
170
+
171
+ /*
172
+ * Info about the type and value of a formatting parameter. Note that we
173
+ * don't currently support "long double", "wint_t", or "wchar_t *" data,
174
+ * nor the '%n' formatting code; else we'd need more types. Also, at this
175
+ * level we need not worry about signed vs unsigned values.
176
+ */
177
+ typedef enum
178
+ {
179
+ ATYPE_NONE = 0,
180
+ ATYPE_INT,
181
+ ATYPE_LONG,
182
+ ATYPE_LONGLONG,
183
+ ATYPE_DOUBLE,
184
+ ATYPE_CHARPTR
185
+ } PrintfArgType;
186
+
187
+ typedef union
188
+ {
189
+ int i;
190
+ long l;
191
+ int64 ll;
192
+ double d;
193
+ char *cptr;
194
+ } PrintfArgValue;
195
+
196
+
197
+ static void flushbuffer(PrintfTarget *target);
198
+ static int dopr(PrintfTarget *target, const char *format, va_list args);
199
+
200
+
201
+ int
202
+ pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
203
+ {
204
+ PrintfTarget target;
205
+
206
+ if (str == NULL || count == 0)
207
+ return 0;
208
+ target.bufstart = target.bufptr = str;
209
+ target.bufend = str + count - 1;
210
+ target.stream = NULL;
211
+ /* target.nchars is unused in this case */
212
+ if (dopr(&target, fmt, args))
213
+ {
214
+ *(target.bufptr) = '\0';
215
+
216
+ errno = EINVAL; /* bad format */
217
+
218
+ return -1;
219
+ }
220
+ *(target.bufptr) = '\0';
221
+ return target.bufptr - target.bufstart;
222
+ }
223
+
224
+ #if 0
225
+ int
226
+ pg_snprintf(char *str, size_t count, const char *fmt,...)
227
+ {
228
+ int len;
229
+ va_list args;
230
+
231
+ va_start(args, fmt);
232
+ len = pg_vsnprintf(str, count, fmt, args);
233
+ va_end(args);
234
+ return len;
235
+ }
236
+
237
+ static int
238
+ pg_vsprintf(char *str, const char *fmt, va_list args)
239
+ {
240
+ PrintfTarget target;
241
+
242
+ if (str == NULL)
243
+ return 0;
244
+ target.bufstart = target.bufptr = str;
245
+ target.bufend = NULL;
246
+ target.stream = NULL;
247
+ /* target.nchars is unused in this case */
248
+ if (dopr(&target, fmt, args))
249
+ {
250
+ *(target.bufptr) = '\0';
251
+
252
+ errno = EINVAL; /* bad format */
253
+
254
+ return -1;
255
+ }
256
+ *(target.bufptr) = '\0';
257
+ return target.bufptr - target.bufstart;
258
+ }
259
+
260
+ int
261
+ pg_sprintf(char *str, const char *fmt,...)
262
+ {
263
+ int len;
264
+ va_list args;
265
+
266
+ va_start(args, fmt);
267
+ len = pg_vsprintf(str, fmt, args);
268
+ va_end(args);
269
+ return len;
270
+ }
271
+
272
+ int
273
+ pg_vfprintf(FILE *stream, const char *fmt, va_list args)
274
+ {
275
+ PrintfTarget target;
276
+ char buffer[1024]; /* size is arbitrary */
277
+
278
+ if (stream == NULL)
279
+ {
280
+ errno = EINVAL;
281
+ return -1;
282
+ }
283
+ target.bufstart = target.bufptr = buffer;
284
+ target.bufend = buffer + sizeof(buffer) - 1;
285
+ target.stream = stream;
286
+ target.nchars = 0;
287
+ if (dopr(&target, fmt, args))
288
+ {
289
+ errno = EINVAL; /* bad format */
290
+ return -1;
291
+ }
292
+ /* dump any remaining buffer contents */
293
+ flushbuffer(&target);
294
+ return target.nchars;
295
+ }
296
+
297
+ int
298
+ pg_fprintf(FILE *stream, const char *fmt,...)
299
+ {
300
+ int len;
301
+ va_list args;
302
+
303
+ va_start(args, fmt);
304
+ len = pg_vfprintf(stream, fmt, args);
305
+ va_end(args);
306
+ return len;
307
+ }
308
+
309
+ int
310
+ pg_printf(const char *fmt,...)
311
+ {
312
+ int len;
313
+ va_list args;
314
+
315
+ va_start(args, fmt);
316
+ len = pg_vfprintf(stdout, fmt, args);
317
+ va_end(args);
318
+ return len;
319
+ }
320
+ #endif
321
+
322
+ /* call this only when stream is defined */
323
+ static void
324
+ flushbuffer(PrintfTarget *target)
325
+ {
326
+ size_t nc = target->bufptr - target->bufstart;
327
+
328
+ if (nc > 0)
329
+ target->nchars += fwrite(target->bufstart, 1, nc, target->stream);
330
+ target->bufptr = target->bufstart;
331
+ }
332
+
333
+ static void fmtstr(char *value, int leftjust, int minlen, int maxwidth,
334
+ int pointflag, PrintfTarget *target);
335
+ static void fmtptr(void *value, PrintfTarget *target);
336
+ static void fmtint(int64 value, char type, int forcesign,
337
+ int leftjust, int minlen, int zpad, int precision, int pointflag,
338
+ PrintfTarget *target);
339
+ static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target);
340
+ static void fmtfloat(double value, char type, int forcesign,
341
+ int leftjust, int minlen, int zpad, int precision, int pointflag,
342
+ PrintfTarget *target);
343
+ static void dostr(const char *str, int slen, PrintfTarget *target);
344
+ static void dopr_outch(int c, PrintfTarget *target);
345
+ static int adjust_sign(int is_negative, int forcesign, int *signvalue);
346
+ static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen);
347
+ static void leading_pad(int zpad, int *signvalue, int *padlen,
348
+ PrintfTarget *target);
349
+ static void trailing_pad(int *padlen, PrintfTarget *target);
350
+
351
+ /*
352
+ * dopr(): poor man's version of doprintf
353
+ */
354
+ static int
355
+ dopr(PrintfTarget *target, const char *format, va_list args)
356
+ {
357
+ const char *format_start = format;
358
+ int ch;
359
+ bool have_dollar;
360
+ bool have_non_dollar;
361
+ bool have_star;
362
+ bool afterstar;
363
+ int accum;
364
+ int longlongflag;
365
+ int longflag;
366
+ int pointflag;
367
+ int leftjust;
368
+ int fieldwidth;
369
+ int precision;
370
+ int zpad;
371
+ int forcesign;
372
+ int last_dollar;
373
+ int fmtpos;
374
+ int cvalue;
375
+ int64 numvalue;
376
+ double fvalue;
377
+ char *strvalue;
378
+ int i;
379
+ PrintfArgType argtypes[NL_ARGMAX + 1];
380
+ PrintfArgValue argvalues[NL_ARGMAX + 1];
381
+
382
+ /*
383
+ * Parse the format string to determine whether there are %n$ format
384
+ * specs, and identify the types and order of the format parameters.
385
+ */
386
+ have_dollar = have_non_dollar = false;
387
+ last_dollar = 0;
388
+ MemSet(argtypes, 0, sizeof(argtypes));
389
+
390
+ while ((ch = *format++) != '\0')
391
+ {
392
+ if (ch != '%')
393
+ continue;
394
+ longflag = longlongflag = pointflag = 0;
395
+ fmtpos = accum = 0;
396
+ afterstar = false;
397
+ nextch1:
398
+ ch = *format++;
399
+ if (ch == '\0')
400
+ break; /* illegal, but we don't complain */
401
+ switch (ch)
402
+ {
403
+ case '-':
404
+ case '+':
405
+ goto nextch1;
406
+ case '0':
407
+ case '1':
408
+ case '2':
409
+ case '3':
410
+ case '4':
411
+ case '5':
412
+ case '6':
413
+ case '7':
414
+ case '8':
415
+ case '9':
416
+ accum = accum * 10 + (ch - '0');
417
+ goto nextch1;
418
+ case '.':
419
+ pointflag = 1;
420
+ accum = 0;
421
+ goto nextch1;
422
+ case '*':
423
+ if (afterstar)
424
+ have_non_dollar = true; /* multiple stars */
425
+ afterstar = true;
426
+ accum = 0;
427
+ goto nextch1;
428
+ case '$':
429
+ have_dollar = true;
430
+ if (accum <= 0 || accum > NL_ARGMAX)
431
+ return -1;
432
+ if (afterstar)
433
+ {
434
+ if (argtypes[accum] &&
435
+ argtypes[accum] != ATYPE_INT)
436
+ return -1;
437
+ argtypes[accum] = ATYPE_INT;
438
+ last_dollar = Max(last_dollar, accum);
439
+ afterstar = false;
440
+ }
441
+ else
442
+ fmtpos = accum;
443
+ accum = 0;
444
+ goto nextch1;
445
+ case 'l':
446
+ if (longflag)
447
+ longlongflag = 1;
448
+ else
449
+ longflag = 1;
450
+ goto nextch1;
451
+ case 'h':
452
+ case '\'':
453
+ /* ignore these */
454
+ goto nextch1;
455
+ case 'd':
456
+ case 'i':
457
+ case 'o':
458
+ case 'u':
459
+ case 'x':
460
+ case 'X':
461
+ if (fmtpos)
462
+ {
463
+ PrintfArgType atype;
464
+
465
+ if (longlongflag)
466
+ atype = ATYPE_LONGLONG;
467
+ else if (longflag)
468
+ atype = ATYPE_LONG;
469
+ else
470
+ atype = ATYPE_INT;
471
+ if (argtypes[fmtpos] &&
472
+ argtypes[fmtpos] != atype)
473
+ return -1;
474
+ argtypes[fmtpos] = atype;
475
+ last_dollar = Max(last_dollar, fmtpos);
476
+ }
477
+ else
478
+ have_non_dollar = true;
479
+ break;
480
+ case 'c':
481
+ if (fmtpos)
482
+ {
483
+ if (argtypes[fmtpos] &&
484
+ argtypes[fmtpos] != ATYPE_INT)
485
+ return -1;
486
+ argtypes[fmtpos] = ATYPE_INT;
487
+ last_dollar = Max(last_dollar, fmtpos);
488
+ }
489
+ else
490
+ have_non_dollar = true;
491
+ break;
492
+ case 's':
493
+ case 'p':
494
+ if (fmtpos)
495
+ {
496
+ if (argtypes[fmtpos] &&
497
+ argtypes[fmtpos] != ATYPE_CHARPTR)
498
+ return -1;
499
+ argtypes[fmtpos] = ATYPE_CHARPTR;
500
+ last_dollar = Max(last_dollar, fmtpos);
501
+ }
502
+ else
503
+ have_non_dollar = true;
504
+ break;
505
+ case 'e':
506
+ case 'E':
507
+ case 'f':
508
+ case 'g':
509
+ case 'G':
510
+ if (fmtpos)
511
+ {
512
+ if (argtypes[fmtpos] &&
513
+ argtypes[fmtpos] != ATYPE_DOUBLE)
514
+ return -1;
515
+ argtypes[fmtpos] = ATYPE_DOUBLE;
516
+ last_dollar = Max(last_dollar, fmtpos);
517
+ }
518
+ else
519
+ have_non_dollar = true;
520
+ break;
521
+ case '%':
522
+ break;
523
+ }
524
+
525
+ /*
526
+ * If we finish the spec with afterstar still set, there's a
527
+ * non-dollar star in there.
528
+ */
529
+ if (afterstar)
530
+ have_non_dollar = true;
531
+ }
532
+
533
+ /* Per spec, you use either all dollar or all not. */
534
+ if (have_dollar && have_non_dollar)
535
+ return -1;
536
+
537
+ /*
538
+ * In dollar mode, collect the arguments in physical order.
539
+ */
540
+ for (i = 1; i <= last_dollar; i++)
541
+ {
542
+ switch (argtypes[i])
543
+ {
544
+ case ATYPE_NONE:
545
+ return -1; /* invalid format */
546
+ case ATYPE_INT:
547
+ argvalues[i].i = va_arg(args, int);
548
+ break;
549
+ case ATYPE_LONG:
550
+ argvalues[i].l = va_arg(args, long);
551
+ break;
552
+ case ATYPE_LONGLONG:
553
+ argvalues[i].ll = va_arg(args, int64);
554
+ break;
555
+ case ATYPE_DOUBLE:
556
+ argvalues[i].d = va_arg(args, double);
557
+ break;
558
+ case ATYPE_CHARPTR:
559
+ argvalues[i].cptr = va_arg(args, char *);
560
+ break;
561
+ }
562
+ }
563
+
564
+ /*
565
+ * At last we can parse the format for real.
566
+ */
567
+ format = format_start;
568
+ while ((ch = *format++) != '\0')
569
+ {
570
+ if (ch != '%')
571
+ {
572
+ dopr_outch(ch, target);
573
+ continue;
574
+ }
575
+ fieldwidth = precision = zpad = leftjust = forcesign = 0;
576
+ longflag = longlongflag = pointflag = 0;
577
+ fmtpos = accum = 0;
578
+ have_star = afterstar = false;
579
+ nextch2:
580
+ ch = *format++;
581
+ if (ch == '\0')
582
+ break; /* illegal, but we don't complain */
583
+ switch (ch)
584
+ {
585
+ case '-':
586
+ leftjust = 1;
587
+ goto nextch2;
588
+ case '+':
589
+ forcesign = 1;
590
+ goto nextch2;
591
+ case '0':
592
+ /* set zero padding if no nonzero digits yet */
593
+ if (accum == 0 && !pointflag)
594
+ zpad = '0';
595
+ /* FALL THRU */
596
+ case '1':
597
+ case '2':
598
+ case '3':
599
+ case '4':
600
+ case '5':
601
+ case '6':
602
+ case '7':
603
+ case '8':
604
+ case '9':
605
+ accum = accum * 10 + (ch - '0');
606
+ goto nextch2;
607
+ case '.':
608
+ if (have_star)
609
+ have_star = false;
610
+ else
611
+ fieldwidth = accum;
612
+ pointflag = 1;
613
+ accum = 0;
614
+ goto nextch2;
615
+ case '*':
616
+ if (have_dollar)
617
+ {
618
+ /* process value after reading n$ */
619
+ afterstar = true;
620
+ }
621
+ else
622
+ {
623
+ /* fetch and process value now */
624
+ int starval = va_arg(args, int);
625
+
626
+ if (pointflag)
627
+ {
628
+ precision = starval;
629
+ if (precision < 0)
630
+ {
631
+ precision = 0;
632
+ pointflag = 0;
633
+ }
634
+ }
635
+ else
636
+ {
637
+ fieldwidth = starval;
638
+ if (fieldwidth < 0)
639
+ {
640
+ leftjust = 1;
641
+ fieldwidth = -fieldwidth;
642
+ }
643
+ }
644
+ }
645
+ have_star = true;
646
+ accum = 0;
647
+ goto nextch2;
648
+ case '$':
649
+ if (afterstar)
650
+ {
651
+ /* fetch and process star value */
652
+ int starval = argvalues[accum].i;
653
+
654
+ if (pointflag)
655
+ {
656
+ precision = starval;
657
+ if (precision < 0)
658
+ {
659
+ precision = 0;
660
+ pointflag = 0;
661
+ }
662
+ }
663
+ else
664
+ {
665
+ fieldwidth = starval;
666
+ if (fieldwidth < 0)
667
+ {
668
+ leftjust = 1;
669
+ fieldwidth = -fieldwidth;
670
+ }
671
+ }
672
+ afterstar = false;
673
+ }
674
+ else
675
+ fmtpos = accum;
676
+ accum = 0;
677
+ goto nextch2;
678
+ case 'l':
679
+ if (longflag)
680
+ longlongflag = 1;
681
+ else
682
+ longflag = 1;
683
+ goto nextch2;
684
+ case 'h':
685
+ case '\'':
686
+ /* ignore these */
687
+ goto nextch2;
688
+ case 'd':
689
+ case 'i':
690
+ if (!have_star)
691
+ {
692
+ if (pointflag)
693
+ precision = accum;
694
+ else
695
+ fieldwidth = accum;
696
+ }
697
+ if (have_dollar)
698
+ {
699
+ if (longlongflag)
700
+ numvalue = argvalues[fmtpos].ll;
701
+ else if (longflag)
702
+ numvalue = argvalues[fmtpos].l;
703
+ else
704
+ numvalue = argvalues[fmtpos].i;
705
+ }
706
+ else
707
+ {
708
+ if (longlongflag)
709
+ numvalue = va_arg(args, int64);
710
+ else if (longflag)
711
+ numvalue = va_arg(args, long);
712
+ else
713
+ numvalue = va_arg(args, int);
714
+ }
715
+ fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
716
+ precision, pointflag, target);
717
+ break;
718
+ case 'o':
719
+ case 'u':
720
+ case 'x':
721
+ case 'X':
722
+ if (!have_star)
723
+ {
724
+ if (pointflag)
725
+ precision = accum;
726
+ else
727
+ fieldwidth = accum;
728
+ }
729
+ if (have_dollar)
730
+ {
731
+ if (longlongflag)
732
+ numvalue = (uint64) argvalues[fmtpos].ll;
733
+ else if (longflag)
734
+ numvalue = (unsigned long) argvalues[fmtpos].l;
735
+ else
736
+ numvalue = (unsigned int) argvalues[fmtpos].i;
737
+ }
738
+ else
739
+ {
740
+ if (longlongflag)
741
+ numvalue = (uint64) va_arg(args, int64);
742
+ else if (longflag)
743
+ numvalue = (unsigned long) va_arg(args, long);
744
+ else
745
+ numvalue = (unsigned int) va_arg(args, int);
746
+ }
747
+ fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad,
748
+ precision, pointflag, target);
749
+ break;
750
+ case 'c':
751
+ if (!have_star)
752
+ {
753
+ if (pointflag)
754
+ precision = accum;
755
+ else
756
+ fieldwidth = accum;
757
+ }
758
+ if (have_dollar)
759
+ cvalue = (unsigned char) argvalues[fmtpos].i;
760
+ else
761
+ cvalue = (unsigned char) va_arg(args, int);
762
+ fmtchar(cvalue, leftjust, fieldwidth, target);
763
+ break;
764
+ case 's':
765
+ if (!have_star)
766
+ {
767
+ if (pointflag)
768
+ precision = accum;
769
+ else
770
+ fieldwidth = accum;
771
+ }
772
+ if (have_dollar)
773
+ strvalue = argvalues[fmtpos].cptr;
774
+ else
775
+ strvalue = va_arg(args, char *);
776
+ fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag,
777
+ target);
778
+ break;
779
+ case 'p':
780
+ /* fieldwidth/leftjust are ignored ... */
781
+ if (have_dollar)
782
+ strvalue = argvalues[fmtpos].cptr;
783
+ else
784
+ strvalue = va_arg(args, char *);
785
+ fmtptr((void *) strvalue, target);
786
+ break;
787
+ case 'e':
788
+ case 'E':
789
+ case 'f':
790
+ case 'g':
791
+ case 'G':
792
+ if (!have_star)
793
+ {
794
+ if (pointflag)
795
+ precision = accum;
796
+ else
797
+ fieldwidth = accum;
798
+ }
799
+ if (have_dollar)
800
+ fvalue = argvalues[fmtpos].d;
801
+ else
802
+ fvalue = va_arg(args, double);
803
+ fmtfloat(fvalue, ch, forcesign, leftjust,
804
+ fieldwidth, zpad,
805
+ precision, pointflag,
806
+ target);
807
+ break;
808
+ case '%':
809
+ dopr_outch('%', target);
810
+ break;
811
+ }
812
+ }
813
+
814
+ return 0;
815
+ }
816
+
817
+ static size_t
818
+ pg_strnlen(const char *str, size_t maxlen)
819
+ {
820
+ const char *p = str;
821
+
822
+ while (maxlen-- > 0 && *p)
823
+ p++;
824
+ return p - str;
825
+ }
826
+
827
+ static void
828
+ fmtstr(char *value, int leftjust, int minlen, int maxwidth,
829
+ int pointflag, PrintfTarget *target)
830
+ {
831
+ int padlen,
832
+ vallen; /* amount to pad */
833
+
834
+ /*
835
+ * If a maxwidth (precision) is specified, we must not fetch more bytes
836
+ * than that.
837
+ */
838
+ if (pointflag)
839
+ vallen = pg_strnlen(value, maxwidth);
840
+ else
841
+ vallen = strlen(value);
842
+
843
+ adjust_padlen(minlen, vallen, leftjust, &padlen);
844
+
845
+ while (padlen > 0)
846
+ {
847
+ dopr_outch(' ', target);
848
+ --padlen;
849
+ }
850
+
851
+ dostr(value, vallen, target);
852
+
853
+ trailing_pad(&padlen, target);
854
+ }
855
+
856
+ static void
857
+ fmtptr(void *value, PrintfTarget *target)
858
+ {
859
+ int vallen;
860
+ char convert[64];
861
+
862
+ /* we rely on regular C library's sprintf to do the basic conversion */
863
+ vallen = sprintf(convert, "%p", value);
864
+
865
+ dostr(convert, vallen, target);
866
+ }
867
+
868
+ static void
869
+ fmtint(int64 value, char type, int forcesign, int leftjust,
870
+ int minlen, int zpad, int precision, int pointflag,
871
+ PrintfTarget *target)
872
+ {
873
+ uint64 base;
874
+ int dosign;
875
+ const char *cvt = "0123456789abcdef";
876
+ int signvalue = 0;
877
+ char convert[64];
878
+ int vallen = 0;
879
+ int padlen = 0; /* amount to pad */
880
+ int zeropad; /* extra leading zeroes */
881
+
882
+ switch (type)
883
+ {
884
+ case 'd':
885
+ case 'i':
886
+ base = 10;
887
+ dosign = 1;
888
+ break;
889
+ case 'o':
890
+ base = 8;
891
+ dosign = 0;
892
+ break;
893
+ case 'u':
894
+ base = 10;
895
+ dosign = 0;
896
+ break;
897
+ case 'x':
898
+ base = 16;
899
+ dosign = 0;
900
+ break;
901
+ case 'X':
902
+ cvt = "0123456789ABCDEF";
903
+ base = 16;
904
+ dosign = 0;
905
+ break;
906
+ default:
907
+ return; /* keep compiler quiet */
908
+ }
909
+
910
+ /* Handle +/- */
911
+ if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
912
+ value = -value;
913
+
914
+ /*
915
+ * SUS: the result of converting 0 with an explicit precision of 0 is no
916
+ * characters
917
+ */
918
+ if (value == 0 && pointflag && precision == 0)
919
+ vallen = 0;
920
+ else
921
+ {
922
+ /* make integer string */
923
+ uint64 uvalue = (uint64) value;
924
+
925
+ do
926
+ {
927
+ convert[vallen++] = cvt[uvalue % base];
928
+ uvalue = uvalue / base;
929
+ } while (uvalue);
930
+ }
931
+
932
+ zeropad = Max(0, precision - vallen);
933
+
934
+ adjust_padlen(minlen, vallen + zeropad, leftjust, &padlen);
935
+
936
+ leading_pad(zpad, &signvalue, &padlen, target);
937
+
938
+ while (zeropad-- > 0)
939
+ dopr_outch('0', target);
940
+
941
+ while (vallen > 0)
942
+ dopr_outch(convert[--vallen], target);
943
+
944
+ trailing_pad(&padlen, target);
945
+ }
946
+
947
+ static void
948
+ fmtchar(int value, int leftjust, int minlen, PrintfTarget *target)
949
+ {
950
+ int padlen = 0; /* amount to pad */
951
+
952
+ adjust_padlen(minlen, 1, leftjust, &padlen);
953
+
954
+ while (padlen > 0)
955
+ {
956
+ dopr_outch(' ', target);
957
+ --padlen;
958
+ }
959
+
960
+ dopr_outch(value, target);
961
+
962
+ trailing_pad(&padlen, target);
963
+ }
964
+
965
+ static void
966
+ fmtfloat(double value, char type, int forcesign, int leftjust,
967
+ int minlen, int zpad, int precision, int pointflag,
968
+ PrintfTarget *target)
969
+ {
970
+ int signvalue = 0;
971
+ int vallen;
972
+ char fmt[32];
973
+ char convert[512];
974
+ int padlen = 0; /* amount to pad */
975
+
976
+ /* we rely on regular C library's sprintf to do the basic conversion */
977
+ if (pointflag)
978
+ sprintf(fmt, "%%.%d%c", precision, type);
979
+ else
980
+ sprintf(fmt, "%%%c", type);
981
+
982
+ if (adjust_sign((value < 0), forcesign, &signvalue))
983
+ value = -value;
984
+
985
+ vallen = sprintf(convert, fmt, value);
986
+
987
+ adjust_padlen(minlen, vallen, leftjust, &padlen);
988
+
989
+ leading_pad(zpad, &signvalue, &padlen, target);
990
+
991
+ dostr(convert, vallen, target);
992
+
993
+ trailing_pad(&padlen, target);
994
+ }
995
+
996
+ static void
997
+ dostr(const char *str, int slen, PrintfTarget *target)
998
+ {
999
+ while (slen > 0)
1000
+ {
1001
+ int avail;
1002
+
1003
+ if (target->bufend != NULL)
1004
+ avail = target->bufend - target->bufptr;
1005
+ else
1006
+ avail = slen;
1007
+ if (avail <= 0)
1008
+ {
1009
+ /* buffer full, can we dump to stream? */
1010
+ if (target->stream == NULL)
1011
+ return; /* no, lose the data */
1012
+ flushbuffer(target);
1013
+ continue;
1014
+ }
1015
+ avail = Min(avail, slen);
1016
+ memmove(target->bufptr, str, avail);
1017
+ target->bufptr += avail;
1018
+ str += avail;
1019
+ slen -= avail;
1020
+ }
1021
+ }
1022
+
1023
+ static void
1024
+ dopr_outch(int c, PrintfTarget *target)
1025
+ {
1026
+ if (target->bufend != NULL && target->bufptr >= target->bufend)
1027
+ {
1028
+ /* buffer full, can we dump to stream? */
1029
+ if (target->stream == NULL)
1030
+ return; /* no, lose the data */
1031
+ flushbuffer(target);
1032
+ }
1033
+ *(target->bufptr++) = c;
1034
+ }
1035
+
1036
+ static int
1037
+ adjust_sign(int is_negative, int forcesign, int *signvalue)
1038
+ {
1039
+ if (is_negative)
1040
+ {
1041
+ *signvalue = '-';
1042
+ return true;
1043
+ }
1044
+ else if (forcesign)
1045
+ *signvalue = '+';
1046
+ return false;
1047
+ }
1048
+
1049
+
1050
+ static void
1051
+ adjust_padlen(int minlen, int vallen, int leftjust, int *padlen)
1052
+ {
1053
+ *padlen = minlen - vallen;
1054
+ if (*padlen < 0)
1055
+ *padlen = 0;
1056
+ if (leftjust)
1057
+ *padlen = -(*padlen);
1058
+ }
1059
+
1060
+
1061
+ static void
1062
+ leading_pad(int zpad, int *signvalue, int *padlen, PrintfTarget *target)
1063
+ {
1064
+ if (*padlen > 0 && zpad)
1065
+ {
1066
+ if (*signvalue)
1067
+ {
1068
+ dopr_outch(*signvalue, target);
1069
+ --(*padlen);
1070
+ *signvalue = 0;
1071
+ }
1072
+ while (*padlen > 0)
1073
+ {
1074
+ dopr_outch(zpad, target);
1075
+ --(*padlen);
1076
+ }
1077
+ }
1078
+ while (*padlen > (*signvalue != 0))
1079
+ {
1080
+ dopr_outch(' ', target);
1081
+ --(*padlen);
1082
+ }
1083
+ if (*signvalue)
1084
+ {
1085
+ dopr_outch(*signvalue, target);
1086
+ if (*padlen > 0)
1087
+ --(*padlen);
1088
+ else if (*padlen < 0)
1089
+ ++(*padlen);
1090
+ }
1091
+ }
1092
+
1093
+
1094
+ static void
1095
+ trailing_pad(int *padlen, PrintfTarget *target)
1096
+ {
1097
+ while (*padlen < 0)
1098
+ {
1099
+ dopr_outch(' ', target);
1100
+ ++(*padlen);
1101
+ }
1102
+ }