Structorizer.Desktop
Structorizer.Desktop copied to clipboard
On C import, neither direct struct, enum etc. definitions nor (structured) typedefs from header files are imported as type declarations
Though structured typedefs found in headers for used type names make a C source file pass the C99 parser (with bugfix #1085 integrated), they don't induce a type declaration in an includable diagram on C import. (This happens only if the typedef or struct definition occurs in the C file itself).
Example:
File version 1 (C flile with integrated type definition):
typedef struct Date {
int year;
unsigned short month;
unsigned short day;
} Date_t;
bool isValid(const Date_t aDate)
{
unsigned short days = getMonthLength(aDate.month, aDate.year);
return (days > 0 && aDate.day <= days);
}
unsigned short getMonthLength(unsigned short month, int year)
{
unsigned short days = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28;
if (isLeapYear(year)) {
days++;
}
break;
}
return days;
}
bool isLeapYear(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
results in:
File version 2 (properly decomposed in header and C file):
Date.h
#ifndef DATE_H
#define DATE_H
#include <stdbool.h>
typedef struct Date {
int year;
unsigned short month;
unsigned short day;
} Date_t;
bool isValid(const Date_t aDate);
unsigned short getMonthLength(unsigned short month, int year);
bool isLeapYear(int year);
#endif DATE_H
Date.c
#include "Date.h"
bool isValid(const Date_t aDate)
{
unsigned short days = getMonthLength(aDate.month, aDate.year);
return (days > 0 && aDate.day <= days);
}
unsigned short getMonthLength(unsigned short month, int year)
{
unsigned short days = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28;
if (isLeapYear(year)) {
days++;
}
break;
}
return days;
}
bool isLeapYear(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
results in (and causes Analyser warnings, particularly on component access):
It seems to be a sensible way to have the file preparation phase (which scans the included header files) copy the structure definitions into the C file selected for import (as the C preprocessor does for the the C parser). An even more sensible approach might be directly to derive an includable diagram from every header file, i.e. to reflect the header structure by an analogous system of Includables. This operation ought to be made optional, i.e., a language-specific preference.
On the other hand, if a declaration (e.g. variable or argument) refers to a struct name in the traditional C manner without typedef, i.e., by using the struct
prefix, then Structorizer fails to eliminate the struct
keyword in the diagram:
I wrote in https://github.com/fesch/Structorizer.Desktop/issues/1087#issuecomment-1716632402:
It seems to be a sensible way ...
It will be an important decision whether to transform all representable defined stuff from the header files or to filter them by actual usage in the C file. This is not only a question of efforts. The filtering would be more feasible (and sensible) in the approach to copy needed definitions into the source file, whereas for the direct header-to-includable approach it would be more natural not to filter. By the way, even the copy approach is likely to produce Includables - as soon as more than one function of the C file refers to a defined type. But in this case at most one, common Includable would be created.
Well, the implementation turns out to be more complex than initially assumed, at least if the existing code is not to be rewritten completely. So it will reqire a deeper insight. We will also have to care e.g. for constants, for all kind of struct, enum, and union definition, not just typedefs alone as before.