Why do I find `/*{{{*/` and `/*}}}*/` around functions in C code? [duplicate] - c

I just downloaded complete source code of PHP from php.net (PHP 5.4.0 [tar.bz2]).
They are often using three curly brackets together as given below (The following code snippet extracted form ext/ctype/ctype.c.)
/* {{{ proto bool ctype_digit(mixed c)
Checks for numeric character(s) */
static PHP_FUNCTION(ctype_digit)
{
CTYPE(isdigit);
}
/* }}} */
Does anyone have the idea why they are using these three curly brackets together?

They are vim fold markers, they make it easy to collapse and expand the text inbetween the triple curly braces in vim, in the example shown alternating between:
...
/* {{{ proto bool ctype_digit(mixed c)
Checks for numeric character(s) */
static PHP_FUNCTION(ctype_digit)
{
CTYPE(isdigit);
}
/* }}} */
...
and just
...
/* {{{ proto bool ctype_digit(mixed c)
...
If you look at the end of the file where you find them, you'll often find a block like this:
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
Which is another more-obvious indicator that these comments relate to vim.

Related

What does the "in" keyword in Lua do?

I know it's usually combined with a for i,v in pairs() do loop (or ipairs, or even next) but what exactly is in?
Just to clarify, I know how to use it, I just don't know the logic behind it, how does it work/what does it return?
Lua's in is not a function or a variable. It's a part of the syntax for flow control. You can't replace it, you can't copy it, you can't even refer to it. It's rather like parentheses: a syntactic construct which has meaning for how a program is parsed, but which cannot be referred to within the program.
It doesn't "return" anything. It doesn't have "logic." It's more like a placeholder, or punctuation.
It doesn't do anything. It is syntax. It isn't a function. It isn't an opcode. It isn't a language feature. It is purely syntactical.
See the forlist function in lparser.c:
static void forlist (LexState *ls, TString *indexname) {
/* forlist -> NAME {,NAME} IN explist1 forbody */
FuncState *fs = ls->fs;
expdesc e;
int nvars = 0;
int line;
int base = fs->freereg;
/* create control variables */
new_localvarliteral(ls, "(for generator)", nvars++);
new_localvarliteral(ls, "(for state)", nvars++);
new_localvarliteral(ls, "(for control)", nvars++);
/* create declared variables */
new_localvar(ls, indexname, nvars++);
while (testnext(ls, ','))
new_localvar(ls, str_checkname(ls), nvars++);
checknext(ls, TK_IN);
line = ls->linenumber;
adjust_assign(ls, 3, explist1(ls, &e), &e);
luaK_checkstack(fs, 3); /* extra space to call generator */
forbody(ls, base, line, nvars - 3, 0);
}
Create the control variables.
Handle the local variables in the comma list.
Check that the next token is TK_IN which maps to luaX_tokens.

How i can disable maximal munch rule in Lex?

Suppose i want to deal with certain patterns and have the other text(VHDL code) as it is in the output file.
For that purpose i would be required to write a master rule in the end as
(MY_PATTERN){
// do something with my pattern
}
(.*){
return TOK_VHDL_CODE;
}
Problem with this strategy is MY_PATTERN is useless in this case and would be matched with .* by maximum munch rule.
So how can i get this functionality ?
The easy way is to get rid of the * in your default rule at the end and just use
. { append_to_buffer(*yytext); }
so your default rule takes all the stuff that isn't matched by the previous rules and stuffs it off in a buffer somehwere to be dealt with by someone else.
In theory, it's possible to find a regular expression which will match a string not containing a pattern, but except in the case of very simple patterns, it is neither easy nor legible.
If all you want to do is search for (and react to) specific patterns, you could use a default rule which matches one character and does nothing:
{Pattern1} { /* Do something with the pattern */ }
{Pattern2} { /* Do something with the pattern */ }
.|\n /* Default rule does nothing */
If, on the other hand, you wanted to do something with the not-otherwise-matched strings (as in your example), you'll need to default rule to accumulate the strings, and the pattern rules to "send" (return) the accumulated token before acting on the token which they matched. That means that some actions will need to send two tokens, which is a bit awkward with the standard parser calls scanner for a token architecture, because it requires the scanner to maintain some state.
If you have a no-too-ancient version of bison, you could use a "push parser" instead, which allows the scanner to call the parser. That makes it easy to send two tokens in a single action. Otherwise, you need to build a kind of state machine into your scanner.
Below is a simple example (which needs pattern definitions, among other things) using a push-parser.
%{
#include <stdlib.h>
#include <string.h>
#include "parser.tab.h"
/* Since the lexer calls the parser and we call the lexer,
* we pass through a parser (state) to the lexer. This is
* how you change the `yylex` prototype:
*/
#define YY_DECL static int yylex(yypstate* parser)
%}
pattern1 ...
pattern2 ...
/* Standard "avoid warnings" options */
%option noyywrap noinput nounput nodefault
%%
/* Indented code before the first pattern is inserted at the beginning
* of yylex, perfect for local variables.
*/
size_t vhdl_length = 0;
/* These are macros because they do out-of-sequence return on error. */
/* If you don't like macros, please accept my apologies for the offense. */
#define SEND_(toke, leng) do { \
size_t leng_ = leng; \
char* text = memmove(malloc(leng_ + 1), yytext, leng_); \
text[leng_] = 0; \
int status = yypush_parse(parser, toke, &text); \
if (status != YYPUSH_MORE) return status; \
} while(0);
#define SEND_TOKEN(toke) SEND_(toke, yyleng)
#define SEND_TEXT do if(vhdl_length){ \
SEND_(TEXT, vhdl_length); \
yytext += vhdl_length; yyleng -= vhdl_length; vhdl_length = 0; \
} while(0);
{pattern1} { SEND_TEXT; SEND_TOKEN(TOK_1); }
{pattern2} { SEND_TEXT; SEND_TOKEN(TOK_2); }
/* Default action just registers that we have one more char
* calls yymore() to keep accumulating the token.
*/
.|\n { ++vhdl_length; yymore(); }
/* In the push model, we're responsible for sending EOF to the parser */
<<EOF>> { SEND_TEXT; return yypush_parse(parser, 0, 0); }
%%
/* In this model, the lexer drives everything, so we provide the
* top-level interface here.
*/
int parse_vhdl(FILE* in) {
yyin = in;
/* Create a new pure push parser */
yypstate* parser = yypstate_new();
int status = yylex(parser);
yypstate_delete(parser);
return status;
}
To actually get that to work with bison, you need to provide a couple of extra options:
parser.y
%code requires {
/* requires blocks get copied into the tab.h file */
/* Don't do this if you prefer a %union declaration, of course */
#define YYSTYPE char*
}
%code {
#include <stdio.h>
void yyerror(const char* msg) { fprintf(stderr, "%s\n", msg); }
}
%define api.pure full
%define api.push-pull push

Insert and edit comments in c

Now I have a bunch of C source files with already inserted comments, which are in format /*****......*****/ for functions and /*....*/ for phrases and variables. My task is to document these files with doxygen. The problem is obvious: the comment formats are not supported by doxygen. So I have to find a way to modify the comment format of the files and also add other further comments.
I've tried with gvim with doxygen toolkit. I was only able to insert something simple like
/**
* #brief
*/
only to functions. So I'm wondering if there's a way for me to modify the already existing comments. Thank you in advance.
For Vim:
\/\*\*\*\*\*\_.\{-}\*\*\*\*\*\/
Finds
/*****
abcdef
*****/
void main()
{
int a = 0;
/**** abcdef ****/
}
/***** abcdef *****/
void function()
{
}
/*****
abcdef
abcdef
abcdef
*****/
void function2()
{
}
Which can easily be convert to a sub expression replacement VIM command:
:1,$ s/\(\/\*\*\*\*\*\)\(\_.\{-}\)\(\*\*\*\*\*\/\)/\/\*\*\2\*\//g
:)
Perhaps python/grep-awk would be a better choice here!
EDIT: Comment - Above solution is strictly based on the /***** pattern (i.e. number of '*' in /*****)

How to documenting global dependencies for functions?

I've got some C code from a 3rd party vendor (for an embedded platform) that uses global variables (for speed & space optimizations). I'm documenting the code, converting to Doxygen format.
How do I put a note in the function documentation that the function requires on global variables and functions?
Doxygen has special commands for annotating parameters and return values as describe here: Doxygen Special Commands. I did not see any commands for global variables.
Example C code:
extern unsigned char data_buffer[]; //!< Global variable.
/*! Returns the next available data byte.
* \return Next data byte.
*/
unsigned char Get_Byte(void)
{
static unsigned int index = 0;
return data_buffer[index++]; //!< Uses global variable.
}
In the above code, I would like to add Doxygen comments that the function depends on the global variable data_buffer.
You can just add a note to that effect and use the \link directive to direct the reader to the description of the global variable.
Doxygen could do with an #global command to complement #param. Until that day arrives you could approximate it with aliases.
In your Doxygen configuration file add the following aliases:
ALIASES += global_START="<dl class=\"params\"><dt>Globals</dt><dd><table class=\"params\">"
ALIASES += global_{2}="<tr><td class=\"paramname\">\1</td><td>: \2</td></tr>"
ALIASES += global_END="</table></dd></dl>"
Example of usage:
int fxnMAIN_Main(void)
{
/**
* #brief Bla Bla Bla.
*
* #global_START
* #global_{bExampleOne, Description Here}
* #global_{bExampleTwo, Second Description Here}
* #global_END
*
* #retval int : Bla Bla Bla.
*/
// Code Here
}

erasing terminal output on linux

I was writing a command line program which will have a status bar, much like wget.
The main problem I'm facing is: how do I delete what I've already sent into stdout/stderr?
I had on idea: use the backspace char '\b' and erase the output I've sent. Is that the best way? Is it the only way? Is there a better way?
PS: I don't want to use anything like ncurses. Plain old C please.
Thanks
EDIT:
Can I also go up and/or down? Example: I have 10 lines of output, I want to change the 3rd line from Doing ABC to ABC: Done. How can I do that?
Also, can anyone post more details about what VT102 characters are? What are its capabilities? Please post good links on this if you have any.
Thanks
The basic formatting control characters are backspace (\b), tab (\t), newline (\n), and carriage return (\r). If you need more than that then you can use ANSI X3.64 / ISO/IEC 6429 / ECMA-48 escape sequences; at least the VT100 subset is recognized by most modern terminals and emulators. An advantage of using ncurses is that it will look up the capabilities of your particular terminal and so it will work even if your terminal uses a different set of escape sequences.
You have to remember that as far as the regular stdio routines are concerned, stdout is just a byte stream with no inherent display characteristics; that depends on the target device, which can be anything from a regular VT100-style terminal to a hardcopy terminal to a sheet-fed printer to a plotter to whatever.
IMO, you're far better off using a library like ncurses than trying to hack together your own display management code with VT100 escape codes, even for a relatively simple task like this. I know you want to stick with "plain old C", but this is a task that falls outside the bounds of plain old C.
Use '\r' to return to the beginning of the line and possibly rewrite the whole line.
Look for VT102 control sequences - these are character sequences ESC ... to control your terminal.
There is also the possiblity of using Ncurses, which is a library for Textual UI, where this kind of behaviour should have some support. However, it may be overkill for something like this.
A slight variation on your own solution:
You can also print a carriage return (\r), which will return you to the start of the line.
It is a progressbar for bash.
function gauge()
{
progress="$1"
total="$2"
width=`tput cols`
let gwidth=width-7
if [ "$total" == "0" ]; then
percent=100
else
set +e
let percent=progress*100/total;
set -e
fi
set +e
let fillcount=percent*gwidth/100
let nofillcount=gwidth-fillcount
set -e
fill="";
if [ "$fillcount" -gt "0" ]; then
for i in `seq $fillcount`; do
fill="$fill""|"
done
fi;
nofill=""
if [ "$nofillcount" -gt "0" ]; then
for i in `seq $nofillcount`; do
nofill="$nofill"" ";
done
fi
echo -e -n "\r[""$fill""$nofill""] ""$percent""%";
}
About the progress bar: something like this?
#include <stdio.h>
#include <unistd.h>
typedef enum
{
false=0,
true=!false
} bool;
typedef struct
{
/* Start delimiter (e.g. [ )*/
char StartDelimiter;
/* End Delimiter (e.g. ] )*/
char EndDelimiter;
/* Central block (e.g. = )*/
char Block;
/* Last block (e.g. > ) */
char CurBlock;
/* Width of the progress bar (in characters) */
unsigned int Width;
/* Maximum value of the progress bar */
double Max;
/* True if we have to print also the percentage of the operation */
bool PrintPercentage;
/* True if the bar must be redrawn;
note that this must be just set to false before the first call, the function then will change it by itself. */
bool Update;
} ProgressBarSettings;
/* Prints/updates the progress bar */
void PrintProgressBar(double Pos, ProgressBarSettings * Settings);
/* Inits the settings of the progress bar to the default values */
void DefaultProgressBar(ProgressBarSettings * Settings);
int main()
{
int i;
/* Init the bar settings */
ProgressBarSettings pbs;
DefaultProgressBar(&pbs);
pbs.Max=200;
pbs.Width=60;
printf("Progress: ");
/* Show the empty bar */
PrintProgressBar(0,&pbs);
for(i=0;i<=pbs.Max;i++)
{
/* Wait 50 msec */
usleep(50000);
/* Update the progress bar */
PrintProgressBar(i,&pbs);
}
puts(" Done");
return 0;
}
/* Inits the settings of the progress bar to the default values */
void DefaultProgressBar(ProgressBarSettings * Settings)
{
Settings->StartDelimiter='[';
Settings->EndDelimiter=']';
Settings->Block='=';
Settings->CurBlock='>';
Settings->PrintPercentage=true;
Settings->Update=false;
Settings->Max=100;
Settings->Width=40;
}
/* Prints/updates the progress bar */
void PrintProgressBar(double Pos, ProgressBarSettings * Settings)
{
/* Blocks to print */
unsigned int printBlocks=(unsigned int)(Settings->Width*Pos/Settings->Max);
/* Counter */
unsigned int counter;
/* If we are updating an existing bar...*/
if(Settings->Update)
{
/* ... we get back to its first character to rewrite it... */
for(counter=Settings->Width+2+(Settings->PrintPercentage?5:0);counter;counter--)
putchar('\b');
}
else
Settings->Update=true; /* next time we'll be updating it */
/* Print the first delimiter */
putchar(Settings->StartDelimiter);
/* Reset the counter */
counter=Settings->Width;
/* Print all the blocks except the last; in the meantime, we decrement the counter, so in the end we'll have
the number of spaces to fill the bar */
for(;printBlocks>1;printBlocks--,counter--)
putchar(Settings->Block);
/* Print the last block; if the operation ended, use the normal block, otherwise the one for the last block */
putchar((Settings->Max==Pos)?Settings->Block:Settings->CurBlock);
/* Another block was printed, decrement the counter */
counter--;
/* Fill the rest of the bar with spaces */
for(;counter;counter--)
putchar(' ');
/* Print the end delimiter */
putchar(Settings->EndDelimiter);
/* If asked, print also the percentage */
if(Settings->PrintPercentage)
printf(" %3d%%",(int)(100*Pos/Settings->Max));
/* Flush the output buffer */
fflush(stdout);
};
Note: the unistd.h and usleep thing is just to fake the progress of an operation, the progress bar code itself just uses the standard library. Its only assumptions about the output stream are that \b actually gets to the previous written character. I tried it successfully on Windows and Linux (with gnome-terminal), don't know if it doesn't work correctly with some terminal emulators.
Sorry for the excessive amount of comments, I wrote it for another forum where I needed to explain pratically every line of the code to a C newbie.

Resources