Browse Source

working on moving rendering to js

master
churchianity 2 years ago
parent
commit
4a0db39473
  1. 209
      base-index.html
  2. 215
      index.html
  3. 26
      main.c
  4. 99
      table.h
  5. 91
      visualization.h

209
base-index.html

@ -32,6 +32,7 @@
height: 100vh; height: 100vh;
overscroll-behavior: none; overscroll-behavior: none;
background: #F0EAD6; background: #F0EAD6;
padding-top: 10px;
direction: ltr; direction: ltr;
font: 16px HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif; font: 16px HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;
@ -119,6 +120,10 @@
width: 30px; width: 30px;
height: 45px; height: 45px;
} }
.struct-info-byte-alignment {
background-color: seagreen;
opacity: 0.4;
}
.struct-info-byte-first { .struct-info-byte-first {
border-left-width: 3px; border-left-width: 3px;
} }
@ -137,8 +142,206 @@
font-weight: bold; font-weight: bold;
color: white; color: white;
} }
dialog {
position: sticky;
top: 50vh;
left: 50vw;
transform: translate(-50%, -50%);
padding: 20px;
border: none;
border-radius: 3px;
background-color: #F0EAD6;
box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75);
max-width: 80vw;
max-height: 80vh;
}
input:not([type=checkbox]):not([type=radio]) {
display: block;
height: 2em;
}
p {
margin: 20px;
}
input[type=checkbox] {
width: 1.2rem;
height: 1.2rem;
}
label {
display: block;
}
label > input {
margin: 5px 15px 15px 15px;
}
.fix-missing-declaration-dialog-footer {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
button {
width: 10rem;
height: 2rem;
}
.help-idk {
color: darkslategray;
font-size: 0.9rem;
}
.help-idk-container {
width: 100%;
margin-bottom: 10px;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
</style> </style>
<script>
</script>
<body> <body>
<!-- c code will terminate the body and html tags -->
<dialog
id="fix-missing-declaration-dialog"
>
<p>What's the size and alignment of this type on your architecture?</p>
<div class="help-idk-container">
<p class="help-idk">
Help, I don't know!
</p>
</div>
<label>
It's a bitfield!
<input
type="checkbox"
/>
</label>
<label>
size (in bytes)
<input
type="number"
min="1"
value="8"
/>
</label>
<label>
alignment (in bytes)
<input
type="number"
value="8"
/>
</label>
<footer class="fix-missing-declaration-dialog-footer">
<button
onclick="fixMissingDeclDialog.close()"
>
Confirm
</button>
</footer>
</dialog>
<script defer>
const fixMissingDeclDialog = document.getElementById("fix-missing-declaration-dialog");
function createWithClasses(e, ...classes) {
const elem = document.createElement(e);
elem.classList.add(...classes);
return elem;
}
function alignForward(a, b) {
}
function renderStruct(structInfo, containingElement) {
const div = createWithClasses("div", "struct-info");
const structInfoHeader = createWithClasses("label", "struct-info-header");
structInfoHeader.innerText = `struct ${structInfo.name} - alias: ${structInfo.alias}`;
div.appendChild(structInfoHeader);
for (let i = 0; i < structInfo.declarations.length; i++) {
const decl = structInfo.declarations[i];
const position = i % 2 == 0;
const positionClass = position ? "struct-info-declaration-top" : "struct-info-declaration-bottom";
let bytesInStructSoFar = 0;
if (decl.size === -1) {
const byteGroup = createWithClasses("struct-info-bytegroup");
byteGroup.onclick = fixMissingDeclDialog.showMoodal();
const unknownByte = createWithClasses("div", "struct-info-byte", "struct-info-byte-unknown");
unknownByte.innerText = "?";
byteGroup.appendChild(unknownByte);
const declaration = createWithClasses("div", "struct-info-declaration", positionClass);
declaration.innerHTML = `${decl.type} <span class="struct-info-declaration-name">${decl.name}</span>`;
unknownByte.appendChild(declaration);
const ellipsisByte = createWithClasses("div", "struct-info-byte", "struct_info_byte_ellipsis");
ellipsisByte.innerText = "...";
byteGroup.appendChild(ellipsisByte);
div.appendChild(byteGroup);
} else {
// find if we need to align this field - pad some alignment bytes visually if we do.
const aligned = alignForward(bytesInStructSoFar, decl.align);
const needsAlign = aligned !== bytesInStructSoFar;
if (needsAlign) {
//sb_concatf("%s", "<div class='struct-info-bytegroup'>");
//for (int a = 0; a < (aligned - bytesInStructSoFar); a++) {
// sb_concatf("%s", "<div class='struct-info-byte struct-info-byte-alignment'></div>");
//}
//sb_concatf("%s", "</div>");
//bytesInStructSoFar += aligned - bytesInStructSoFar;
}
// now for the bytes representing the actual field.
//sb_concatf("%s", "<div class='struct-info-bytegroup'>");
//for (int b = 0; b < decl->size; b++) {
// if (b == 0) {
// sb_concatf(
// "<div class='struct-info-byte struct-info-byte-first'>"
// "<div class='struct-info-declaration %s'>"
// "%s <span class='struct-info-declaration-name'>%s</span>"
// "</div>"
// "</div>"
// , positionClass, decl->type, decl->name);
// } else {
// sb_concatf("%s", "<div class='struct-info-byte'></div>");
// }
//}
//bytesInStructSoFar += decl->size;
//sb_concatf("%s", "</div>"); // end bytegroup
}
//sb_concatf("%s", "</div></div>");
}
containingElement.appendChild(div);
}
function renderAllStructs() {
for (let i = 0; i < window.structs.length; i++) {
const structInfo = structs[i];
renderStruct(structInfo, document.body);
}
}
</script>
<!-- c code will place a script tag containing all of the data structures in JSON format, and terminate the body and html tags -->

215
index.html
File diff suppressed because it is too large
View File

26
main.c

@ -66,14 +66,21 @@
#include <inttypes.h> // strtoimax #include <inttypes.h> // strtoimax
#include <limits.h> #include <limits.h>
#include <assert.h> //assert
#include <stdio.h> // fread, fseek, ftell #include <stdio.h> // fread, fseek, ftell
#include <stdlib.h> // malloc, free #include <stdlib.h> // malloc, free
#include <stdarg.h> // va_start, va_list, va_end #include <stdarg.h> // va_start, va_list, va_end
#include <stdint.h>
#include <stdint.h> // intxx_t, etc.
#include <string.h> // memcmp #include <string.h> // memcmp
#include <stdbool.h>
#include <stdbool.h> // bool
struct Dummy {
char *p;
char c;
int x;
};
static inline void die(const char* format, ...) { static inline void die(const char* format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -140,6 +147,18 @@ static inline int strWrite(char *dest, const char *src, int maxCount) {
dest[i] = '\0'; dest[i] = '\0';
return i; return i;
} }
static ssize_t alignForward(ssize_t ptr, ssize_t align) {
ssize_t p, a, modulo;
p = ptr;
a = align;
modulo = p % a;
if (modulo != 0) {
p += a - modulo;
}
return p;
}
struct Declaration { struct Declaration {
char type[64]; char type[64];
char name[64]; char name[64];
@ -341,7 +360,8 @@ void parseStructDeclaration(struct StructInfo *structInfo, stb_lexer *lexer) {
case ']': case ']':
arrayVal = strtoimax(lastOpenBracket + 1, &lexer->where_firstchar, 10); arrayVal = strtoimax(lastOpenBracket + 1, &lexer->where_firstchar, 10);
if (arrayVal == 0) arrayVal = -1;
// happens if there is no value between, in which case it's a "name[]" decl
if (arrayVal == 0) arrayVal = -1;
break; break;
case ';': { case ';': {

99
table.h

@ -92,72 +92,41 @@ static inline Table* initTable() {
Table *table = malloc(sizeof(Table)); Table *table = malloc(sizeof(Table));
table->entries = (TableEntry**) calloc(sizeof(TableEntry*), TABLE_NUM_LANES); table->entries = (TableEntry**) calloc(sizeof(TableEntry*), TABLE_NUM_LANES);
insertPadZeroes(table, "char", sizeof(char), sizeof(char));
insertPadZeroes(table, "signed char", sizeof(signed char), sizeof(signed char));
insertPadZeroes(table, "unsigned char", sizeof(unsigned char), sizeof(unsigned char));
insertPadZeroes(table, "short", sizeof(short), sizeof(short));
insertPadZeroes(table, "short int", sizeof(short int), sizeof(short int));
insertPadZeroes(table, "signed short", sizeof(signed short), sizeof(signed short));
insertPadZeroes(table, "signed short int", sizeof(signed short int), sizeof(signed short int));
insertPadZeroes(table, "unsigned short", sizeof(unsigned short), sizeof(unsigned short));
insertPadZeroes(table, "unsigned short int", sizeof(unsigned short int), sizeof(unsigned short int));
insertPadZeroes(table, "int", sizeof(int), sizeof(int));
insertPadZeroes(table, "signed", sizeof(signed), sizeof(signed));
insertPadZeroes(table, "signed int", sizeof(signed int), sizeof(signed int));
insertPadZeroes(table, "unsigned", sizeof(unsigned), sizeof(unsigned));
insertPadZeroes(table, "unsigned int", sizeof(unsigned int), sizeof(unsigned int));
insertPadZeroes(table, "long", sizeof(long), sizeof(long));
insertPadZeroes(table, "long int", sizeof(long int), sizeof(long int));
insertPadZeroes(table, "signed long", sizeof(signed long), sizeof(signed long));
insertPadZeroes(table, "signed long int", sizeof(signed long int), sizeof(signed long int));
insertPadZeroes(table, "unsigned long", sizeof(unsigned long), sizeof(unsigned long));
insertPadZeroes(table, "unsigned long int", sizeof(unsigned long int), sizeof(unsigned long int));
insertPadZeroes(table, "long long", sizeof(long long), sizeof(long long));
insertPadZeroes(table, "long long int", sizeof(long long int), sizeof(long long int));
insertPadZeroes(table, "signed long long", sizeof(signed long long), sizeof(signed long long));
insertPadZeroes(table, "signed long long int", sizeof(signed long long int), sizeof(signed long long int));
insertPadZeroes(table, "unsigned long long", sizeof(unsigned long long), sizeof(unsigned long long));
// alignof === sizeof for primitive data types, C99 doesn't have 'alignof'
insertPadZeroes(table, "char", sizeof(char), sizeof(char));
insertPadZeroes(table, "signed char", sizeof(signed char), sizeof(signed char));
insertPadZeroes(table, "unsigned char", sizeof(unsigned char), sizeof(unsigned char));
insertPadZeroes(table, "short", sizeof(short), sizeof(short));
insertPadZeroes(table, "short int", sizeof(short int), sizeof(short int));
insertPadZeroes(table, "signed short", sizeof(signed short), sizeof(signed short));
insertPadZeroes(table, "signed short int", sizeof(signed short int), sizeof(signed short int));
insertPadZeroes(table, "unsigned short", sizeof(unsigned short), sizeof(unsigned short));
insertPadZeroes(table, "unsigned short int", sizeof(unsigned short int), sizeof(unsigned short int));
insertPadZeroes(table, "int", sizeof(int), sizeof(int));
insertPadZeroes(table, "signed", sizeof(signed), sizeof(signed));
insertPadZeroes(table, "signed int", sizeof(signed int), sizeof(signed int));
insertPadZeroes(table, "unsigned", sizeof(unsigned), sizeof(unsigned));
insertPadZeroes(table, "unsigned int", sizeof(unsigned int), sizeof(unsigned int));
insertPadZeroes(table, "long", sizeof(long), sizeof(long));
insertPadZeroes(table, "long int", sizeof(long int), sizeof(long int));
insertPadZeroes(table, "signed long", sizeof(signed long), sizeof(signed long));
insertPadZeroes(table, "signed long int", sizeof(signed long int), sizeof(signed long int));
insertPadZeroes(table, "unsigned long", sizeof(unsigned long), sizeof(unsigned long));
insertPadZeroes(table, "unsigned long int", sizeof(unsigned long int), sizeof(unsigned long int));
insertPadZeroes(table, "long long", sizeof(long long), sizeof(long long));
insertPadZeroes(table, "long long int", sizeof(long long int), sizeof(long long int));
insertPadZeroes(table, "signed long long", sizeof(signed long long), sizeof(signed long long));
insertPadZeroes(table, "signed long long int", sizeof(signed long long int), sizeof(signed long long int));
insertPadZeroes(table, "unsigned long long", sizeof(unsigned long long), sizeof(unsigned long long));
insertPadZeroes(table, "unsigned long long int", sizeof(unsigned long long int), sizeof(unsigned long long int)); insertPadZeroes(table, "unsigned long long int", sizeof(unsigned long long int), sizeof(unsigned long long int));
insertPadZeroes(table, "float", sizeof(float), sizeof(float));
insertPadZeroes(table, "double", sizeof(double), sizeof(double));
insertPadZeroes(table, "long double", sizeof(long double), sizeof(long double));
insertPadZeroes(table, "size_t", sizeof(size_t), sizeof(size_t));
insertPadZeroes(table, "ssize_t", sizeof(ssize_t), sizeof(ssize_t));
insertPadZeroes(table, "bool", sizeof(bool), sizeof(bool));
insertPadZeroes(table, "_Bool", sizeof(_Bool), sizeof(_Bool));
//char
//signed char
//unsigned char
//short
//short int
//signed short
//signed short int
//unsigned short
//unsigned short int
//int
//signed
//signed int
//unsigned
//unsigned int
//long
//long int
//signed long
//signed long int
//unsigned long
//unsigned long int
//long long
//long long int
//signed long long
//signed long long int
//unsigned long long
//unsigned long long int
//float
//double
//long double
//traversePrint(table);
insertPadZeroes(table, "float", sizeof(float), sizeof(float));
insertPadZeroes(table, "double", sizeof(double), sizeof(double));
insertPadZeroes(table, "long double", sizeof(long double), sizeof(long double));
insertPadZeroes(table, "size_t", sizeof(size_t), sizeof(size_t));
insertPadZeroes(table, "ssize_t", sizeof(ssize_t), sizeof(ssize_t));
insertPadZeroes(table, "bool", sizeof(bool), sizeof(bool));
insertPadZeroes(table, "_Bool", sizeof(_Bool), sizeof(_Bool));
return table; return table;
} }

91
visualization.h

@ -2,6 +2,7 @@
static size_t indexHtmlSize = 0; static size_t indexHtmlSize = 0;
static char* indexHtml = NULL; static char* indexHtml = NULL;
// @NOTE the assumption that we won't concat more than 1024 bytes at once.
#define sb_concatf(fmt, ...) \ #define sb_concatf(fmt, ...) \
if ((sbc - sbi) < 1024) { \ if ((sbc - sbi) < 1024) { \
sbc *= 1.5; \ sbc *= 1.5; \
@ -20,74 +21,52 @@ static void outputHtml() {
if (indexHtml == NULL) indexHtml = readWholeFile("base-index.html", &indexHtmlSize); if (indexHtml == NULL) indexHtml = readWholeFile("base-index.html", &indexHtmlSize);
int result = 0; int result = 0;
sb_concatf("%s", indexHtml);
sb_concatf("%s\n<script>\nwindow.structs = JSON.parse(`[\n", indexHtml);
for (int i = 0; i < numAllStructs; i++) { for (int i = 0; i < numAllStructs; i++) {
struct StructInfo *structInfo = allStructs + i; struct StructInfo *structInfo = allStructs + i;
printStructInfo(structInfo);
ssize_t byteCounter = 0;
sb_concatf(
"<div class='struct-info'>"
"<label class='struct-info-header'>struct %s - alias: %s</label>"
"<div class='struct-info-byte-row'>"
, structInfo->name, structInfo->alias);
for (int d = 0; d < structInfo->numDeclarations; d++) {
struct Declaration *decl = structInfo->declarations + d;
bool truncate32 = false;
if (decl->size > 32) {
truncate32 = true;
}
sb_concatf("%s", "<div class='struct-info-bytegroup'>");
bool first = (d % 2) == 0;
const char* positionClass = first ? "struct-info-declaration-top" : "struct-info-declaration-bottom";
if (decl->size == -1) {
sb_concatf(
"<div class='struct-info-byte struct-info-byte-unknown'>?"
"<div class='struct-info-declaration %s'>"
"%s <span class='struct-info-declaration-name'>%s</span>"
"</div>"
"</div>"
"<div class='struct-info-byte struct-info-byte-ellipsis'>...</div>"
, positionClass, decl->type, decl->name);
} else {
for (int b = 0; b < decl->size; b++) {
if (b == 0) {
sb_concatf(
"<div class='struct-info-byte struct-info-byte-first'>"
"<div class='struct-info-declaration %s'>"
"%s <span class='struct-info-declaration-name'>%s</span>"
"</div>"
"</div>"
, positionClass, decl->type, decl->name);
//} else if (truncate32 && b == 32) {
// sb_concatf("<div class='struct-info-byte struct-info-byte-counted-ellipsis'>...[%ld]</div>", decl->size - b);
// break;
} else {
sb_concatf("%s", "<div class='struct-info-byte'></div>");
}
}
}
sb_concatf("%s", "</div>");
sb_concatf("{"
"\"name\":\"%s\","
"\"alias\":\"%s\","
"\"filename\":\"%s\","
"\"lineNumber\":%d,"
"\"lineOffset\":%d,"
"\"size\":%ld,"
"\"declarations\":[",
structInfo->name,
structInfo->alias,
structInfo->filename,
structInfo->lineNumber,
structInfo->lineOffset,
structInfo->size
);
for (int j = 0; j < structInfo->numDeclarations; j++) {
struct Declaration *decl = structInfo->declarations + j;
sb_concatf("{"
"\"type\": \"%s\","
"\"name\": \"%s\","
"\"size\": \"%ld\","
"\"align\": \"%ld\","
"\"isBitfield\": %s}%s",
decl->type,
decl->name,
decl->size,
decl->align,
decl->isBitfield ? "true" : "false",
(j != (structInfo->numDeclarations - 1)) ? "," : "");
} }
sb_concatf("%s", "</div></div>");
}
// don't forget the closing body and html tags
sb_concatf("%s", "</body></html>");
sb_concatf("]}%s", (i != (numAllStructs - 1)) ? "," : "");
}
sb_concatf("%s", "]`);renderAllStructs();\n</script></body></html>");
// write the index.html file out to disk // write the index.html file out to disk
FILE* fp = fopen("index.html", "wb"); FILE* fp = fopen("index.html", "wb");
if (fp == NULL) { if (fp == NULL) {
die("failed to open the file index.html"); die("failed to open the file index.html");
} }
size_t writtenCount = fwrite(stringBuffer, 1, sbi, fp); size_t writtenCount = fwrite(stringBuffer, 1, sbi, fp);
fclose(fp); fclose(fp);
if (writtenCount != sbi) { if (writtenCount != sbi) {
die("wrote only partially"); die("wrote only partially");
} }

Loading…
Cancel
Save