GLW View Support Functions Source Code Analysis¶
File: movian/src/ui/glw/glw_view_support.c
Purpose: Utility functions for token manipulation and management
Status: 🟢 Verified from source code analysis
Overview¶
The glw_view_support.c file provides essential utility functions for managing tokens throughout the GLW view system. These functions handle token allocation, deallocation, copying, cloning, and debugging. They form the foundation for all token manipulation operations in the lexer, preprocessor, parser, and evaluator.
Architecture¶
Token Memory Management¶
Tokens are managed through a memory pool system for efficiency:
Benefits: - Fast allocation (no malloc overhead) - Reduced memory fragmentation - Efficient reuse of token structures
Key Functions¶
Token Allocation¶
glw_view_token_alloc()¶
Source: Lines 31-34
Purpose: Allocate a new token from the memory pool
Parameters: - gr: GLW root context containing the token pool
Returns: Pointer to newly allocated token (uninitialized)
Usage: Called by lexer and other components when creating new tokens
Note: Returned token must be initialized before use
Token Deallocation¶
glw_view_token_free()¶
Source: Lines 40-127
Purpose: Free a token and its associated resources
Parameters: - gr: GLW root context - t: Token to free (must be unlinked from all lists)
Behavior: Type-specific cleanup based on t->type
Token Type Cleanup¶
Common Cleanup (all types):
Type-Specific Cleanup:
- TOKEN_FUNCTION:
-
Calls function-specific destructor if defined
-
TOKEN_PROPERTY_REF:
-
Decrements property reference count
-
TOKEN_PROPERTY_OWNER:
-
Destroys owned property
-
TOKEN_RSTRING, TOKEN_IDENTIFIER, TOKEN_UNRESOLVED_ATTRIBUTE:
-
Releases reference-counted string
-
TOKEN_PROPERTY_NAME:
-
Releases all property name components
-
TOKEN_GEM (GLW Event Map):
-
Destroys event map structure
-
TOKEN_EVENT:
-
Releases event reference
-
TOKEN_URI:
- Releases both URI and title strings
No Cleanup Required: - Numeric types (TOKEN_FLOAT, TOKEN_EM, TOKEN_INT, TOKEN_VECTOR_FLOAT) - Operators and punctuation - TOKEN_VOID, TOKEN_DIRECTORY, TOKEN_CSTRING - Expression types (TOKEN_EXPR, TOKEN_RPN, TOKEN_PURE_RPN, TOKEN_BLOCK)
Final Step:
- Returns token to memory pool for reuseToken Copying¶
glw_view_token_copy()¶
Source: Lines 134-267
Purpose: Create a shallow copy of a single token
Parameters: - gr: GLW root context - src: Source token to copy
Returns: Pointer to new token (copy of source)
Behavior: Creates new token with copied data
Common Fields Copied¶
dst->file = rstr_dup(src->file);
dst->line = src->line;
dst->type = src->type;
dst->t_propsubr = src->t_propsubr;
dst->t_flags = src->t_flags;
Type-Specific Copying¶
-
TOKEN_FLOAT, TOKEN_EM:
-
TOKEN_INT:
-
TOKEN_MOD_FLAGS:
-
TOKEN_PROPERTY_REF:
-
Increments reference count
-
TOKEN_PROPERTY_OWNER:
-
Creates cross-reference
-
TOKEN_FUNCTION:
- Copies function pointer and arguments
-
Calls constructor if defined
-
TOKEN_RESOLVED_ATTRIBUTE:
-
TOKEN_CSTRING:
-
Shallow copy (C string not owned)
-
TOKEN_RSTRING:
-
TOKEN_IDENTIFIER, TOKEN_UNRESOLVED_ATTRIBUTE:
-
TOKEN_PROPERTY_NAME:
-
TOKEN_RPN:
-
TOKEN_URI:
Important: Does not copy next or child pointers - only the token itself
Chain Operations¶
glw_view_clone_chain()¶
Source: Lines 289-304
Purpose: Deep copy of an entire token chain
Parameters: - gr: GLW root context - src: First token in source chain - lp: Optional pointer to receive last token in cloned chain
Returns: Pointer to first token in cloned chain
Behavior:
token_t *r = NULL, *d;
token_t **pp = &r;
for(; src != NULL; src = src->next) {
d = glw_view_token_copy(gr, src);
*pp = d;
pp = &d->next;
if(lp)
*lp = d;
d->child = glw_view_clone_chain(gr, src->child, NULL);
}
return r;
Process:
1. Iterates through source chain
2. Copies each token using glw_view_token_copy()
3. Links copied tokens together
4. Recursively clones child chains
5. Optionally returns pointer to last token
Use Cases: - Macro expansion (copying macro body) - Creating default argument values - Duplicating view fragments
glw_view_free_chain()¶
Source: Lines 281-284
Purpose: Free an entire token chain
Parameters: - gr: GLW root context - t: First token in chain to free
glw_view_free_chain2()¶
Source: Lines 272-279
static void
glw_view_free_chain2(glw_root_t *gr, token_t *t, int indent)
{
token_t *n;
for(; t != NULL; t = n) {
n = t->next;
if(t->child != NULL)
glw_view_free_chain2(gr, t->child, indent + 2);
glw_view_token_free(gr, t);
}
}
Purpose: Recursively free token chain (internal implementation)
Parameters: - indent: Indentation level for debugging (currently unused)
Behavior: 1. Iterates through chain 2. Recursively frees child chains 3. Frees each token 4. Handles arbitrary chain structures
Debugging Utilities¶
token2name()¶
Source: Lines 311-431
Purpose: Convert token to human-readable string representation
Parameters: - t: Token to convert
Returns: String representation (static buffer or token data)
Examples:
-
Punctuation:
-
Operators:
-
Values:
-
Complex Types:
-
Abstract Types:
Usage: Debugging, error messages, logging
glw_view_print_tree()¶
Source: Lines 438-451
void
glw_view_print_tree(token_t *f, int indent)
{
token_t *c = f;
while(c != NULL) {
TRACE(TRACE_DEBUG, "GLW",
"%*.s%s %p (%s:%d)\n", indent, "", token2name(c), c,
rstr_get(c->file), c->line);
if(c->child != NULL) {
glw_view_print_tree(c->child, indent + 4);
}
c = c->next;
}
}
Purpose: Print token tree structure for debugging
Parameters: - f: First token in chain - indent: Initial indentation level
Output Format:
<start> 0x12345678 (main.view:1)
{ 0x12345679 (main.view:2)
identifier 0x1234567a (main.view:3)
<property> name 0x1234567b (main.view:3)
= 0x1234567c (main.view:3)
"value" 0x1234567d (main.view:3)
} 0x1234567e (main.view:4)
<end> 0x1234567f (main.view:5)
Features: - Indentation shows hierarchy - Shows token type, pointer, file, and line number - Recursively prints child tokens - Useful for debugging parser and preprocessor
Error Handling¶
glw_view_seterr()¶
Source: Lines 458-474
int
glw_view_seterr(errorinfo_t *ei, token_t *b, const char *fmt, ...)
{
if(ei == NULL)
ei = alloca(sizeof(errorinfo_t));
va_list ap;
va_start(ap, fmt);
assert(b != NULL);
vsnprintf(ei->error, sizeof(ei->error), fmt, ap);
va_end(ap);
snprintf(ei->file, sizeof(ei->file), "%s", rstr_get(b->file));
ei->line = b->line;
tracelog(TRACE_NO_PROP, TRACE_ERROR, "GLW", "Error %s:%d: %s",
rstr_get(b->file), b->line, ei->error);
return -1;
}
Purpose: Set error information and log error message
Parameters: - ei: Error info structure (can be NULL) - b: Token where error occurred - fmt: Printf-style format string - ...: Format arguments
Returns: Always returns -1 (for convenient error propagation)
Behavior: 1. Allocates error info on stack if NULL 2. Formats error message 3. Extracts file and line from token 4. Logs error to trace system 5. Returns -1
Usage Pattern:
Error Info Structure:
typedef struct errorinfo {
char error[256]; // Error message
char file[256]; // Source file
int line; // Line number
} errorinfo_t;
Property Name Utilities¶
glw_propname_to_array()¶
Source: Lines 481-489
void
glw_propname_to_array(const char *pname[16], const token_t *a)
{
const token_t *t;
int i, j;
for(i = 0, t = a; t != NULL && i < 16 - 1; t = t->child)
for(j = 0; j < t->t_elements && i < 16 - 1; j++)
pname[i++] = rstr_get(t->t_pnvec[j]);
pname[i] = NULL;
}
Purpose: Convert property name token chain to string array
Parameters: - pname: Output array (must have space for 16 pointers) - a: First token in property name chain
Behavior:
1. Iterates through token chain (following child pointers)
2. Extracts property name components from each token
3. Stores pointers to strings in output array
4. NULL-terminates array
5. Maximum 15 components (16th slot is NULL)
Example:
Token Structure:
TOKEN_PROPERTY_NAME
t_pnvec[0] = "page"
t_pnvec[1] = "model"
child →
TOKEN_PROPERTY_NAME
t_pnvec[0] = "title"
Output Array:
Usage: Converting property references for property system lookups
Token Type Reference¶
Value Tokens¶
- TOKEN_FLOAT: Floating-point number (e.g.,
3.14) - TOKEN_EM: EM unit (e.g.,
2.5em) - TOKEN_INT: Integer (e.g.,
42) - TOKEN_VOID: Void/null value
- TOKEN_VECTOR_FLOAT: Float vector (e.g.,
[1.0, 2.0, 3.0]) - TOKEN_RSTRING: Reference-counted string
- TOKEN_CSTRING: C string constant
- TOKEN_IDENTIFIER: Identifier name
- TOKEN_URI: URI with title
Structural Tokens¶
- TOKEN_START: Start of token stream
- TOKEN_END: End of token stream
- TOKEN_BLOCK_OPEN:
{ - TOKEN_BLOCK_CLOSE:
} - TOKEN_LEFT_PARENTHESIS:
( - TOKEN_RIGHT_PARENTHESIS:
) - TOKEN_LEFT_BRACKET:
[ - TOKEN_RIGHT_BRACKET:
] - TOKEN_SEPARATOR:
, - TOKEN_END_OF_EXPR:
; - TOKEN_DOT:
. - TOKEN_COLON:
: - TOKEN_HASH:
#
Operator Tokens¶
- TOKEN_ASSIGNMENT:
= - TOKEN_COND_ASSIGNMENT:
?= - TOKEN_REF_ASSIGNMENT:
&= - TOKEN_DEBUG_ASSIGNMENT:
!= - TOKEN_LINK_ASSIGNMENT:
~= - TOKEN_ADD:
+ - TOKEN_SUB:
- - TOKEN_MULTIPLY:
* - TOKEN_DIVIDE:
/ - TOKEN_MODULO:
% - TOKEN_BOOLEAN_AND:
&& - TOKEN_BOOLEAN_OR:
|| - TOKEN_BOOLEAN_XOR:
^^ - TOKEN_BOOLEAN_NOT:
! - TOKEN_EQ:
== - TOKEN_NEQ:
!= - TOKEN_LT:
< - TOKEN_GT:
> - TOKEN_NULL_COALESCE:
?? - TOKEN_QUESTIONMARK:
? - TOKEN_TENARY: Ternary operator
- TOKEN_DOLLAR:
$ - TOKEN_AMPERSAND:
&
Property Tokens¶
- TOKEN_PROPERTY_REF: Property reference
- TOKEN_PROPERTY_OWNER: Owned property
- TOKEN_PROPERTY_NAME: Property name components
- TOKEN_PROPERTY_SUBSCRIPTION: Property subscription
Attribute Tokens¶
- TOKEN_RESOLVED_ATTRIBUTE: Resolved attribute name
- TOKEN_UNRESOLVED_ATTRIBUTE: Unresolved attribute name
Expression Tokens¶
- TOKEN_EXPR: Infix expression
- TOKEN_RPN: Reverse Polish Notation expression
- TOKEN_PURE_RPN: Pure RPN (no side effects)
- TOKEN_BLOCK: Code block
- TOKEN_NOP: No operation
- TOKEN_VECTOR: Vector constructor
Special Tokens¶
- TOKEN_FUNCTION: Function call
- TOKEN_GEM: GLW Event Map
- TOKEN_EVENT: Event object
- TOKEN_DIRECTORY: Directory reference
- TOKEN_MOD_FLAGS: Flag modification
Memory Management Patterns¶
Allocation Pattern¶
token_t *t = glw_view_token_alloc(gr);
t->type = TOKEN_INT;
t->t_int = 42;
t->file = rstr_dup(filename);
t->line = line_number;
t->next = NULL;
t->child = NULL;
Deallocation Pattern¶
Chain Building Pattern¶
token_t *first = NULL;
token_t **pp = &first;
for(...) {
token_t *t = glw_view_token_alloc(gr);
// Initialize t
*pp = t;
pp = &t->next;
}
*pp = NULL; // Terminate chain
Chain Cloning Pattern¶
token_t *original = ...;
token_t *copy = glw_view_clone_chain(gr, original, NULL);
// copy is independent of original
Chain Freeing Pattern¶
Performance Considerations¶
Memory Pool Benefits¶
- Fast Allocation: O(1) allocation from pool
- Reduced Fragmentation: Tokens are same size
- Cache Locality: Pool allocations are contiguous
- Efficient Reuse: Freed tokens immediately available
Reference Counting¶
- rstr_t: Reference-counted strings reduce copying
- prop_t: Reference-counted properties prevent duplication
- Shared Data: Multiple tokens can reference same string
Chain Operations¶
- Cloning: Creates deep copy (can be expensive for large chains)
- Freeing: Recursive (can cause stack issues for very deep trees)
- Copying: Single token copy is fast
Integration with View System¶
Lexer Integration¶
// Lexer creates tokens
token_t *t = glw_view_token_alloc(gr);
t->type = TOKEN_IDENTIFIER;
t->t_rstring = rstr_alloc(identifier_text);
Preprocessor Integration¶
// Preprocessor clones macro bodies
token_t *expanded = glw_view_clone_chain(gr, macro->body, NULL);
Parser Integration¶
// Parser consumes tokens
token_t *t = current;
current = current->next;
glw_view_token_free(gr, t);
Error Reporting Integration¶
// Error reporting uses token location
if(error)
return glw_view_seterr(ei, token, "Parse error: %s", msg);
Related Files¶
- glw_view.h: Token structure definitions
- glw_view_lexer.c: Token creation
- glw_view_preproc.c: Token manipulation for preprocessing
- glw_view_parser.c: Token consumption
- glw_view_eval.c: Token evaluation
See Also¶
- glw_view_lexer.c.md - Tokenization
- glw_view_preproc.c.md - Preprocessing
- glw_view_parser.c.md - Parsing
- glw_view_eval.c.md - Expression evaluation