Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

618 lines
20 KiB

  1. /*
  2. ** Copyright 1995-2095, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. */
  17. #include "glslib.h"
  18. #include <stdlib.h>
  19. #include <string.h>
  20. /******************************************************************************
  21. __GLScontext
  22. ******************************************************************************/
  23. static GLvoid* __glsGLRCbuf_alloc(__GLSglrcBuf *inoutBuf, size_t inByteCount) {
  24. GLvoid *base;
  25. if (inoutBuf->base && inoutBuf->byteCount >= inByteCount) {
  26. return inoutBuf->base;
  27. }
  28. if (base = __glsMalloc(inByteCount)) {
  29. free(inoutBuf->base);
  30. inoutBuf->base = base;
  31. inoutBuf->byteCount = inByteCount;
  32. }
  33. return base;
  34. }
  35. GLvoid* __glsContext_allocFeedbackBuf(
  36. __GLScontext *inoutContext, size_t inByteCount
  37. ) {
  38. return __glsGLRCbuf_alloc(
  39. &inoutContext->header.glrcs[inoutContext->currentGLRC].feedbackBuf,
  40. inByteCount
  41. );
  42. }
  43. GLvoid* __glsContext_allocSelectBuf(
  44. __GLScontext *inoutContext, size_t inByteCount
  45. ) {
  46. return __glsGLRCbuf_alloc(
  47. &inoutContext->header.glrcs[inoutContext->currentGLRC].selectBuf,
  48. inByteCount
  49. );
  50. }
  51. #if __GL_EXT_vertex_array
  52. GLvoid* __glsContext_allocVertexArrayBuf(
  53. __GLScontext *inoutContext, GLSopcode inOpcode, size_t inByteCount
  54. ) {
  55. __GLSglrcBuf *buf;
  56. __GLSglrc *const glrc = (
  57. inoutContext->header.glrcs + inoutContext->currentGLRC
  58. );
  59. switch (inOpcode) {
  60. case GLS_OP_glColorPointerEXT:
  61. buf = &glrc->colorBuf;
  62. break;
  63. case GLS_OP_glEdgeFlagPointerEXT:
  64. buf = &glrc->edgeFlagBuf;
  65. break;
  66. case GLS_OP_glIndexPointerEXT:
  67. buf = &glrc->indexBuf;
  68. break;
  69. case GLS_OP_glNormalPointerEXT:
  70. buf = &glrc->normalBuf;
  71. break;
  72. case GLS_OP_glTexCoordPointerEXT:
  73. buf = &glrc->texCoordBuf;
  74. break;
  75. case GLS_OP_glVertexPointerEXT:
  76. buf = &glrc->vertexBuf;
  77. break;
  78. default:
  79. return GLS_NONE;
  80. }
  81. return __glsGLRCbuf_alloc(buf, inByteCount);
  82. }
  83. #endif /* __GL_EXT_vertex_array */
  84. __GLScontext* __glsContext_create(GLuint inName) {
  85. const GLubyte *listSep;
  86. GLSopcode op;
  87. __GLScontext *const outContext = __glsCalloc(1, sizeof(__GLScontext));
  88. GLubyte *prefixPtr;
  89. __GLSlistString *readPrefix;
  90. if (!outContext) return GLS_NONE;
  91. outContext->blockType = GLS_FRAME;
  92. for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
  93. outContext->captureFlags[op] = GLS_CAPTURE_WRITE_BIT;
  94. }
  95. outContext->captureFlags[GLS_OP_glsBeginGLS] = GLS_NONE;
  96. outContext->captureFlags[GLS_OP_glsEndGLS] = GLS_NONE;
  97. outContext->captureFlags[GLS_OP_glsPad] = GLS_NONE;
  98. __glsString_init(&outContext->returnString);
  99. __glsString_init(&outContext->savedLocale);
  100. if (!__glsHeader_init(&outContext->header)) {
  101. return __glsContext_destroy(outContext);
  102. }
  103. outContext->contextStreamDict = __glsStrDict_create(1, GL_FALSE);
  104. if (!outContext->contextStreamDict) {
  105. return __glsContext_destroy(outContext);
  106. }
  107. outContext->currentGLRC = 1;
  108. outContext->defaultReadChannel = stdin;
  109. outContext->defaultWriteChannel = stdout;
  110. listSep = glsCSTR(getenv("GLS_LIST_SEPARATOR"));
  111. outContext->name = inName;
  112. outContext->pixelSetupGen = GL_TRUE;
  113. #if __GLS_PLATFORM_WIN32
  114. // DrewB
  115. outContext->captureExecOverride = GL_FALSE;
  116. #endif
  117. if (!listSep) listSep = glsCSTR(":");
  118. if (prefixPtr = glsSTR(getenv("GLS_READ_PREFIX_LIST"))) {
  119. __GLSstring prefixString;
  120. __glsString_init(&prefixString);
  121. if (!__glsString_append(&prefixString, prefixPtr)) {
  122. __glsString_final(&prefixString);
  123. return __glsContext_destroy(outContext);
  124. }
  125. prefixPtr = prefixString.head;
  126. while (
  127. prefixPtr = glsSTR(
  128. strtok((char *)prefixPtr, (const char *)listSep)
  129. )
  130. ) {
  131. readPrefix = __glsListString_create(prefixPtr);
  132. if (!readPrefix) {
  133. __glsString_final(&prefixString);
  134. return __glsContext_destroy(outContext);
  135. }
  136. __GLS_ITERLIST_APPEND(&outContext->readPrefixList, readPrefix);
  137. prefixPtr = GLS_NONE;
  138. }
  139. __glsString_final(&prefixString);
  140. }
  141. readPrefix = __glsListString_create(glsCSTR(""));
  142. if (!readPrefix) return __glsContext_destroy(outContext);
  143. __GLS_ITERLIST_APPEND(&outContext->readPrefixList, readPrefix);
  144. outContext->writePrefix = __glsListString_create(
  145. glsCSTR(getenv("GLS_WRITE_PREFIX"))
  146. );
  147. if (!outContext->writePrefix) return __glsContext_destroy(outContext);
  148. __glsContext_updateDispatchTables(outContext);
  149. return outContext;
  150. }
  151. __GLScontext* __glsContext_destroy(__GLScontext *inContext) {
  152. GLint i;
  153. if (!inContext) return GLS_NONE;
  154. __glsStrDict_destroy(inContext->contextStreamDict);
  155. __GLS_ITERLIST_CLEAR_DESTROY(
  156. &inContext->contextStreamList, __glsContextStream_destroy
  157. );
  158. __glsHeader_final(&inContext->header);
  159. __GLS_ITERLIST_CLEAR_DESTROY(
  160. &inContext->readPrefixList, __glsListString_destroy
  161. );
  162. __glsString_final(&inContext->returnString);
  163. __glsString_final(&inContext->savedLocale);
  164. for (i = 0 ; i < inContext->captureNesting ; ++i) {
  165. __glsWriter_destroy(inContext->writers[i]);
  166. }
  167. __glsListString_destroy(inContext->writePrefix);
  168. free(inContext);
  169. return GLS_NONE;
  170. }
  171. #ifndef __GLS_PLATFORM_WIN32
  172. // DrewB
  173. static void __glsNullDecodeBinFunc(GLubyte *inoutPtr) {
  174. }
  175. #else
  176. static void __glsNullDecodeBinFunc(__GLScontext *ctx, GLubyte *inoutPtr) {
  177. }
  178. #endif
  179. void __glsContext_updateDispatchDecode_bin(__GLScontext *inoutContext) {
  180. GLSopcode op;
  181. if (inoutContext->abortMode) {
  182. for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
  183. inoutContext->dispatchDecode_bin[op] = __glsNullDecodeBinFunc;
  184. }
  185. } else {
  186. for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
  187. __GLSdecodeBinFunc decode = __glsDispatchDecode_bin_default[op];
  188. if (decode) {
  189. inoutContext->dispatchDecode_bin[op] = decode;
  190. } else {
  191. inoutContext->dispatchDecode_bin[op] = (
  192. (__GLSdecodeBinFunc)inoutContext->dispatchCall[op]
  193. );
  194. }
  195. }
  196. }
  197. }
  198. void __glsContext_updateDispatchTables(__GLScontext *inoutContext) {
  199. GLSopcode op;
  200. if (inoutContext->captureNesting) {
  201. for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
  202. inoutContext->dispatchAPI[op] = (GLSfunc)__glsDispatchCapture[op];
  203. }
  204. } else {
  205. for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
  206. inoutContext->dispatchAPI[op] = __glsDispatchExec[op];
  207. }
  208. }
  209. for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
  210. const GLSfunc commandFunc = inoutContext->commandFuncs[op];
  211. if (commandFunc) {
  212. inoutContext->dispatchCall[op] = commandFunc;
  213. } else {
  214. inoutContext->dispatchCall[op] = inoutContext->dispatchAPI[op];
  215. }
  216. }
  217. __glsContext_updateDispatchDecode_bin(inoutContext);
  218. __glsUpdateDispatchTables();
  219. }
  220. /******************************************************************************
  221. __GLScontextStream
  222. ******************************************************************************/
  223. __GLScontextStream* __glsContextStream_create(const GLubyte *inName) {
  224. __GLScontextStream *const outStream = __glsCalloc(
  225. 1, sizeof(__GLScontextStream)
  226. );
  227. __GLScontextStreamBlock *block;
  228. if (!outStream) return GLS_NONE;
  229. __glsString_init(&outStream->name);
  230. if (!__glsString_append(&outStream->name, inName)) {
  231. return __glsContextStream_destroy(outStream);
  232. }
  233. block = __glsContextStream_appendBlock(outStream, __GLS_JUMP_ALLOC);
  234. if (!block) return __glsContextStream_destroy(outStream);
  235. __glsContextStreamBlock_addJump(block, GLS_NONE);
  236. return outStream;
  237. }
  238. __GLScontextStream* __glsContextStream_destroy(__GLScontextStream *inStream) {
  239. if (!inStream) return GLS_NONE;
  240. __glsString_final(&inStream->name);
  241. __GLS_LIST_CLEAR_DESTROY(
  242. &inStream->blockList, __glsContextStreamBlock_destroy
  243. );
  244. free(inStream);
  245. return GLS_NONE;
  246. }
  247. __GLScontextStreamBlock* __glsContextStream_appendBlock(
  248. __GLScontextStream *inoutStream, size_t inBufSize
  249. ) {
  250. __GLScontextStreamBlock *const outBlock = (
  251. __glsContextStreamBlock_create(inBufSize)
  252. );
  253. __GLS_LIST_APPEND(&inoutStream->blockList, outBlock);
  254. return outBlock;
  255. }
  256. #ifndef __GLS_PLATFORM_WIN32
  257. // DrewB
  258. #define __GLS_CONTEXT_STREAM_CALL_STEP \
  259. if (word = *(GLuint *)pc) { \
  260. dispatchDecode[__GLS_OP_SMALL(word)](pc + 4); \
  261. pc += __GLS_COUNT_SMALL(word) << 2; \
  262. } else if (word = __GLS_HEAD_LARGE(pc)->opLarge) { \
  263. dispatchDecode[word](pc + 12); \
  264. pc += __GLS_HEAD_LARGE(pc)->countLarge << 2; \
  265. } else { \
  266. pc = __GLS_COMMAND_JUMP(pc)->dest; \
  267. if (!pc || __GLS_CONTEXT->abortMode) break; \
  268. }
  269. #else
  270. #define __GLS_CONTEXT_STREAM_CALL_STEP \
  271. if (word = *(GLuint *)pc) { \
  272. dispatchDecode[__GLS_OP_SMALL(word)](ctx, pc + 4); \
  273. pc += __GLS_COUNT_SMALL(word) << 2; \
  274. } else if (word = __GLS_HEAD_LARGE(pc)->opLarge) { \
  275. dispatchDecode[word](ctx, pc + 12); \
  276. pc += __GLS_HEAD_LARGE(pc)->countLarge << 2; \
  277. } else { \
  278. pc = __GLS_COMMAND_JUMP(pc)->dest; \
  279. if (!pc || __GLS_CONTEXT->abortMode) break; \
  280. }
  281. #endif
  282. void __glsContextStream_call(__GLScontextStream *inoutStream) {
  283. GLboolean callSave;
  284. __GLScontext *const ctx = __GLS_CONTEXT;
  285. __GLSdecodeBinFunc *const dispatchDecode = ctx->dispatchDecode_bin;
  286. GLubyte *pc = inoutStream->blockList.head->buf;
  287. GLuint word;
  288. ++inoutStream->callCount;
  289. callSave = ctx->contextCall;
  290. ctx->contextCall = GL_TRUE;
  291. for (;;) {
  292. __GLS_CONTEXT_STREAM_CALL_STEP
  293. __GLS_CONTEXT_STREAM_CALL_STEP
  294. __GLS_CONTEXT_STREAM_CALL_STEP
  295. __GLS_CONTEXT_STREAM_CALL_STEP
  296. }
  297. ctx->contextCall = callSave;
  298. if (!--inoutStream->callCount && inoutStream->deleted) {
  299. __glsContextStream_destroy(inoutStream);
  300. }
  301. }
  302. __GLScontextStreamBlock* __glsContextStream_firstBlock(
  303. __GLScontextStream *inoutStream
  304. ) {
  305. return inoutStream->blockList.head;
  306. }
  307. size_t __glsContextStream_getByteCount(__GLScontextStream *inoutStream) {
  308. __GLScontextStreamBlockIter iter;
  309. size_t outVal = 0;
  310. __GLS_LIST_FIRST(&inoutStream->blockList, &iter);
  311. while (iter.elem) {
  312. outVal += (size_t)(iter.elem->writeTail - iter.elem->buf);
  313. if (__glsContextStreamBlock_hasJump(iter.elem)) {
  314. outVal -= sizeof(__GLSbinCommand_jump);
  315. }
  316. __GLS_LIST_NEXT(&inoutStream->blockList, &iter);
  317. }
  318. return outVal;
  319. }
  320. GLuint __glsContextStream_getCRC32(__GLScontextStream *inoutStream) {
  321. __GLScontextStreamBlockIter iter;
  322. GLuint outVal = 0xffffffff;
  323. GLubyte *ptr, *tail;
  324. __GLS_LIST_FIRST(&inoutStream->blockList, &iter);
  325. while (iter.elem) {
  326. ptr = iter.elem->buf;
  327. tail = iter.elem->writeTail;
  328. if (__glsContextStreamBlock_hasJump(iter.elem)) {
  329. tail -= sizeof(__GLSbinCommand_jump);
  330. }
  331. while (ptr < tail) __GLS_CRC32_STEP(outVal, *ptr++);
  332. __GLS_LIST_NEXT(&inoutStream->blockList, &iter);
  333. }
  334. return ~outVal;
  335. }
  336. __GLScontextStreamBlock* __glsContextStream_lastBlock(
  337. __GLScontextStream *inoutStream
  338. ) {
  339. __GLScontextStreamBlockIter iter;
  340. __GLS_LIST_LAST(&inoutStream->blockList, &iter);
  341. return iter.elem;
  342. }
  343. void __glsContextStream_truncate(
  344. __GLScontextStream *inoutStream,
  345. __GLScontextStreamBlock *inBlock,
  346. size_t inOffset
  347. ) {
  348. __GLScontextStreamBlockIter iter;
  349. inBlock->writeTail = inBlock->buf + inOffset;
  350. __glsContextStreamBlock_addJump(inBlock, GLS_NONE);
  351. if (inBlock->writeTail < inBlock->bufTail) {
  352. const size_t fillBytes = (size_t)(inBlock->writeTail - inBlock->buf);
  353. GLubyte *const buf = __glsMalloc(fillBytes);
  354. if (buf) {
  355. size_t i;
  356. for (i = 0 ; i < fillBytes ; ++i) buf[i] = inBlock->buf[i];
  357. free(inBlock->buf);
  358. inBlock->buf = buf;
  359. inBlock->bufTail = inBlock->writeTail = buf + fillBytes;
  360. iter.elem = inBlock;
  361. __GLS_LIST_PREV(&inoutStream->blockList, &iter);
  362. if (iter.elem) {
  363. __glsContextStreamBlock_removeJump(iter.elem);
  364. __glsContextStreamBlock_addJump(iter.elem, buf);
  365. }
  366. }
  367. }
  368. __GLS_LIST_LAST(&inoutStream->blockList, &iter);
  369. while (iter.elem != inBlock) {
  370. __GLScontextStreamBlock *const block = iter.elem;
  371. __GLS_LIST_PREV(&inoutStream->blockList, &iter);
  372. __GLS_LIST_REMOVE_DESTROY(
  373. &inoutStream->blockList, block, __glsContextStreamBlock_destroy
  374. );
  375. }
  376. }
  377. __GLScontextStreamBlock* __glsContextStreamBlock_create(size_t inBufSize) {
  378. __GLScontextStreamBlock *const outBlock = (
  379. __glsCalloc(1, sizeof(__GLScontextStreamBlock))
  380. );
  381. if (!outBlock) return GLS_NONE;
  382. outBlock->buf = __glsMalloc(inBufSize);
  383. if (!outBlock->buf) return __glsContextStreamBlock_destroy(outBlock);
  384. outBlock->bufTail = outBlock->buf + inBufSize;
  385. outBlock->writeTail = outBlock->buf;
  386. return outBlock;
  387. }
  388. __GLScontextStreamBlock* __glsContextStreamBlock_destroy(
  389. __GLScontextStreamBlock *inBlock
  390. ) {
  391. if (!inBlock) return GLS_NONE;
  392. free(inBlock->buf);
  393. free(inBlock);
  394. return GLS_NONE;
  395. }
  396. GLboolean __glsContextStreamBlock_addJump(
  397. __GLScontextStreamBlock *inoutBlock, GLubyte *inDest
  398. ) {
  399. __GLSbinCommand_jump *jump;
  400. const size_t wordCount = (
  401. ((size_t)(inoutBlock->writeTail - inoutBlock->buf)) >> 2
  402. );
  403. if ((wordCount & 1) && !__glsContextStreamBlock_addPad(inoutBlock)) {
  404. return GL_FALSE;
  405. }
  406. jump = (__GLSbinCommand_jump *)inoutBlock->writeTail;
  407. if (inoutBlock->writeTail + sizeof(*jump) > inoutBlock->bufTail) {
  408. return GL_FALSE;
  409. }
  410. jump->head.opSmall = GLS_NONE;
  411. jump->head.countSmall = 0;
  412. jump->head.opLarge = GLS_NONE;
  413. jump->head.countLarge = 0;
  414. jump->pad = 0;
  415. jump->dest = inDest;
  416. inoutBlock->writeTail += sizeof(*jump);
  417. return GL_TRUE;
  418. }
  419. GLboolean __glsContextStreamBlock_addPad(__GLScontextStreamBlock *inoutBlock) {
  420. __GLSbinCommand_pad *const pad = (
  421. (__GLSbinCommand_pad *)inoutBlock->writeTail
  422. );
  423. if (inoutBlock->writeTail + sizeof(*pad) > inoutBlock->bufTail) {
  424. return GL_FALSE;
  425. }
  426. pad->head.opSmall = GLS_OP_glsPad;
  427. pad->head.countSmall = 1;
  428. inoutBlock->writeTail += sizeof(*pad);
  429. return GL_TRUE;
  430. }
  431. GLboolean __glsContextStreamBlock_hasJump(__GLScontextStreamBlock *inBlock) {
  432. GLubyte *const jumpPos = (
  433. inBlock->writeTail - sizeof(__GLSbinCommand_jump)
  434. );
  435. __GLSbinCommand_jump *const jump = (__GLSbinCommand_jump *)jumpPos;
  436. return (GLboolean)(
  437. jumpPos >= inBlock->buf &&
  438. !jump->head.opSmall &&
  439. !jump->head.countSmall &&
  440. !jump->head.opLarge &&
  441. !jump->head.countLarge &&
  442. !jump->pad
  443. );
  444. }
  445. GLboolean __glsContextStreamBlock_removeJump(
  446. __GLScontextStreamBlock *inoutBlock
  447. ) {
  448. if (__glsContextStreamBlock_hasJump(inoutBlock)) {
  449. inoutBlock->writeTail -= sizeof(__GLSbinCommand_jump);
  450. return GL_TRUE;
  451. } else {
  452. return GL_FALSE;
  453. }
  454. }
  455. /******************************************************************************
  456. __GLSglrc
  457. ******************************************************************************/
  458. void __glsGLRC_final(__GLSglrc *inoutGLRC) {
  459. free(inoutGLRC->feedbackBuf.base);
  460. free(inoutGLRC->selectBuf.base);
  461. #if __GL_EXT_vertex_array
  462. free(inoutGLRC->colorBuf.base);
  463. free(inoutGLRC->edgeFlagBuf.base);
  464. free(inoutGLRC->indexBuf.base);
  465. free(inoutGLRC->normalBuf.base);
  466. free(inoutGLRC->texCoordBuf.base);
  467. free(inoutGLRC->vertexBuf.base);
  468. #endif /* __GL_EXT_vertex_array */
  469. }
  470. void __glsGLRC_init(__GLSglrc *outGLRC) {
  471. memset(outGLRC, 0, sizeof(__GLSglrc));
  472. outGLRC->layer = 1;
  473. }
  474. /******************************************************************************
  475. __GLSlayer
  476. ******************************************************************************/
  477. void __glsLayer_init(__GLSlayer *outLayer) {
  478. memset(outLayer, 0, sizeof(__GLSlayer));
  479. outLayer->displayFormat = GLS_RGBA;
  480. }
  481. /******************************************************************************
  482. __GLSheader
  483. ******************************************************************************/
  484. void __glsHeader_final(__GLSheader *inoutHeader) {
  485. while (inoutHeader->glrcCount > 0) {
  486. __glsGLRC_final(inoutHeader->glrcs + --inoutHeader->glrcCount);
  487. }
  488. free(inoutHeader->glrcs);
  489. free(inoutHeader->layers);
  490. __glsString_final(&inoutHeader->extensions);
  491. __glsString_final(&inoutHeader->author);
  492. __glsString_final(&inoutHeader->description);
  493. __glsString_final(&inoutHeader->notes);
  494. __glsString_final(&inoutHeader->title);
  495. __glsString_final(&inoutHeader->tools);
  496. __glsString_final(&inoutHeader->version);
  497. }
  498. GLboolean __glsHeader_init(__GLSheader *outHeader) {
  499. memset(outHeader, 0, sizeof(__GLSheader));
  500. outHeader->glrcs = __glsMalloc(sizeof(__GLSglrc));
  501. outHeader->layers = __glsMalloc(sizeof(__GLSlayer));
  502. if (!outHeader->glrcs || !outHeader->layers) return GL_FALSE;
  503. __glsGLRC_init(outHeader->glrcs);
  504. __glsLayer_init(outHeader->layers);
  505. outHeader->glrcCount = 1;
  506. outHeader->layerCount = 1;
  507. outHeader->tileable = GL_TRUE;
  508. __glsString_init(&outHeader->extensions);
  509. __glsString_init(&outHeader->author);
  510. __glsString_init(&outHeader->description);
  511. __glsString_init(&outHeader->notes);
  512. __glsString_init(&outHeader->title);
  513. __glsString_init(&outHeader->tools);
  514. __glsString_init(&outHeader->version);
  515. return GL_TRUE;
  516. }
  517. GLboolean __glsHeader_reset(__GLSheader *inoutHeader) {
  518. __glsHeader_final(inoutHeader);
  519. return __glsHeader_init(inoutHeader);
  520. }
  521. /******************************************************************************
  522. __GLSlistString
  523. ******************************************************************************/
  524. GLboolean __glsListString_prefix(
  525. const __GLSlistString *inString,
  526. const GLubyte *inName,
  527. __GLSstring *outPath
  528. ) {
  529. if (
  530. __glsString_assign(outPath, inString->val.head) &&
  531. __glsString_append(outPath, inName)
  532. ) {
  533. return GL_TRUE;
  534. } else {
  535. __glsString_reset(outPath);
  536. return GL_FALSE;
  537. }
  538. }
  539. __GLSlistString* __glsListString_create(const GLubyte *inVal) {
  540. __GLSlistString *const outString = __glsCalloc(1, sizeof(__GLSlistString));
  541. if (!outString) return GLS_NONE;
  542. __glsString_init(&outString->val);
  543. if (inVal && !__glsString_append(&outString->val, inVal)) {
  544. return __glsListString_destroy(outString);
  545. }
  546. return outString;
  547. }
  548. __GLSlistString* __glsListString_destroy(__GLSlistString *inString) {
  549. if (!inString) return GLS_NONE;
  550. __glsString_final(&inString->val);
  551. free(inString);
  552. return GLS_NONE;
  553. }