1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
38 symbol *interrupts[256];
40 void printIval (symbol *, sym_link *, initList *, FILE *);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Varibles that are declared as extern */
44 /* TODO: this should be configurable (DS803C90 uses more than 6) */
45 unsigned maxInterrupts = 6;
48 set *pipeSet = NULL; /* set of pipes */
49 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
50 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
52 /*-----------------------------------------------------------------*/
53 /* closePipes - closes all pipes created by the compiler */
54 /*-----------------------------------------------------------------*/
55 DEFSETFUNC (closePipes)
68 /*-----------------------------------------------------------------*/
69 /* closeTmpFiles - closes all tmp files created by the compiler */
70 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
71 /*-----------------------------------------------------------------*/
72 DEFSETFUNC (closeTmpFiles)
85 /*-----------------------------------------------------------------*/
86 /* rmTmpFiles - unlinks all tmp files created by the compiler */
87 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
88 /*-----------------------------------------------------------------*/
89 DEFSETFUNC (rmTmpFiles)
103 /*-----------------------------------------------------------------*/
104 /* rm_tmpfiles - close and remove temporary files and delete sets */
105 /*-----------------------------------------------------------------*/
109 /* close temporary files */
110 applyToSet (pipeSet, closePipes);
111 /* close temporary files */
112 deleteSet (&pipeSet);
114 applyToSet (tmpfileSet, closeTmpFiles);
115 /* remove temporary files */
116 applyToSet (tmpfileNameSet, rmTmpFiles);
117 /* delete temorary file sets */
118 deleteSet (&tmpfileSet);
119 deleteSet (&tmpfileNameSet);
122 /*-----------------------------------------------------------------*/
123 /* copyFile - copies source file to destination file */
124 /*-----------------------------------------------------------------*/
126 copyFile (FILE * dest, FILE * src)
132 if ((ch = fgetc (src)) != EOF)
137 aopLiteralLong (value * val, int offset, int size)
146 // assuming we have been warned before
150 /* if it is a float then it gets tricky */
151 /* otherwise it is fairly simple */
152 if (!IS_FLOAT (val->type)) {
153 unsigned long v = (unsigned long) floatFromVal (val);
158 tsprintf (buffer, sizeof(buffer),
159 "!immedbyte", (unsigned int) v & 0xff);
162 tsprintf (buffer, sizeof(buffer),
163 "!immedword", (unsigned int) v & 0xffff);
166 /* Hmm. Too big for now. */
169 return Safe_strdup (buffer);
172 /* PENDING: For now size must be 1 */
175 /* it is type float */
176 fl.f = (float) floatFromVal (val);
177 #ifdef WORDS_BIGENDIAN
178 tsprintf (buffer, sizeof(buffer),
179 "!immedbyte", fl.c[3 - offset]);
181 tsprintf (buffer, sizeof(buffer),
182 "!immedbyte", fl.c[offset]);
184 return Safe_strdup (buffer);
187 /*-----------------------------------------------------------------*/
188 /* aopLiteral - string from a literal value */
189 /*-----------------------------------------------------------------*/
191 aopLiteral (value * val, int offset)
193 return aopLiteralLong (val, offset, 1);
196 /*-----------------------------------------------------------------*/
197 /* emitRegularMap - emit code for maps with no special cases */
198 /*-----------------------------------------------------------------*/
200 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
210 /* PENDING: special case here - should remove */
211 if (!strcmp (map->sname, CODE_NAME))
212 tfprintf (map->oFile, "\t!areacode\n", map->sname);
213 else if (!strcmp (map->sname, DATA_NAME))
214 tfprintf (map->oFile, "\t!areadata\n", map->sname);
215 else if (!strcmp (map->sname, HOME_NAME))
216 tfprintf (map->oFile, "\t!areahome\n", map->sname);
218 tfprintf (map->oFile, "\t!area\n", map->sname);
221 for (sym = setFirstItem (map->syms); sym;
222 sym = setNextItem (map->syms))
226 /* if extern then add it into the extern list */
227 if (IS_EXTERN (sym->etype))
229 addSetHead (&externs, sym);
233 /* if allocation required check is needed
234 then check if the symbol really requires
235 allocation only for local variables */
237 if (arFlag && !IS_AGGREGATE (sym->type) &&
238 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
239 !sym->allocreq && sym->level)
242 /* for bitvar locals and parameters */
243 if (!arFlag && !sym->allocreq && sym->level
244 && !SPEC_ABSA (sym->etype)) {
248 /* if global variable & not static or extern
249 and addPublics allowed then add it to the public set */
250 if ((sym->level == 0 ||
251 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
253 !IS_STATIC (sym->etype) &&
254 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
256 addSetHead (&publics, sym);
259 /* if extern then do nothing or is a function
261 if (IS_FUNC (sym->type))
264 /* print extra debug info if required */
267 if (!sym->level) /* global */
269 if (IS_STATIC (sym->etype))
270 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
272 fprintf (map->oFile, "G$"); /* scope is global */
276 /* symbol is local */
277 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
279 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
282 /* if it has an initial value then do it only if
283 it is a global variable */
284 if (sym->ival && sym->level == 0) {
285 if (SPEC_OCLS(sym->etype)==xidata) {
286 // create a new "XINIT (CODE)" symbol, that will be emitted later
287 newSym=copySymbol (sym);
288 SPEC_OCLS(newSym->etype)=xinit;
289 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
290 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
291 SPEC_CONST(newSym->etype)=1;
292 SPEC_STAT(newSym->etype)=1;
293 resolveIvalSym(newSym->ival);
295 // add it to the "XINIT (CODE)" segment
296 addSet(&xinit->syms, newSym);
299 if (IS_AGGREGATE (sym->type)) {
300 ival = initAggregates (sym, sym->ival, NULL);
302 if (getNelements(sym->type, sym->ival)>1) {
303 werror (W_EXCESS_INITIALIZERS, "scalar",
304 sym->name, sym->lineDef);
306 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
307 decorateType (resolveSymbols (list2expr (sym->ival))));
309 codeOutFile = statsg->oFile;
312 // set ival's lineno to where the symbol was defined
313 setAstLineno (ival, lineno=sym->lineDef);
314 // check if this is not a constant expression
315 if (!constExprTree(ival)) {
316 werror (E_CONST_EXPECTED, "found expression");
317 // but try to do it anyway
320 eBBlockFromiCode (iCodeFromAst (ival));
327 /* if is has an absolute address then generate
328 an equate for this no need to allocate space */
329 if (SPEC_ABSA (sym->etype))
333 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
335 if (TARGET_IS_XA51) {
338 } else if (map==bit || map==sfrbit) {
342 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
344 SPEC_ADDR (sym->etype));
347 int size = getSize (sym->type);
349 werror(E_UNKNOWN_SIZE,sym->name);
353 fprintf (map->oFile, "==.\n");
355 if (IS_STATIC (sym->etype))
356 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
358 tfprintf (map->oFile, "!labeldef\n", sym->rname);
359 tfprintf (map->oFile, "\t!ds\n",
360 (unsigned int) size & 0xffff);
365 /*-----------------------------------------------------------------*/
366 /* initPointer - pointer initialization code massaging */
367 /*-----------------------------------------------------------------*/
369 initPointer (initList * ilist, sym_link *toType)
372 ast *expr = list2expr (ilist);
377 /* try it the oldway first */
378 if ((val = constExprValue (expr, FALSE)))
381 /* ( ptr + constant ) */
382 if (IS_AST_OP (expr) &&
383 (expr->opval.op == '+' || expr->opval.op == '-') &&
384 IS_AST_SYM_VALUE (expr->left) &&
385 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
386 compareType(toType, expr->left->ftype) &&
387 IS_AST_LIT_VALUE (expr->right)) {
388 return valForCastAggr (expr->left, expr->left->ftype,
394 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
395 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
396 if (compareType(toType, expr->left->ftype)!=1) {
397 werror (W_INIT_WRONG);
398 printFromToType(expr->left->ftype, toType);
404 /* no then we have to do these cludgy checks */
405 /* pointers can be initialized with address of
406 a variable or address of an array element */
407 if (IS_AST_OP (expr) && expr->opval.op == '&') {
408 /* address of symbol */
409 if (IS_AST_SYM_VALUE (expr->left)) {
410 val = copyValue (AST_VALUE (expr->left));
411 val->type = newLink (DECLARATOR);
412 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
413 DCL_TYPE (val->type) = CPOINTER;
414 DCL_PTR_CONST (val->type) = port->mem.code_ro;
416 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
417 DCL_TYPE (val->type) = FPOINTER;
418 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
419 DCL_TYPE (val->type) = PPOINTER;
420 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
421 DCL_TYPE (val->type) = IPOINTER;
422 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
423 DCL_TYPE (val->type) = EEPPOINTER;
425 DCL_TYPE (val->type) = POINTER;
426 val->type->next = expr->left->ftype;
427 val->etype = getSpec (val->type);
431 /* if address of indexed array */
432 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
433 return valForArray (expr->left);
435 /* if address of structure element then
437 if (IS_AST_OP (expr->left) &&
438 expr->left->opval.op == '.') {
439 return valForStructElem (expr->left->left,
444 (&some_struct)->element */
445 if (IS_AST_OP (expr->left) &&
446 expr->left->opval.op == PTR_OP &&
447 IS_ADDRESS_OF_OP (expr->left->left)) {
448 return valForStructElem (expr->left->left->left,
452 /* case 3. (((char *) &a) +/- constant) */
453 if (IS_AST_OP (expr) &&
454 (expr->opval.op == '+' || expr->opval.op == '-') &&
455 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
456 IS_AST_OP (expr->left->right) &&
457 expr->left->right->opval.op == '&' &&
458 IS_AST_LIT_VALUE (expr->right)) {
460 return valForCastAggr (expr->left->right->left,
461 expr->left->left->opval.lnk,
462 expr->right, expr->opval.op);
465 /* case 4. (char *)(array type) */
466 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
467 IS_ARRAY(expr->right->ftype)) {
469 val = copyValue (AST_VALUE (expr->right));
470 val->type = newLink (DECLARATOR);
471 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
472 DCL_TYPE (val->type) = CPOINTER;
473 DCL_PTR_CONST (val->type) = port->mem.code_ro;
475 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
476 DCL_TYPE (val->type) = FPOINTER;
477 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
478 DCL_TYPE (val->type) = PPOINTER;
479 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
480 DCL_TYPE (val->type) = IPOINTER;
481 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
482 DCL_TYPE (val->type) = EEPPOINTER;
484 DCL_TYPE (val->type) = POINTER;
485 val->type->next = expr->right->ftype->next;
486 val->etype = getSpec (val->type);
490 werror (E_INCOMPAT_PTYPES);
495 /*-----------------------------------------------------------------*/
496 /* printChar - formats and prints a characater string with DB */
497 /*-----------------------------------------------------------------*/
499 printChar (FILE * ofile, char *s, int plen)
502 int len = strlen (s);
507 while (len && pplen < plen)
510 while (i && *s && pplen < plen)
512 if (*s < ' ' || *s == '\"' || *s=='\\')
516 tfprintf (ofile, "\t!ascii\n", buf);
517 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
532 tfprintf (ofile, "\t!ascii\n", buf);
541 tfprintf (ofile, "\t!db !constbyte\n", 0);
544 /*-----------------------------------------------------------------*/
545 /* return the generic pointer high byte for a given pointer type. */
546 /*-----------------------------------------------------------------*/
548 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
556 werror (E_CANNOT_USE_GENERIC_POINTER,
557 iname ? iname : "<null>",
558 oname ? oname : "<null>");
565 return GPTYPE_XSTACK;
567 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
575 /*-----------------------------------------------------------------*/
576 /* printPointerType - generates ival for pointer type */
577 /*-----------------------------------------------------------------*/
579 _printPointerType (FILE * oFile, const char *name)
581 if (options.model == MODEL_FLAT24)
583 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
587 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
591 /*-----------------------------------------------------------------*/
592 /* printPointerType - generates ival for pointer type */
593 /*-----------------------------------------------------------------*/
595 printPointerType (FILE * oFile, const char *name)
597 _printPointerType (oFile, name);
598 fprintf (oFile, "\n");
601 /*-----------------------------------------------------------------*/
602 /* printGPointerType - generates ival for generic pointer type */
603 /*-----------------------------------------------------------------*/
605 printGPointerType (FILE * oFile, const char *iname, const char *oname,
606 const unsigned int type)
608 _printPointerType (oFile, iname);
609 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
612 /*-----------------------------------------------------------------*/
613 /* printIvalType - generates ival for int/char */
614 /*-----------------------------------------------------------------*/
616 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
620 /* if initList is deep */
621 if (ilist->type == INIT_DEEP)
622 ilist = ilist->init.deep;
624 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
625 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
628 if (!(val = list2val (ilist))) {
629 // assuming a warning has been thrown
633 if (val->type != type) {
634 val = valCastLiteral(type, floatFromVal(val));
637 switch (getSize (type)) {
640 tfprintf (oFile, "\t!db !constbyte\n", 0);
642 tfprintf (oFile, "\t!dbs\n",
643 aopLiteral (val, 0));
647 if (port->use_dw_for_init)
648 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
650 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
654 tfprintf (oFile, "\t!dw !constword\n", 0);
655 tfprintf (oFile, "\t!dw !constword\n", 0);
658 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
659 aopLiteral (val, 0), aopLiteral (val, 1),
660 aopLiteral (val, 2), aopLiteral (val, 3));
666 /*-----------------------------------------------------------------*/
667 /* printIvalBitFields - generate initializer for bitfields */
668 /*-----------------------------------------------------------------*/
669 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
673 initList *lilist = *ilist ;
674 unsigned long ival = 0;
680 val = list2val(lilist);
682 if (SPEC_BLEN(lsym->etype) > 8) {
683 size += ((SPEC_BLEN (lsym->etype) / 8) +
684 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
687 size = ((SPEC_BLEN (lsym->etype) / 8) +
688 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
690 i = (unsigned long)floatFromVal(val);
691 i <<= SPEC_BSTR (lsym->etype);
693 if (! ( lsym->next &&
694 (IS_BITFIELD(lsym->next->type)) &&
695 (SPEC_BSTR(lsym->next->etype)))) break;
697 lilist = lilist->next;
701 tfprintf (oFile, "\t!db !constbyte\n",ival);
705 tfprintf (oFile, "\t!dw !constword\n",ival);
708 tfprintf (oFile, "\t!db !constword,!constword\n",
709 (ival >> 8) & 0xffff, (ival & 0xffff));
716 /*-----------------------------------------------------------------*/
717 /* printIvalStruct - generates initial value for structures */
718 /*-----------------------------------------------------------------*/
720 printIvalStruct (symbol * sym, sym_link * type,
721 initList * ilist, FILE * oFile)
726 sflds = SPEC_STRUCT (type)->fields;
727 if (ilist->type != INIT_DEEP) {
728 werror (E_INIT_STRUCT, sym->name);
732 iloop = ilist->init.deep;
734 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
735 if (IS_BITFIELD(sflds->type)) {
736 printIvalBitFields(&sflds,&iloop,oFile);
738 printIval (sym, sflds->type, iloop, oFile);
742 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
747 /*-----------------------------------------------------------------*/
748 /* printIvalChar - generates initital value for character array */
749 /*-----------------------------------------------------------------*/
751 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
759 val = list2val (ilist);
760 /* if the value is a character string */
761 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
763 if (!DCL_ELEM (type))
764 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
766 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
768 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
770 tfprintf (oFile, "\t!db !constbyte\n", 0);
778 printChar (oFile, s, strlen (s) + 1);
782 /*-----------------------------------------------------------------*/
783 /* printIvalArray - generates code for array initialization */
784 /*-----------------------------------------------------------------*/
786 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
790 int lcnt = 0, size = 0;
793 /* take care of the special case */
794 /* array of characters can be init */
796 if (IS_CHAR (type->next)) {
797 if (!IS_LITERAL(list2val(ilist)->etype)) {
798 werror (E_CONST_EXPECTED);
801 if (printIvalChar (type,
802 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
803 oFile, SPEC_CVAL (sym->etype).v_char))
806 /* not the special case */
807 if (ilist->type != INIT_DEEP)
809 werror (E_INIT_STRUCT, sym->name);
813 iloop = ilist->init.deep;
814 lcnt = DCL_ELEM (type);
815 for (last_type = type->next;
816 last_type && IS_DECL(last_type) && DCL_ELEM (last_type);
817 last_type = last_type->next) {
818 lcnt *= DCL_ELEM (last_type);
824 printIval (sym, type->next, iloop, oFile);
825 iloop = (iloop ? iloop->next : NULL);
828 /* if not array limits given & we */
829 /* are out of initialisers then */
830 if (!DCL_ELEM (type) && !iloop)
833 /* no of elements given and we */
834 /* have generated for all of them */
836 /* if initializers left */
838 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
844 /* if we have not been given a size */
845 if (!DCL_ELEM (type))
846 DCL_ELEM (type) = size;
851 /*-----------------------------------------------------------------*/
852 /* printIvalFuncPtr - generate initial value for function pointers */
853 /*-----------------------------------------------------------------*/
855 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
860 val = list2val (ilist);
863 // an error has been thrown allready
867 if (IS_LITERAL(val->etype)) {
868 if (compareType(type,val->etype)==0) {
869 werror (E_INCOMPAT_TYPES);
870 printFromToType (val->type, type);
872 printIvalCharPtr (NULL, type, val, oFile);
876 /* check the types */
877 if ((dLvl = compareType (val->type, type->next)) <= 0)
879 tfprintf (oFile, "\t!dw !constword\n", 0);
883 /* now generate the name */
886 if (port->use_dw_for_init)
888 tfprintf (oFile, "\t!dws\n", val->name);
892 printPointerType (oFile, val->name);
895 else if (port->use_dw_for_init)
897 tfprintf (oFile, "\t!dws\n", val->sym->rname);
901 printPointerType (oFile, val->sym->rname);
907 /*-----------------------------------------------------------------*/
908 /* printIvalCharPtr - generates initial values for character pointers */
909 /*-----------------------------------------------------------------*/
911 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
915 /* PENDING: this is _very_ mcs51 specific, including a magic
917 It's also endin specific.
919 size = getSize (type);
921 if (val->name && strlen (val->name))
923 if (size == 1) /* This appears to be Z80 specific?? */
926 "\t!dbs\n", val->name);
928 else if (size == FPTRSIZE)
930 if (port->use_dw_for_init)
932 tfprintf (oFile, "\t!dws\n", val->name);
936 printPointerType (oFile, val->name);
939 else if (size == GPTRSIZE)
942 if (IS_PTR (val->type)) {
943 type = DCL_TYPE (val->type);
945 type = PTR_TYPE (SPEC_OCLS (val->etype));
947 if (val->sym && val->sym->isstrlit) {
948 // this is a literal string
951 printGPointerType (oFile, val->name, sym->name, type);
955 fprintf (stderr, "*** internal error: unknown size in "
956 "printIvalCharPtr.\n");
961 // these are literals assigned to pointers
965 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
968 if (port->use_dw_for_init)
969 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
971 tfprintf (oFile, "\t.byte %s,%s\n",
972 aopLiteral (val, 0), aopLiteral (val, 1));
975 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
976 // non-zero mcs51 generic pointer
977 werror (E_LITERAL_GENERIC);
979 fprintf (oFile, "\t.byte %s,%s,%s\n",
982 aopLiteral (val, 2));
985 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
986 // non-zero ds390 generic pointer
987 werror (E_LITERAL_GENERIC);
989 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
993 aopLiteral (val, 3));
1000 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1001 addSet (&statsg->syms, val->sym);
1007 /*-----------------------------------------------------------------*/
1008 /* printIvalPtr - generates initial value for pointers */
1009 /*-----------------------------------------------------------------*/
1011 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1017 if (ilist->type == INIT_DEEP)
1018 ilist = ilist->init.deep;
1020 /* function pointer */
1021 if (IS_FUNC (type->next))
1023 printIvalFuncPtr (type, ilist, oFile);
1027 if (!(val = initPointer (ilist, type)))
1030 /* if character pointer */
1031 if (IS_CHAR (type->next))
1032 if (printIvalCharPtr (sym, type, val, oFile))
1035 /* check the type */
1036 if (compareType (type, val->type) == 0) {
1037 werror (W_INIT_WRONG);
1038 printFromToType (val->type, type);
1041 /* if val is literal */
1042 if (IS_LITERAL (val->etype))
1044 switch (getSize (type))
1047 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1050 if (port->use_dw_for_init)
1051 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1053 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1055 case 3: // how about '390??
1056 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1057 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1063 size = getSize (type);
1065 if (size == 1) /* Z80 specific?? */
1067 tfprintf (oFile, "\t!dbs\n", val->name);
1069 else if (size == FPTRSIZE)
1071 if (port->use_dw_for_init) {
1072 tfprintf (oFile, "\t!dws\n", val->name);
1074 printPointerType (oFile, val->name);
1077 else if (size == GPTRSIZE)
1079 printGPointerType (oFile, val->name, sym->name,
1080 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1081 PTR_TYPE (SPEC_OCLS (val->etype))));
1086 /*-----------------------------------------------------------------*/
1087 /* printIval - generates code for initial value */
1088 /*-----------------------------------------------------------------*/
1090 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1095 /* update line number for error msgs */
1096 lineno=sym->lineDef;
1098 /* if structure then */
1099 if (IS_STRUCT (type))
1101 printIvalStruct (sym, type, ilist, oFile);
1105 /* if this is a pointer */
1108 printIvalPtr (sym, type, ilist, oFile);
1112 /* if this is an array */
1113 if (IS_ARRAY (type))
1115 printIvalArray (sym, type, ilist, oFile);
1119 /* if type is SPECIFIER */
1122 printIvalType (sym, type, ilist, oFile);
1127 /*-----------------------------------------------------------------*/
1128 /* emitStaticSeg - emitcode for the static segment */
1129 /*-----------------------------------------------------------------*/
1131 emitStaticSeg (memmap * map, FILE * out)
1135 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1137 /* for all variables in this segment do */
1138 for (sym = setFirstItem (map->syms); sym;
1139 sym = setNextItem (map->syms))
1142 /* if it is "extern" then do nothing */
1143 if (IS_EXTERN (sym->etype))
1146 /* if it is not static add it to the public
1148 if (!IS_STATIC (sym->etype))
1150 addSetHead (&publics, sym);
1153 /* print extra debug info if required */
1154 if (options.debug) {
1158 if (IS_STATIC (sym->etype))
1159 fprintf (out, "F%s$", moduleName); /* scope is file */
1161 fprintf (out, "G$"); /* scope is global */
1164 /* symbol is local */
1165 fprintf (out, "L%s$",
1166 (sym->localof ? sym->localof->name : "-null-"));
1167 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1170 /* if it has an absolute address */
1171 if (SPEC_ABSA (sym->etype))
1174 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1176 fprintf (out, "%s\t=\t0x%04x\n",
1178 SPEC_ADDR (sym->etype));
1183 fprintf (out, " == .\n");
1185 /* if it has an initial value */
1188 fprintf (out, "%s:\n", sym->rname);
1190 resolveIvalSym (sym->ival);
1191 printIval (sym, sym->type, sym->ival, out);
1193 /* if sym is a simple string and sym->ival is a string,
1194 WE don't need it anymore */
1195 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1196 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1197 list2val(sym->ival)->sym->isstrlit) {
1198 freeStringSymbol(list2val(sym->ival)->sym);
1202 /* allocate space */
1203 int size = getSize (sym->type);
1206 werror(E_UNKNOWN_SIZE,sym->name);
1208 fprintf (out, "%s:\n", sym->rname);
1209 /* special case for character strings */
1210 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1211 SPEC_CVAL (sym->etype).v_char)
1213 SPEC_CVAL (sym->etype).v_char,
1214 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1216 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1222 /*-----------------------------------------------------------------*/
1223 /* emitMaps - emits the code for the data portion the code */
1224 /*-----------------------------------------------------------------*/
1229 /* no special considerations for the following
1230 data, idata & bit & xdata */
1231 emitRegularMap (data, TRUE, TRUE);
1232 emitRegularMap (idata, TRUE, TRUE);
1233 emitRegularMap (bit, TRUE, FALSE);
1234 emitRegularMap (xdata, TRUE, TRUE);
1235 if (port->genXINIT) {
1236 emitRegularMap (xidata, TRUE, TRUE);
1238 emitRegularMap (sfr, FALSE, FALSE);
1239 emitRegularMap (sfrbit, FALSE, FALSE);
1240 emitRegularMap (home, TRUE, FALSE);
1241 emitRegularMap (code, TRUE, FALSE);
1243 emitStaticSeg (statsg, code->oFile);
1244 if (port->genXINIT) {
1245 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1246 emitStaticSeg (xinit, code->oFile);
1251 /*-----------------------------------------------------------------*/
1252 /* flushStatics - flush all currently defined statics out to file */
1253 /* and delete. Temporary function */
1254 /*-----------------------------------------------------------------*/
1258 emitStaticSeg (statsg, codeOutFile);
1259 statsg->syms = NULL;
1262 /*-----------------------------------------------------------------*/
1263 /* createInterruptVect - creates the interrupt vector */
1264 /*-----------------------------------------------------------------*/
1266 createInterruptVect (FILE * vFile)
1269 mainf = newSymbol ("main", 0);
1272 /* only if the main function exists */
1273 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1275 if (!options.cc_only && !noAssemble && !options.c1mode)
1280 /* if the main is only a prototype ie. no body then do nothing */
1281 if (!IFFUNC_HASBODY(mainf->type))
1283 /* if ! compile only then main function should be present */
1284 if (!options.cc_only && !noAssemble)
1289 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1290 fprintf (vFile, "__interrupt_vect:\n");
1293 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1295 /* "generic" interrupt table header (if port doesn't specify one).
1296 * Look suspiciously like 8051 code to me...
1299 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1302 /* now for the other interrupts */
1303 for (; i < maxInterrupts; i++)
1306 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1308 fprintf (vFile, "\treti\n\t.ds\t7\n");
1315 ";--------------------------------------------------------\n"
1316 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1320 ";--------------------------------------------------------\n"};
1323 /*-----------------------------------------------------------------*/
1324 /* initialComments - puts in some initial comments */
1325 /*-----------------------------------------------------------------*/
1327 initialComments (FILE * afile)
1331 fprintf (afile, "%s", iComments1);
1332 fprintf (afile, "; Version " SDCC_VERSION_STR " %s\n", asctime (localtime (&t)));
1333 fprintf (afile, "%s", iComments2);
1336 /*-----------------------------------------------------------------*/
1337 /* printPublics - generates .global for publics */
1338 /*-----------------------------------------------------------------*/
1340 printPublics (FILE * afile)
1344 fprintf (afile, "%s", iComments2);
1345 fprintf (afile, "; Public variables in this module\n");
1346 fprintf (afile, "%s", iComments2);
1348 for (sym = setFirstItem (publics); sym;
1349 sym = setNextItem (publics))
1350 tfprintf (afile, "\t!global\n", sym->rname);
1353 /*-----------------------------------------------------------------*/
1354 /* printExterns - generates .global for externs */
1355 /*-----------------------------------------------------------------*/
1357 printExterns (FILE * afile)
1361 fprintf (afile, "%s", iComments2);
1362 fprintf (afile, "; Externals used\n");
1363 fprintf (afile, "%s", iComments2);
1365 for (sym = setFirstItem (externs); sym;
1366 sym = setNextItem (externs))
1367 tfprintf (afile, "\t!extern\n", sym->rname);
1370 /*-----------------------------------------------------------------*/
1371 /* emitOverlay - will emit code for the overlay stuff */
1372 /*-----------------------------------------------------------------*/
1374 emitOverlay (FILE * afile)
1378 if (!elementsInSet (ovrSetSets))
1379 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1381 /* for each of the sets in the overlay segment do */
1382 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1383 ovrset = setNextItem (ovrSetSets))
1388 if (elementsInSet (ovrset))
1390 /* output the area informtion */
1391 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1394 for (sym = setFirstItem (ovrset); sym;
1395 sym = setNextItem (ovrset))
1397 /* if extern then it is in the publics table: do nothing */
1398 if (IS_EXTERN (sym->etype))
1401 /* if allocation required check is needed
1402 then check if the symbol really requires
1403 allocation only for local variables */
1404 if (!IS_AGGREGATE (sym->type) &&
1405 !(sym->_isparm && !IS_REGPARM (sym->etype))
1406 && !sym->allocreq && sym->level)
1409 /* if global variable & not static or extern
1410 and addPublics allowed then add it to the public set */
1411 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1412 && !IS_STATIC (sym->etype))
1414 addSetHead (&publics, sym);
1417 /* if extern then do nothing or is a function
1419 if (IS_FUNC (sym->type))
1422 /* print extra debug info if required */
1427 if (IS_STATIC (sym->etype))
1428 fprintf (afile, "F%s$", moduleName); /* scope is file */
1430 fprintf (afile, "G$"); /* scope is global */
1433 /* symbol is local */
1434 fprintf (afile, "L%s$",
1435 (sym->localof ? sym->localof->name : "-null-"));
1436 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1439 /* if is has an absolute address then generate
1440 an equate for this no need to allocate space */
1441 if (SPEC_ABSA (sym->etype))
1445 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1447 fprintf (afile, "%s\t=\t0x%04x\n",
1449 SPEC_ADDR (sym->etype));
1452 int size = getSize(sym->type);
1455 werror(E_UNKNOWN_SIZE,sym->name);
1458 fprintf (afile, "==.\n");
1460 /* allocate space */
1461 tfprintf (afile, "!labeldef\n", sym->rname);
1462 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1470 /*-----------------------------------------------------------------*/
1471 /* spacesToUnderscores - replace spaces with underscores */
1472 /*-----------------------------------------------------------------*/
1474 spacesToUnderscores (char *dest, const char *src, size_t len)
1479 assert(dest != NULL);
1480 assert(src != NULL);
1484 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1485 *p++ = isspace(*src) ? '_' : *src;
1493 /*-----------------------------------------------------------------*/
1494 /* glue - the final glue that hold the whole thing together */
1495 /*-----------------------------------------------------------------*/
1501 FILE *ovrFile = tempfile ();
1502 char moduleBuf[PATH_MAX];
1504 addSetHead (&tmpfileSet, ovrFile);
1505 /* print the global struct definitions */
1509 vFile = tempfile ();
1510 /* PENDING: this isnt the best place but it will do */
1511 if (port->general.glue_up_main)
1513 /* create the interrupt vector table */
1514 createInterruptVect (vFile);
1517 addSetHead (&tmpfileSet, vFile);
1519 /* emit code for the all the variables declared */
1521 /* do the overlay segments */
1522 emitOverlay (ovrFile);
1524 outputDebugSymbols();
1526 /* now put it all together into the assembler file */
1527 /* create the assembler file name */
1529 /* -o option overrides default name? */
1530 if ((noAssemble || options.c1mode) && fullDstFileName)
1532 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1536 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1537 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1540 if (!(asmFile = fopen (scratchFileName, "w")))
1542 werror (E_FILE_OPEN_ERR, scratchFileName);
1546 /* initial comments */
1547 initialComments (asmFile);
1549 /* print module name */
1550 tfprintf (asmFile, "\t!module\n",
1551 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1552 tfprintf (asmFile, "\t!fileprelude\n");
1554 /* Let the port generate any global directives, etc. */
1555 if (port->genAssemblerPreamble)
1557 port->genAssemblerPreamble (asmFile);
1560 /* print the global variables in this module */
1561 printPublics (asmFile);
1562 if (port->assembler.externGlobal)
1563 printExterns (asmFile);
1565 /* copy the sfr segment */
1566 fprintf (asmFile, "%s", iComments2);
1567 fprintf (asmFile, "; special function registers\n");
1568 fprintf (asmFile, "%s", iComments2);
1569 copyFile (asmFile, sfr->oFile);
1571 /* copy the sbit segment */
1572 fprintf (asmFile, "%s", iComments2);
1573 fprintf (asmFile, "; special function bits \n");
1574 fprintf (asmFile, "%s", iComments2);
1575 copyFile (asmFile, sfrbit->oFile);
1577 /*JCF: Create the areas for the register banks*/
1578 if(port->general.glue_up_main &&
1579 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1581 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1583 fprintf (asmFile, "%s", iComments2);
1584 fprintf (asmFile, "; overlayable register banks \n");
1585 fprintf (asmFile, "%s", iComments2);
1587 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1588 if(RegBankUsed[1]||options.parms_in_bank1)
1589 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1591 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1593 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1597 /* copy the data segment */
1598 fprintf (asmFile, "%s", iComments2);
1599 fprintf (asmFile, "; internal ram data\n");
1600 fprintf (asmFile, "%s", iComments2);
1601 copyFile (asmFile, data->oFile);
1604 /* create the overlay segments */
1606 fprintf (asmFile, "%s", iComments2);
1607 fprintf (asmFile, "; overlayable items in internal ram \n");
1608 fprintf (asmFile, "%s", iComments2);
1609 copyFile (asmFile, ovrFile);
1612 /* create the stack segment MOF */
1613 if (mainf && IFFUNC_HASBODY(mainf->type))
1615 fprintf (asmFile, "%s", iComments2);
1616 fprintf (asmFile, "; Stack segment in internal ram \n");
1617 fprintf (asmFile, "%s", iComments2);
1618 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1619 "__start__stack:\n\t.ds\t1\n\n");
1622 /* create the idata segment */
1624 fprintf (asmFile, "%s", iComments2);
1625 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1626 fprintf (asmFile, "%s", iComments2);
1627 copyFile (asmFile, idata->oFile);
1630 /* copy the bit segment */
1631 fprintf (asmFile, "%s", iComments2);
1632 fprintf (asmFile, "; bit data\n");
1633 fprintf (asmFile, "%s", iComments2);
1634 copyFile (asmFile, bit->oFile);
1636 /* if external stack then reserve space of it */
1637 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1639 fprintf (asmFile, "%s", iComments2);
1640 fprintf (asmFile, "; external stack \n");
1641 fprintf (asmFile, "%s", iComments2);
1642 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1643 fprintf (asmFile, "\t.ds 256\n");
1647 /* copy xtern ram data */
1648 fprintf (asmFile, "%s", iComments2);
1649 fprintf (asmFile, "; external ram data\n");
1650 fprintf (asmFile, "%s", iComments2);
1651 copyFile (asmFile, xdata->oFile);
1653 /* copy xternal initialized ram data */
1654 fprintf (asmFile, "%s", iComments2);
1655 fprintf (asmFile, "; external initialized ram data\n");
1656 fprintf (asmFile, "%s", iComments2);
1657 copyFile (asmFile, xidata->oFile);
1659 /* copy the interrupt vector table */
1660 if (mainf && IFFUNC_HASBODY(mainf->type))
1662 fprintf (asmFile, "%s", iComments2);
1663 fprintf (asmFile, "; interrupt vector \n");
1664 fprintf (asmFile, "%s", iComments2);
1665 copyFile (asmFile, vFile);
1668 /* copy global & static initialisations */
1669 fprintf (asmFile, "%s", iComments2);
1670 fprintf (asmFile, "; global & static initialisations\n");
1671 fprintf (asmFile, "%s", iComments2);
1673 /* Everywhere we generate a reference to the static_name area,
1674 * (which is currently only here), we immediately follow it with a
1675 * definition of the post_static_name area. This guarantees that
1676 * the post_static_name area will immediately follow the static_name
1679 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1680 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1681 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1683 if (mainf && IFFUNC_HASBODY(mainf->type))
1685 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1686 /* if external stack is specified then the
1687 higher order byte of the xdatalocation is
1688 going into P2 and the lower order going into
1690 if (options.useXstack)
1692 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1693 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1694 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1695 (unsigned int) options.xdata_loc & 0xff);
1698 // This should probably be a port option, but I'm being lazy.
1699 // on the 400, the firmware boot loader gives us a valid stack
1700 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1701 if (!TARGET_IS_DS400)
1703 /* initialise the stack pointer. JCF: aslink takes care of the location */
1704 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1707 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1708 fprintf (asmFile, "\tmov\ta,dpl\n");
1709 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1710 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1711 fprintf (asmFile, "__sdcc_init_data:\n");
1713 // if the port can copy the XINIT segment to XISEG
1714 if (port->genXINIT) {
1715 port->genXINIT(asmFile);
1719 copyFile (asmFile, statsg->oFile);
1721 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1723 /* This code is generated in the post-static area.
1724 * This area is guaranteed to follow the static area
1725 * by the ugly shucking and jiving about 20 lines ago.
1727 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1728 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1734 "%s", iComments2, iComments2);
1735 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1736 copyFile (asmFile, home->oFile);
1738 /* copy over code */
1739 fprintf (asmFile, "%s", iComments2);
1740 fprintf (asmFile, "; code\n");
1741 fprintf (asmFile, "%s", iComments2);
1742 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1743 if (mainf && IFFUNC_HASBODY(mainf->type))
1746 /* entry point @ start of CSEG */
1747 fprintf (asmFile, "__sdcc_program_startup:\n");
1749 /* put in the call to main */
1750 fprintf (asmFile, "\tlcall\t_main\n");
1751 if (options.mainreturn)
1754 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1755 fprintf (asmFile, "\tret\n");
1761 fprintf (asmFile, ";\treturn from main will lock up\n");
1762 fprintf (asmFile, "\tsjmp .\n");
1765 copyFile (asmFile, code->oFile);
1767 if (port->genAssemblerEnd) {
1768 port->genAssemblerEnd(asmFile);
1776 /** Creates a temporary file with unoque file name
1778 - TMP, TEMP, TMPDIR env. varibles
1779 - if Un*x system: /usr/tmp and /tmp
1780 - root directory using mkstemp() if avaliable
1781 - default location using tempnam()
1784 tempfileandname(char *fname, size_t len)
1786 #define TEMPLATE "sdccXXXXXX"
1787 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1789 const char *tmpdir = NULL;
1792 if ((tmpdir = getenv ("TMP")) == NULL)
1793 if ((tmpdir = getenv ("TEMP")) == NULL)
1794 tmpdir = getenv ("TMPDIR");
1798 /* try with /usr/tmp and /tmp on Un*x systems */
1799 struct stat statbuf;
1801 if (tmpdir == NULL) {
1802 if (stat("/usr/tmp", &statbuf) != -1)
1803 tmpdir = "/usr/tmp";
1804 else if (stat("/tmp", &statbuf) != -1)
1812 char fnamebuf[PATH_MAX];
1815 if (fname == NULL || len == 0) {
1817 len = sizeof fnamebuf;
1821 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
1823 assert(name_len < len);
1824 if (!(name_len < len)) /* in NDEBUG is defined */
1825 return -1; /* buffer too small, temporary file can not be created */
1827 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
1830 name_len = TEMPLATE_LEN;
1832 assert(name_len < len);
1833 if (!(name_len < len)) /* in NDEBUG is defined */
1834 return -1; /* buffer too small, temporary file can not be created */
1836 strcpy(fname, TEMPLATE);
1839 fd = mkstemp(fname);
1843 char *name = tempnam(tmpdir, "sdcc");
1846 perror("Can't create temporary file name");
1850 assert(strlen(name) < len);
1851 if (!(strlen(name) < len)) /* in NDEBUG is defined */
1852 return -1; /* buffer too small, temporary file can not be created */
1854 strcpy(fname, name);
1856 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
1858 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1864 perror("Can't create temporary file");
1872 /** Create a temporary file name
1878 static char fnamebuf[PATH_MAX];
1880 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1881 fprintf(stderr, "Can't create temporary file name!");
1892 /** Create a temporary file and add it to tmpfileNameSet,
1893 so that it is removed explicitly by rm_tmpfiles()
1894 or implicitly at program extit.
1902 char fnamebuf[PATH_MAX];
1904 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1905 fprintf(stderr, "Can't create temporary file!");
1909 tmp = Safe_strdup(fnamebuf);
1911 addSetHead(&tmpfileNameSet, tmp);
1913 if ((fp = fdopen(fd, "w+b")) == NULL) {
1914 perror("Can't create temporary file!");