Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pascal: Add parsing of function/proc signatures #3205

Merged

Conversation

eht16
Copy link
Contributor

@eht16 eht16 commented Nov 29, 2021

Parse the signatures and return type for functions and procedures in Pascal.

This features is ported from the Geany Pascal parser where we use this code already for many years and it might be useful for others too.

parsers/pascal.c Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Nov 29, 2021

Codecov Report

Merging #3205 (6205ac2) into master (1d9e6fe) will increase coverage by 0.10%.
The diff coverage is 97.50%.

❗ Current head 6205ac2 differs from pull request most recent head bd60584. Consider uploading reports for the commit bd60584 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3205      +/-   ##
==========================================
+ Coverage   84.84%   84.94%   +0.10%     
==========================================
  Files         205      206       +1     
  Lines       48369    49030     +661     
==========================================
+ Hits        41040    41650     +610     
- Misses       7329     7380      +51     
Impacted Files Coverage Δ
parsers/pascal.c 90.24% <97.50%> (+12.64%) ⬆️
parsers/gdscript.c 89.82% <0.00%> (ø)
main/entry.c 88.37% <0.00%> (+0.04%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1d9e6fe...bd60584. Read the comment docs.

@eht16 eht16 force-pushed the pascal_add_signature_parsing branch from 98c81b0 to 8c02ce0 Compare November 29, 2021 14:26
@masatake
Copy link
Member

If you are thinking about your hoidays:-), I would like you to see #2241, too.
I need helps from a person who knows pascal.

@eht16
Copy link
Contributor Author

eht16 commented Nov 29, 2021

If you are thinking about your hoidays:-), I would like you to see #2241, too. I need helps from a person who knows pascal.

Ha, nice try.
Actually, the "type" desclaration parsing is, apart from this PR, the only difference between the ctags and Geany Pascal parser. I was about to submit a PR for this too (not realizing #2241 is already there). But I noticed the current implementation is incomplete and buggy and so rather needs to be rewritten or removed. I personally do not know Pascal any good, learned it a bit in school but this was a few decades ago... :).
I don't want and can't spend time on implementing this properly. Sorry.

@masatake
Copy link
Member

@eht16, I see.
After merging GDScript, I will take more time for this pull request.

parsers/pascal.c Outdated
}

*end = '\0';
*arglist = strdup(start);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding:

To do *end = '\0', you have to do c = strdup(buf).
To do strdup(start), you have to do *end = '\0', terminating the C string.

I think you can reduce strdup() with eStrndup(const char* str, size_t len); declared in main/routines.h.
With it, you can make a new C string without doing *end = '\0'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint, did it and then rewrote it with your vString suggestion below :D.

parsers/pascal.c Outdated
*end = '\0';
*arglist = strdup(start);

eFree(c);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If eStrndup helps you expectedly, you can remove this eFree().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fortunately, that code vanished by using vString.

parsers/pascal.c Outdated Show resolved Hide resolved
parsers/pascal.c Outdated
@@ -74,6 +80,68 @@ static bool tail (const char *cp)
return result;
}

static void parseArglist(const char *buf, char **arglist, char **vartype)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using vString() for storing arglist and vartype is an alternative approach.

In a micro view, an operation on vString tasks higher const than using char * directly.
However, in a macro view, vString is not so bad. Using char *, you must call strdup twice in every calling parseArglist.
vString can be reused once it is new'ed in findPascalTags.
A vString can clear its internal buffer keeping char * with vStringClear.
Though, it is cleared, the buffer is not deallocated.

Writing English is hard for me. Let's show me in pseudo-code:

/* Your code using raw C string */

static void parseArglist(const char *buf, char **arglist, char **vartype)
{
  *arglist = strdup();
  *vartype = strdup();  
}

static void findPascalTags (void)
{
  char *arglist = NULL;
  char *vartype = NULL;
  // ...
  loop() {
    createPascalTag();
    // ...
    free (arglist);
    free (vartype);    
    parseArglist(, &arglist, &vartype);
  }
  free (arglist);
  free (vartype);    
  
}

/* What we can do with vString */
static void parseArglist(const char *buf, vString *arglist, vString *vartype)
{
  char c, *str;
  /* ... */
  vStringPut(arglist, c);
  /* or */ vStringCatS(arglist, str);
  /* or */ vStringNCatS(arglist, str, len);
  vStringPut(vartype, c);
  /* or */ vStringCatS(vartype, str);
  /* or */ vStringNCatS(vartype, str, len);

}

static void findPascalTags (void)
{
  vString *arglist = vStringNew();
  vString *vartype = vStringNew();
  // ...
  loop() {
    createPascalTag();
    // ...
    vStringClear (arglist);
    vStringClear (vartype);    
    parseArglist(, arglist, vartype);
  }
  vStringDelete (arglist);
  vStringDelete (vartype);    
  
}

Of course, I don't care about the performance of this level.
However, vString helps me understand the logic.

This comment is not for "must-fix". Your code is already works fine. So this is a just comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea and thanks for the detailed explanation.
I rewrote the code to use vString (back in 2009 when I wrote the code initially I wasn't so much aware of the vString helper and didn't touch the since then).

It's simpler now and we don't need any more string copying than what is done implicitly by vStringCat*().

@masatake
Copy link
Member

masatake commented Dec 1, 2021

NOTE for myself: following semi-fuzz tests are passed.

make chop LANGUAGES=Pascal
make slap LANGUAGES=Pascal
make noise LANGUAGES=Pascal

@eht16
Copy link
Contributor Author

eht16 commented Dec 2, 2021

The chop, noise and slap make targets do not output anything for me and quit pretty fast. I'm not sure if they actually did test anything.

parsers/pascal.c Outdated
parseArglist((const char*) cp, &arglist, (kind == K_FUNCTION) ? &vartype : NULL);
vStringClear (arglist);
vStringClear (vartype);
parseArglist((const char*) cp, arglist, (kind == K_FUNCTION) ? vartype : NULL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A minor issue. The line 282 and the line 283 are not aligned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 282 uses only tag characters.
However, the line 283 uses tabs and spaces mixed way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, will fix.

Another thing I noted (and probably was introduced by me in 2009), there are some inconsistencies in using a space between function name and the opening brace of the argument list. Should I fix them as well, to consistently use a space between?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I fix them as well, to consistently use a space between?

Thank you for the offering. If possible, could you fix them in ANOTHER commit?
In a commit, let's do one thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, the wrong indentation is fixed.

Did you mean another commit in this PR to fix the argument list space problem or a separate PR?
I don't mind.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't mind. However, you already submitted a good commit that aligns with the goal of this pull request.
So I will merge this.

@eht16 eht16 force-pushed the pascal_add_signature_parsing branch from 6205ac2 to bd60584 Compare December 2, 2021 11:46
@masatake masatake merged commit 7e06c76 into universal-ctags:master Dec 2, 2021
@masatake
Copy link
Member

masatake commented Dec 2, 2021

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants