Dump facility in C++ like var_dump() in PHP? - php

When I was in college i did some C/C++, but in near future i was working in PHP, and now I wish to put more time in learning C/C++.
In PHP i was using print_r() or var_dump() in order to display datas from structures or arrays. Do I have such a default functionality in C, in order to see what do i have in a struct or array?

There is no such functionality in C++. You can of course write your own Dump() functions. The reason such a feature cannot be generally provided is that the C++ compilation process removes the object metadata needed to structure the dump output. You can of course display structure contents in a debugger, where such metadata is maintained in the debug information.
BTW, are you asking about C or C++? The two languages are quite different, both in features and approach, although neither has var_dump() or similar.

C++ in itself doesn't provide something like var_dump, but with libraries like Boost.Fusion and the ADAPT_STRUCT and ADAPT_ADT facility it's easily doable.
Indeed as told in the other response, the C++ compiler doesn't generate the metadata needed to generate such an output. However it is possible to generate these metadata and use a bit of template metaprogramming to use them.
That way I've implemented here an adapted_struct_printer, which can print std::container, any classes or structures, boost::variant and boost::tuple.
New solution
Now you can easily do the following :
#include <iostream>
#include <pre/json/to_json.hpp>
struct customer {
std::string name;
size_t money_spent;
std::vector<std::string> interests;
};
BOOST_FUSION_ADAPT_STRUCT(customer,
name,
money_spent,
interests)
...
customer my_customer{
"Mr. Dupond",
1000,
{"sport articles", "food", "tools"}
};
std::cout << pre::json::to_json(my_customer) << std::endl;
You can inversely with this library also do from_json to populate structures from json.
A documentation is available here : http://daminetreg.github.io/lib-cpp-pre/html/namespacepre_1_1json.html#a4325d2cdd64a7e321303fd4428f298b9
OLD Response
The only requirement is that you call BOOST_FUSION_ADAPT_STRUCT/BOOST_FUSION_ADAPT_ADT on your classes (See http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/adapted.html)
So that this example :
#include <iostream>
#include <swissarmyknife/boost/fusion/adapted_struct_printer.hpp>
#include <boost/fusion/include/define_struct.hpp>
#include <boost/variant.hpp>
#include <boost/tuple/tuple.hpp>
namespace bla {
struct someclass {
int i = 12;
int j = 15;
};
using boost::fusion::detail::operator <<;
}
BOOST_FUSION_ADAPT_STRUCT(bla::someclass,
(int, i)
(int, j)
)
BOOST_FUSION_DEFINE_STRUCT((bla), innerbim,
(std::string, mystring)
)
BOOST_FUSION_DEFINE_STRUCT((bla), bimbim,
(int, boom)
(int, bam)
(bla::innerbim, my_inner_bim)
)
typedef boost::variant<int, double, bla::innerbim> myvariant_t;
typedef boost::tuple<std::string, int, bla::innerbim, myvariant_t> my_tuple_t;
BOOST_FUSION_DEFINE_STRUCT((bla), blabla,
(bla::bimbim, bim)
(int, i)
(int, j)
(std::vector<double>, list)
(std::list<bla::bimbim>, list_of_bimbim)
(my_tuple_t, mytuple)
(myvariant_t, myvariant)
)
int main(int argc, char** argv) {
using namespace swak;
bla::blabla instance{
{22, 12, bla::innerbim{"COOL"} },
23,
43,
{2.00, 39.07, 24.05},
{
{24, 9, bla::innerbim{"FEEL GOOD"} },
{26, 14, bla::innerbim{"SO BAD"} },
},
{"Hey that's not an int", 1, bla::innerbim{"hello"}, 12},
bla::innerbim("I'm in the variant")
};
std::cout << instance << std::endl;
bla::someclass otherinstance{};
std::cout << "Other instance : " << otherinstance << std::endl;
return 0;
}
Prints out the following :
{
bim :
{
boom : 22,
bam : 12,
my_inner_bim :
{
mystring : COOL,
}
}
i : 23,
j : 43,
list : [2, 39.07, 24.05],
list_of_bimbim : [
{
boom : 24,
bam : 9,
my_inner_bim :
{
mystring : FEEL GOOD,
}
}
,
{
boom : 26,
bam : 14,
my_inner_bim :
{
mystring : SO BAD,
}
}
],
mytuple :
{
0 (Ss) : Hey that's not an int,
1 (i) : 1,
2 (N3bla8innerbimE) :
{
mystring : hello,
}
3 (N5boost7variantIidN3bla8innerbimENS_6detail7variant5void_ES5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_EE) :
{
12}
}
myvariant :
{
{
mystring : I'm in the variant,
}
}
}
Other instance :
{
i : 12,
j : 15,
}
I'm improving the implementation to get it at some point as a possible new feature in boost fusion, but it's already usable as shown there :
https://github.com/daminetreg/lib-cpp-swissarmyknife/blob/feature/adapted_struct_printer_improved/test/adapted_struct_printer.cpp

It is possible but it would take a lot of work if debug symbols were enabled and all optimisations were disabled. Also it would be slow and perhaps not very reliable[*1].
Anything that a debugger can do could be replicated by a dump() function that causes a breakpoint, and logged out information.
Some debuggers can be automated, so perhaps the dump function itself would be written in the debugger.
*1 e.g. debuggers sometimes crash when dealing with some breakpoints. e.g. the program would need to have a breakpoint and halt all threads before trying to dump data. e.g. programs that need to deal with realtime interrupts probably wouldn't work. e.g. the debugger needs to be reliable enough to deal with many many breakpoints and not introduce other issues.

In microsoft article have some solution:
vector::push_back
https://msdn.microsoft.com/pt-br/library/7fthz5xd.aspx
template <typename T> void print_elem(const T& t) {
cout << "(" << t << ") ";
}
template <typename T> void print_collection(const T& t) {
cout << " " << t.size() << " elements: ";
for (const auto& p : t) {
print_elem(p);
}
cout << endl;
}
and the call for this:
cout << "vector data: " << endl;
print_collection(v);

No, you have to roll your own using one from the cout or C style printf family of output functions for user defined data structures. Similarly, for arrays, (except C-style strings) you will have to loop over all the elements and print each one.

No, there isn't. Use a debugger like ddd, for example. Most IDEs have one integrated.

I usually use GDB printing.
for example this code:
#include <string.h>
struct _example_ {
int a;
int b;
char c[20];
};
int main(){
struct _example_ example;
example.a = 1;
example.b = 2;
strcpy(example.c,"example_c");
}
compile with gcc main.c -o executable -g
if you want to know the values for the struct example, you should execute the program with GDB, put a break on the line that you want and then print the variable, like below.
Breakpoint 1, main () at main.c:12
12 strcpy(example.c,"example_c");
(gdb) n
13 }
(gdb) print example
$1 = {a = 1, b = 2, c = "example_c\000\000\000\000\000\000\000`PUU"}
(gdb)
In this case i put breakpoint on line 12, and print the variable example, then i got all the variables and values on the struct example

Related

Store output of php_execute_script

How can I store the output of php_execute_script() in a character array? php_execute_script() only prints the output.
Here's what I've got:
PHP_EMBED_START_BLOCK(argc, argv)
char string[200];
setbuf(stdout, string);
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, "say.php");
fflush(stdout);
if (php_execute_script(&file_handle) == FAILURE) {
php_printf("Failed to execute PHP script.\n");
}
setbuf(stdout, NULL);
printf("\"%s\" is what say.php has to say.\n", string);
PHP_EMBED_END_BLOCK()
I've tried redirecting stdout to string, but it doesn't even look like php_execute_script is actually writing to stdout! It just ignores it.
I'm trying to communicate with the PHP embedded script ("say.php") from C using the PHP SAPI after building PHP with embedding enabled.
Thinking that there's no such thing, I made an issue:
https://github.com/php/php-src/issues/9330
#include <sapi/embed/php_embed.h>
char *string[999] = {NULL};
int i = 0;
static size_t embed_ub_write(const char *str, size_t str_length){
string[i] = (char *) str; i++;
return str_length;
}
int main(int argc, char **argv)
{
php_embed_module.ub_write = embed_ub_write;
PHP_EMBED_START_BLOCK(argc, argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, "say.php");
if (php_execute_script(&file_handle) == FAILURE) {
php_printf("Failed to execute PHP script.\n");
}
for (i = 0; string[i] != NULL; i++) {
printf("%s", string[i]);
}
PHP_EMBED_END_BLOCK()
}
You need to set php_embed_module.ub_write to a callback function that gets called every time PHP makes an echo.
It's weird how PHP doesn't write to stdout...
EDIT: As it turns out, it does. You just need to use pipe.

Why boost::asio::async_write works well at the first time and something goes wrong for the second time?

I can successfully send out data via TCP by invoking async_write at first, whereas it goes wrong when the async_write is called again.
Here is the code snippet:
#include <algorithm>
#include <array>
#include <boost/asio.hpp>
#include <boost/range.hpp>
#include <chrono>
#include <iostream>
#include <random>
#include <vector>
const std::size_t buf_size = 500*1024;
const int test_cycles = 1.024e5;
namespace asio = boost::asio;
int main()
{
std::vector<char> send_data(buf_size);
std::vector<char> recv_buf(buf_size);
asio::io_service ios;
asio::ip::tcp::socket socket1(ios);
asio::ip::tcp::socket socket2(ios);
asio::ip::tcp::acceptor acceptor(ios, {asio::ip::tcp::v4(), 55557});
socket1.connect({asio::ip::address_v4::loopback(), 55557});
acceptor.accept(socket2);
for (std::size_t i = 0; i < 1; ++i)
{
auto start = std::chrono::steady_clock::now();
for(int j=0; j < test_cycles; ++j)
{
size_t written_bytes = 0;
auto to_send_data = send_data;
asio::async_write(socket1,
asio::dynamic_buffer(send_data),
[&](auto ec, auto n)
{
if(!ec)
{
std::cout << "successfully sent " << n << std::endl;
}
else
{
std::cout << ec.message() << std::endl;
}
if(0==n)
{
std::cout << "send error" << std::endl;
}
written_bytes = n;
});
asio::async_read(socket2, asio::buffer(recv_buf),
[&](auto ec, auto n)
{
if(!ec)
{
//std::cout << "received " << n << std::endl;
}
else
{
std::cout << ec.message() << std::endl;
}
if(0==n)
{
std::cout << "received error" << std::endl;
}
if(written_bytes != n)
{
std::cout << "received is not same with the sent" << std::endl;
}
});
ios.run();
ios.reset();
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<float> elapsed = end - start;
std::cout << elapsed.count() << " seconds\n";
std::cout << (buf_size * test_cycles / elapsed.count() / 1024 / 1024/ 1024) << " GB/s\n";
}
}
Here is the output:
successfully sent 512000
successfully sent 0
send error
Some hint
I found a workaround method and the program goes well.Here is the related code snippet:
auto to_send_data = send_data;
asio::async_write(socket1,
asio::dynamic_buffer(to_send_data),
Why the aforementioned code snippet goes wrong?
UPDATE:
I try to set the breakpoint in the implementation of STD:: vector:: resize() via VsCode IDE(I did this test on Ubuntu. ), but the breakpoint does not work indeed(i.e the breakpoint is grey.). I could guarantee that binary program is built as debug mode. I also try to set the breakpoint by GDB, but GDB outputs "Function "std::vector::resize" not defined."
I set breakpoints in the implementation of the aforementioned operator(), I found the default has never been triggered indeed, in other words, start is always 1.
Unfortunately boost documentation on dynamic_buffer is extremely laconic:
A dynamic buffer encapsulates memory storage that may be automatically resized as required.
meaning that dynamic_buffer will manipulate the underlying vector during IO operations.
Boost ASIO tutorial is more explicit:
Dynamic buffer is a concept. Dynamic buffer is a buffer that you can write data into or read from it. If the buffer isn't big enough to fit your data then it will resize (grow) dynamically. So when you write into the dynamic buffer you don't have to worry if there is enough space left in the buffer. On the other hand, when you read data from a dynamic buffer, you are responsible to throw away (consume) bytes read and no longer needed so the buffer won't grow permanently.
Write operation on dynamic buffer in boost calls consume method of dynamic_buffer that erases bytes_tranferred from it:
class write_dynbuf_v2_op
....
void operator()(const boost::system::error_code& ec,
std::size_t bytes_transferred, int start = 0)
{
switch (start)
{
case 1:
// write operation
async_write(stream_, buffers_.data(0, buffers_.size()),
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
BOOST_ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));
return;
default:
// write completed, consume transferred bytes and call handler
buffers_.consume(bytes_transferred);
handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
}
}
Hence in the original example, we would queue an async write on the vector, then queue async operation on the same vector again and again.
After the first callback finishes, transferring 512000 bytes, the second callback has an empty vector (as it was erased by dynamic_buffer) and the callback prints
Successfully sent 0
As the error code is 0 and then
Send error
As send error is printed when the number of bytes transferred is 0.
io_context.run() is stuck as it has a pending read operation.
The workaround helps as we schedule a copy of the vector for each async_write operation.
An alternative would be resizing the vector back to the original size after io_context.run()

Cannot invoke another function within a PHP_FUNCTION() in C

I need to call a function within a PHP_FUNCTION() function in C to extend PHP, this is a multithread script and The function itself works perfectly using int main(). Here is what I try to achieve.
#define NUM_THREADS 3
char *messages[NUM_THREADS];
void *PrintHello(void *threadid)
{
zend_printf("gP");
int *id_ptr, taskid;
sleep(4);
id_ptr = (int *) threadid;
taskid = *id_ptr;
zend_printf("Thread %d: %s\n", taskid, messages[taskid]);
pthread_exit(NULL);
}
PHP_FUNCTION(hello_world)
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t;
messages[0] = "English: Hello World!";
messages[1] = "French: Bonjour, le monde!";
messages[2] = "Spanish: Hola al mundo";
for(t=0; t < NUM_THREADS; t++)
{
taskids[t] = (int *) malloc(sizeof(int));
*taskids[t] = t;
zend_printf("Creating thread %d\n <br>", t);
rc = pthread_create(&threads[t], NULL, (void* (*) (void*)) pthreads_routine, (void *) taskids[t]);
if (rc) {
zend_printf("ERR; pthread_create() ret = %d\n", rc);
}
}
}
I need to call PrintHello() function from
rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]);
Do I also need to register void *PrintHello(void *threadid) in
const zend_function_entry my_functions[] = {
PHP_FE(hello_world, NULL)
PHP_FE_END
};
the var_dump() out put is
Creating thread 0
Creating thread 1
Creating thread 2
NULL
at the top of void *PrintHello(void *threadid) function I have included zend_printf("gP"); line to make sure that the function is invoked and from the looks of out put it is obvious that the function is not invoked.
My environment is Mac OSX , xCode 7.2, PHP 7.0.1
What am I doing wrong?
It appears you have two problems in your code, both of which explain why you're not getting any output.
1) At least in my tests, it appears that zend_printf -> php_printf -> vspprintf is not thread safe. Your code always crashes for me once one of the threads attempts to call zend_printf(). But, even if that weren't the case, there's also:
2) Assuming your php code looks like this:
<?php
hello_world();
What's happening is that when you call pthread_create(), it returns immediately having created the thread, though the thread has not necessarily started to run. Then, hello_world returns once all the threads have been created. Then, your main thread ends because there's nothing else to do.
Once the main thread ends, your spawned threads are immediately terminated. If you're seeing nothing at all, that's because the main thread ends before any of the pthreads are actually scheduled, before they even execute your zend_printf("gP"); line.
If you change your php code to:
<?php
hello_world();
sleep(10);
Then you give the child threads enough time to be scheduled and given CPU time (at which point they will probably crash calling the first zend_printf), and if not, give them enough time to make it past the sleep(4) to get to the zend_printf(Thread id).
If you replace your PrintHello with this:
void *PrintHello(void *threadid)
{
int *id_ptr, taskid;
id_ptr = (int *) threadid;
taskid = *id_ptr;
printf("Thread %d: start\n", taskid, messages[taskid]);
sleep(4);
printf("Thread %d: %s\n", taskid, messages[taskid]);
pthread_exit(NULL);
}
(replace the zend_printf with regular printf), then you'll get your desired output, at least on the cli.

Alternative for htmlentities($string,ENT_SUBSTITUTE)

I got a bit of a stupid question;
Currently I am making a website for a company on a server which actually has a bit an outdated PHP version (5.2.17). I have a database in which many fields are varchar with characters like 'é ä è ê' and so on, which I have to display in an HTML page.
So as the version of PHP is outdated (and I am not allowed to updated it because there are parts of the site that must keep working and to whom I have no acces to edit them) I can't use the htmlentities function with the ENT_SUBSTITUTE argument, because it was only added after version 5.4.
So my question is:
Does there exist an alternative to
htmlentities($string,ENT_SUBSTITUTE); or do I have to write a function
myself with all kinds of strange characters, which would be incomplete anyway.
Define a function for handling ill-formed byte sequences and call the function before passing the string to htmlentties. There are various way to define the function.
At first, try UConverter::transcode if you don't use Windows.
http://pecl.php.net/package/intl
If you are willing to handle bytes directly, see my previous answer.
https://stackoverflow.com/a/13695364/531320
The last option is to develop PHP extension. Thanks to php_next_utf8_char, it's not hard.
Here is code sample. The name "scrub" comes from Ruby 2.1 (see Equivalent of Iconv.conv("UTF-8//IGNORE",...) in Ruby 1.9.X?)
// header file
// PHP_FUNCTION(utf8_scrub);
#include "ext/standard/html.h"
#include "ext/standard/php_smart_str.h"
const zend_function_entry utf8_string_functions[] = {
PHP_FE(utf8_scrub, NULL)
PHP_FE_END
};
PHP_FUNCTION(utf8_scrub)
{
char *str = NULL;
int len, status;
size_t pos = 0, old_pos;
unsigned int code_point;
smart_str buf = {0};
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
return;
}
while (pos < len) {
old_pos = pos;
code_point = php_next_utf8_char((const unsigned char *) str, len, &pos, &status);
if (status == FAILURE) {
smart_str_appendl(&buf, "\xEF\xBF\xBD", 3);
} else {
smart_str_appendl(&buf, str + old_pos, pos - old_pos);
}
}
smart_str_0(&buf);
RETURN_STRINGL(buf.c, buf.len, 0);
smart_str_free(&buf);
}
You don't need ENT_SUBSTITUTE if your encoding is handled correctly.
If the characters in your database are utf-8, stored in utf-8, read in utf-8 and displayed to the user in utf-8 there should be no problem.
Just add
if (!defined('ENT_SUBSTITUTE')) define('ENT_SUBSTITUTE', 0);
and you'll be able to use ENT_SUBSTITUTE into htmlentities.

Emacs not indenting PHP correctly, although C/C++ do?

I am running GNU Emacs 22.2.1 on a HP notebook running Ubuntu 9.04 with the latest patches.
Recently, I need to handle some PHP codes, so I added Ubuntu's php-mode package, thinking what I have in my .emacs would cover the basics. Well, almost. The following short snippet shows the symptom:
<?php
# main()
/*
*
*
*/
{
$fpath="/tmp";
// This is a comment
if (!file_exists($fpath)) {
// This is another comment
print "$fpath doesn't exist on the system!\n";
exit(1);
} elseif (!is_dir($fpath)) {
print "$fpath is not a directory\n";
exit(2);
} else
// I don't know why it doesn't use the } as the anchor position
// in PHP, but in C and C++?
print "Found $fpath on the system. Good...\n";
} # end of main()
Notice that both the two comments and the print statement are offset by 6 spaces, rather than 4 as I desired. I have only a simple .emacs, with the following for C/C++, the two languages that I use most extensively:
[...]
(defconst my-c-style
'((c-comment-only-line-offset . 0)
(c-hanging-braces-alist . ((substatement-open after)
(brace-list-open)))
(c-hanging-colons-alist . ((member-init-intro before)
(inher-intro)
(case-label after)
(label after)
(access-label after)))
(c-cleanup-list . (scope-operator
empty-defun-braces
defun-close-semi))
(c-offsets-alist . ((arglist-close . c-lineup-arglist)
(substatement-open . 0)
(case-label . 4)
(block-open . 0)
(defun-block-intro . 0)
(statement-block-intro . 4)
(substatement . 4)
(knr-argdecl-intro . -)))
(c-echo-syntactic-information-p . t)
)
"My C Programming Style")
;; Customizations for all of c-mode, c++-mode, and objc-mode
(defun my-c-mode-common-hook ()
;; add my personal style and set it for the current buffer
(c-add-style "PERSONAL" my-c-style t)
;; offset customizations not in my-c-style
(c-set-offset 'defun-block-intro' +)
;; other customizations
;
(setq-default indent-tabs-mode nil)
;; make sure that comments don't get moved when you do a //
(c-set-offset 'comment-intro 0)
;; keybindings for all supported languages. We can put these in
;; c-mode-base-map because c-mode-map, c++-mode-map, objc-mode-map,
;; java-mode-map, and idl-mode-map inherit from it.
(define-key c-mode-base-map "\C-m" 'newline-and-indent)
)
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
(require 'php-mode)
[...]
What's puzzling to me is that with C or C++, emacs is able to indent my codes as desired, e.g:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
[...]
if ((cond = strcmp(word, mid->word)) < 0) {
high = mid;
low = mid - 1;
} else if (cond > 0) {
low = mid + 1;
high = mid + 2;
} else
return mid;
}
I reviewed the CC Mode manual again, but couldn't figure out what's causing emacs to behave like so. I did the typical C-c C-s and the syntatical element is "statement" in PHP as well, so why in the case of PHP, emacs uses the 'e' in else as the anchor for offset calculation, but in C/C++, it uses the closing brace '}' as it should? I would appreciate any tips and/or pointers.
Your problem is a missing { after the else. Emacs is indenting as if you were continuing the else. Add the { and it'll work fine

Categories