| 1 | #ifdef CONFIG_WITH_COMPILER
|
|---|
| 2 | /* $Id: kmk_cc_exec.c 2767 2015-01-30 03:33:33Z bird $ */
|
|---|
| 3 | /** @file
|
|---|
| 4 | * kmk_cc - Make "Compiler".
|
|---|
| 5 | */
|
|---|
| 6 |
|
|---|
| 7 | /*
|
|---|
| 8 | * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
|
|---|
| 9 | *
|
|---|
| 10 | * This file is part of kBuild.
|
|---|
| 11 | *
|
|---|
| 12 | * kBuild is free software; you can redistribute it and/or modify
|
|---|
| 13 | * it under the terms of the GNU General Public License as published by
|
|---|
| 14 | * the Free Software Foundation; either version 3 of the License, or
|
|---|
| 15 | * (at your option) any later version.
|
|---|
| 16 | *
|
|---|
| 17 | * kBuild is distributed in the hope that it will be useful,
|
|---|
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 20 | * GNU General Public License for more details.
|
|---|
| 21 | *
|
|---|
| 22 | * You should have received a copy of the GNU General Public License
|
|---|
| 23 | * along with kBuild. If not, see <http://www.gnu.org/licenses/>
|
|---|
| 24 | *
|
|---|
| 25 | */
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 | /*******************************************************************************
|
|---|
| 29 | * Header Files *
|
|---|
| 30 | *******************************************************************************/
|
|---|
| 31 | #include "make.h"
|
|---|
| 32 |
|
|---|
| 33 | #include "dep.h"
|
|---|
| 34 | #include "variable.h"
|
|---|
| 35 | #include "rule.h"
|
|---|
| 36 | #include "debug.h"
|
|---|
| 37 | #include "hash.h"
|
|---|
| 38 | #include <ctype.h>
|
|---|
| 39 | #ifdef HAVE_STDINT_H
|
|---|
| 40 | # include <stdint.h>
|
|---|
| 41 | #endif
|
|---|
| 42 | #include <stdarg.h>
|
|---|
| 43 | #include <assert.h>
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 | /*******************************************************************************
|
|---|
| 47 | * Structures and Typedefs *
|
|---|
| 48 | *******************************************************************************/
|
|---|
| 49 | /**
|
|---|
| 50 | * Block of expand instructions.
|
|---|
| 51 | *
|
|---|
| 52 | * To avoid wasting space on "next" pointers, as well as a lot of time walking
|
|---|
| 53 | * these chains when destroying programs, we work with blocks of instructions.
|
|---|
| 54 | */
|
|---|
| 55 | typedef struct kmk_cc_exp_block
|
|---|
| 56 | {
|
|---|
| 57 | /** The pointer to the next block (LIFO). */
|
|---|
| 58 | struct kmk_cc_exp_block *pNext;
|
|---|
| 59 | /** The size of this block. */
|
|---|
| 60 | uint32_t cbBlock;
|
|---|
| 61 | } KMKCCEXPBLOCK;
|
|---|
| 62 | typedef KMKCCEXPBLOCK *PKMKCCEXPBLOCK;
|
|---|
| 63 |
|
|---|
| 64 | /** Expansion instructions. */
|
|---|
| 65 | typedef enum KMKCCEXPINSTR
|
|---|
| 66 | {
|
|---|
| 67 | /** Copy a plain string. */
|
|---|
| 68 | kKmkCcExpInstr_CopyString = 0,
|
|---|
| 69 | /** Insert an expanded variable value, which name we already know. */
|
|---|
| 70 | kKmkCcExpInstr_PlainVariable,
|
|---|
| 71 | /** Insert an expanded variable value, the name is dynamic (sub prog). */
|
|---|
| 72 | kKmkCcExpInstr_DynamicVariable,
|
|---|
| 73 | /** Insert the output of function that requires no argument expansion. */
|
|---|
| 74 | kKmkCcExpInstr_PlainFunction,
|
|---|
| 75 | /** Insert the output of function that requires dynamic expansion of one ore
|
|---|
| 76 | * more arguments. */
|
|---|
| 77 | kKmkCcExpInstr_DynamicFunction,
|
|---|
| 78 | /** Jump to a new instruction block. */
|
|---|
| 79 | kKmkCcExpInstr_Jump,
|
|---|
| 80 | /** We're done, return. Has no specific structure. */
|
|---|
| 81 | kKmkCcExpInstr_Done,
|
|---|
| 82 | /** The end of valid instructions (exclusive). */
|
|---|
| 83 | kKmkCcExpInstr_End
|
|---|
| 84 | } KMKCCEXPANDINSTR;
|
|---|
| 85 |
|
|---|
| 86 | /** Instruction core. */
|
|---|
| 87 | typedef struct kmk_cc_exp_core
|
|---|
| 88 | {
|
|---|
| 89 | /** The instruction opcode number (KMKCCEXPANDINSTR). */
|
|---|
| 90 | KMKCCEXPANDINSTR enmOpCode;
|
|---|
| 91 | } KMKCCEXPCORE;
|
|---|
| 92 | typedef KMKCCEXPCORE *PKMKCCEXPCORE;
|
|---|
| 93 |
|
|---|
| 94 | typedef struct kmk_cc_exp_subprog
|
|---|
| 95 | {
|
|---|
| 96 | /** Pointer to the first instruction. */
|
|---|
| 97 | PKMKCCEXPCORE pFirstInstr;
|
|---|
| 98 | /** Max expanded size. */
|
|---|
| 99 | uint32_t cbMax;
|
|---|
| 100 | } KMKCCEXPSUBPROG;
|
|---|
| 101 | typedef KMKCCEXPSUBPROG *PKMKCCEXPSUBPROG;
|
|---|
| 102 |
|
|---|
| 103 | typedef struct kmk_cc_exp_copy_string
|
|---|
| 104 | {
|
|---|
| 105 | /** The core instruction. */
|
|---|
| 106 | KMKCCEXPCORE Core;
|
|---|
| 107 | /** The number of bytes to copy. */
|
|---|
| 108 | uint32_t cchCopy;
|
|---|
| 109 | /** Pointer to the source string (not terminated at cchCopy). */
|
|---|
| 110 | const char *pachSrc;
|
|---|
| 111 | } KMKCCEXPCOPYSTRING;
|
|---|
| 112 | typedef KMKCCEXPCOPYSTRING *PKMKCCEXPCOPYSTRING;
|
|---|
| 113 |
|
|---|
| 114 | typedef struct kmk_cc_exp_plain_variable
|
|---|
| 115 | {
|
|---|
| 116 | /** The core instruction. */
|
|---|
| 117 | KMKCCEXPCORE Core;
|
|---|
| 118 | /** The variable strcache entry for this variable. */
|
|---|
| 119 | struct strcache2_entry *pNameEntry;
|
|---|
| 120 | } KMKCCEXPPLAINVAR;
|
|---|
| 121 | typedef KMKCCEXPPLAINVAR *PKMKCCEXPPLAINVAR;
|
|---|
| 122 |
|
|---|
| 123 | typedef struct kmk_cc_exp_dynamic_variable
|
|---|
| 124 | {
|
|---|
| 125 | /** The core instruction. */
|
|---|
| 126 | KMKCCEXPCORE Core;
|
|---|
| 127 | /** Where to continue after this instruction. This is necessary since the
|
|---|
| 128 | * subprogram is allocated after us in the instruction block. Since the sub
|
|---|
| 129 | * program is of variable size, we don't even know if we're still in the same
|
|---|
| 130 | * instruction block. So, we include a jump here. */
|
|---|
| 131 | PKMKCCEXPCORE pNext;
|
|---|
| 132 | /** The subprogram that will give us the variable name. */
|
|---|
| 133 | KMKCCEXPSUBPROG SubProg;
|
|---|
| 134 | } KMKCCEXPDYNVAR;
|
|---|
| 135 | typedef KMKCCEXPDYNVAR *PKMKCCEXPDYNVAR;
|
|---|
| 136 |
|
|---|
| 137 | typedef struct kmk_cc_exp_function_core
|
|---|
| 138 | {
|
|---|
| 139 | /** The core instruction. */
|
|---|
| 140 | KMKCCEXPCORE Core;
|
|---|
| 141 | /** Number of arguments. */
|
|---|
| 142 | uint8_t cArgs;
|
|---|
| 143 | /** Where to continue after this instruction. This is necessary since the
|
|---|
| 144 | * instruction is of variable size and we don't even know if we're still in the
|
|---|
| 145 | * same instruction block. So, we include a jump here. */
|
|---|
| 146 | PKMKCCEXPCORE pNext;
|
|---|
| 147 | /**
|
|---|
| 148 | * Pointer to the function table entry.
|
|---|
| 149 | *
|
|---|
| 150 | * @returns New variable buffer position.
|
|---|
| 151 | * @param pchDst Current variable buffer position.
|
|---|
| 152 | * @param papszArgs Pointer to a NULL terminated array of argument strings.
|
|---|
| 153 | * @param pszFuncName The name of the function being called.
|
|---|
| 154 | */
|
|---|
| 155 | char * (*pfnFunction)(char *pchDst, char **papszArgs, const char *pszFuncName);
|
|---|
| 156 | /** Pointer to the function name in the variable string cache. */
|
|---|
| 157 | const char *pszFuncName;
|
|---|
| 158 | } KMKCCEXPFUNCCORE;
|
|---|
| 159 | typedef KMKCCEXPFUNCCORE *PKMKCCEXPFUNCCORE;
|
|---|
| 160 |
|
|---|
| 161 | typedef struct kmk_cc_exp_plain_function
|
|---|
| 162 | {
|
|---|
| 163 | /** The bits comment to both plain and dynamic functions. */
|
|---|
| 164 | KMKCCEXPFUNCCORE Core;
|
|---|
| 165 | /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
|
|---|
| 166 | * The string pointers are to memory following this instruction, to memory in
|
|---|
| 167 | * the next block or to memory in the variable / makefile we're working on
|
|---|
| 168 | * (if zero terminated appropriately). */
|
|---|
| 169 | const char *apszArgs[1];
|
|---|
| 170 | } KMKCCEXPPLAINFUNC;
|
|---|
| 171 | typedef KMKCCEXPPLAINFUNC *PKMKCCEXPPLAINFUNC;
|
|---|
| 172 |
|
|---|
| 173 | typedef struct kmk_cc_exp_dyn_function
|
|---|
| 174 | {
|
|---|
| 175 | /** The bits comment to both plain and dynamic functions. */
|
|---|
| 176 | KMKCCEXPFUNCCORE Core;
|
|---|
| 177 | /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
|
|---|
| 178 | * The string pointers are to memory following this instruction, to memory in
|
|---|
| 179 | * the next block or to memory in the variable / makefile we're working on
|
|---|
| 180 | * (if zero terminated appropriately). */
|
|---|
| 181 | struct
|
|---|
| 182 | {
|
|---|
| 183 | /** Set if plain string argument, clear if sub program. */
|
|---|
| 184 | uint8_t fPlain;
|
|---|
| 185 | union
|
|---|
| 186 | {
|
|---|
| 187 | /** Sub program for expanding this argument. */
|
|---|
| 188 | KMKCCEXPSUBPROG SubProg;
|
|---|
| 189 | struct
|
|---|
| 190 | {
|
|---|
| 191 | /** Pointer to the plain argument string.
|
|---|
| 192 | * This is allocated in the same manner as the
|
|---|
| 193 | * string pointed to by KMKCCEXPPLAINFUNC::apszArgs. */
|
|---|
| 194 | const char *pszArg;
|
|---|
| 195 | } Plain;
|
|---|
| 196 | } u;
|
|---|
| 197 | } aArgs[1];
|
|---|
| 198 | } KMKCCEXPDYNFUNC;
|
|---|
| 199 | typedef KMKCCEXPDYNFUNC *PKMKCCEXPDYNFUNC;
|
|---|
| 200 |
|
|---|
| 201 | typedef struct kmk_cc_exp_jump
|
|---|
| 202 | {
|
|---|
| 203 | /** The core instruction. */
|
|---|
| 204 | KMKCCEXPCORE Core;
|
|---|
| 205 | /** Where to jump to (new instruction block, typically). */
|
|---|
| 206 | PKMKCCEXPCORE pNext;
|
|---|
| 207 | } KMKCCEXPJUMP;
|
|---|
| 208 | typedef KMKCCEXPJUMP *PKMKCCEXPJUMP;
|
|---|
| 209 |
|
|---|
| 210 | /**
|
|---|
| 211 | * String expansion program.
|
|---|
| 212 | */
|
|---|
| 213 | typedef struct kmk_cc_expandprog
|
|---|
| 214 | {
|
|---|
| 215 | /** Pointer to the first instruction for this program. */
|
|---|
| 216 | PKMKCCEXPCORE pFirstInstr;
|
|---|
| 217 | /** List of blocks for this program (LIFO). */
|
|---|
| 218 | PKMKCCEXPBLOCK pBlockTail;
|
|---|
| 219 | /** Max expanded size. */
|
|---|
| 220 | uint32_t cbMax;
|
|---|
| 221 | } KMKCCEXPANDPROG;
|
|---|
| 222 | /** Pointer to a string expansion program. */
|
|---|
| 223 | typedef KMKCCEXPANDPROG *PKMKCCEXPANDPROG;
|
|---|
| 224 |
|
|---|
| 225 |
|
|---|
| 226 | /*******************************************************************************
|
|---|
| 227 | * Global Variables *
|
|---|
| 228 | *******************************************************************************/
|
|---|
| 229 |
|
|---|
| 230 |
|
|---|
| 231 | /**
|
|---|
| 232 | * Initializes global variables for the 'compiler'.
|
|---|
| 233 | */
|
|---|
| 234 | void kmk_cc_init(void)
|
|---|
| 235 | {
|
|---|
| 236 | }
|
|---|
| 237 |
|
|---|
| 238 |
|
|---|
| 239 | /**
|
|---|
| 240 | * Compiles a variable direct evaluation as is, setting v->evalprog on success.
|
|---|
| 241 | *
|
|---|
| 242 | * @returns Pointer to the program on success, NULL if no program was created.
|
|---|
| 243 | * @param pVar Pointer to the variable.
|
|---|
| 244 | */
|
|---|
| 245 | struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar)
|
|---|
| 246 | {
|
|---|
| 247 | return NULL;
|
|---|
| 248 | }
|
|---|
| 249 |
|
|---|
| 250 |
|
|---|
| 251 | /**
|
|---|
| 252 | * Compiles a variable for string expansion.
|
|---|
| 253 | *
|
|---|
| 254 | * @returns Pointer to the string expansion program on success, NULL if no
|
|---|
| 255 | * program was created.
|
|---|
| 256 | * @param pVar Pointer to the variable.
|
|---|
| 257 | */
|
|---|
| 258 | struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar)
|
|---|
| 259 | {
|
|---|
| 260 | assert(!pVar->evalprog);
|
|---|
| 261 |
|
|---|
| 262 | //memchr()
|
|---|
| 263 |
|
|---|
| 264 |
|
|---|
| 265 |
|
|---|
| 266 |
|
|---|
| 267 | return NULL;
|
|---|
| 268 | }
|
|---|
| 269 |
|
|---|
| 270 |
|
|---|
| 271 | /**
|
|---|
| 272 | * Equivalent of eval_buffer, only it's using the evalprog of the variable.
|
|---|
| 273 | *
|
|---|
| 274 | * @param pVar Pointer to the variable. Must have a program.
|
|---|
| 275 | */
|
|---|
| 276 | void kmk_exec_evalval(struct variable *pVar)
|
|---|
| 277 | {
|
|---|
| 278 | assert(pVar->evalprog);
|
|---|
| 279 | assert(0);
|
|---|
| 280 | }
|
|---|
| 281 |
|
|---|
| 282 |
|
|---|
| 283 | /**
|
|---|
| 284 | * Expands a variable into a variable buffer using its expandprog.
|
|---|
| 285 | *
|
|---|
| 286 | * @returns The new variable buffer position.
|
|---|
| 287 | * @param pVar Pointer to the variable. Must have a program.
|
|---|
| 288 | * @param pchDst Pointer to the current variable buffer position.
|
|---|
| 289 | */
|
|---|
| 290 | char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst)
|
|---|
| 291 | {
|
|---|
| 292 | assert(pVar->expandprog);
|
|---|
| 293 | assert(0);
|
|---|
| 294 | return pchDst;
|
|---|
| 295 | }
|
|---|
| 296 |
|
|---|
| 297 |
|
|---|
| 298 | /**
|
|---|
| 299 | * Called when a variable with expandprog or/and evalprog changes.
|
|---|
| 300 | *
|
|---|
| 301 | * @param pVar Pointer to the variable.
|
|---|
| 302 | */
|
|---|
| 303 | void kmk_cc_variable_changed(struct variable *pVar)
|
|---|
| 304 | {
|
|---|
| 305 | assert(pVar->evalprog || pVar->expandprog);
|
|---|
| 306 | }
|
|---|
| 307 |
|
|---|
| 308 |
|
|---|
| 309 | /**
|
|---|
| 310 | * Called when a variable with expandprog or/and evalprog is deleted.
|
|---|
| 311 | *
|
|---|
| 312 | * @param pVar Pointer to the variable.
|
|---|
| 313 | */
|
|---|
| 314 | void kmk_cc_variable_deleted(struct variable *pVar)
|
|---|
| 315 | {
|
|---|
| 316 | assert(pVar->evalprog || pVar->expandprog);
|
|---|
| 317 | }
|
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 | #endif /* CONFIG_WITH_COMPILER */
|
|---|
| 321 |
|
|---|